Durable Functions Key Concepts
Durable Functions is an extension of Azure Functions that lets you write stateful functions in a serverless compute environment. It provides a programming model that enables you to orchestrate and manage long-running, stateful workflows.
1. Functions
In Durable Functions, you have different types of functions:
- Orchestrator functions: These functions define the workflow. They are deterministic and must be written in a specific way to ensure replayability. Orchestrators define the sequence, timing, and parallelism of activities.
- Activity functions: These functions perform the actual work. They can be any Azure Function (e.g., triggered by HTTP, queue, blob) and are called by the orchestrator.
- Entity functions: These functions are designed for managing state. They are stateless and used to manage complex domain models or aggregates.
2. State Management
Durable Functions automatically manage the state of your orchestrations. When an orchestrator function yields execution (e.g., waiting for an activity to complete), its state is saved to durable storage. When the execution resumes, the orchestrator function is replayed from its last saved state.
3. Durability Provider
A durability provider (also known as a storage provider or backend) is responsible for storing the state and history of orchestrations. Common providers include Azure Storage (Table and Blob storage) and Azure Cosmos DB. This ensures that your workflows can survive failures and restarts.
4. Instance Management
Each running orchestration is an "instance." You can start, query, signal, and terminate instances of your durable functions. This allows for external control and management of your workflows.
5. Determinism
Orchestrator functions must be deterministic. This means that given the same input and history, the orchestrator function will always produce the same output and call the same activities in the same order. This is crucial for the replay mechanism to work correctly. You cannot use non-deterministic operations like:
- Random number generation
- Current date/time
- Direct I/O operations (e.g., reading from a file or network)
Instead, use the provided orchestrator-aware APIs for time, random numbers, etc.
6. Replay
When an orchestrator function is scheduled to resume, the Durable Functions runtime replays the function from the beginning. However, instead of executing the actual code for activities that have already completed, it uses the previously recorded history from storage. This replay mechanism is what makes orchestrator functions highly resilient and allows them to be stateless from a code perspective.
Durable Functions Workflow Example
Imagine a simple workflow: Order processing.

This diagram illustrates how an orchestrator function calls multiple activity functions to process an order, save the status, and send a notification.
7. Patterns
Durable Functions supports various complex orchestration patterns, including:
- Function Chaining: Running a sequence of functions where the output of one function is the input of the next.
- Fan-out/Fan-in: Running multiple functions in parallel and then aggregating the results.
- Monitoring: Long-running operations that can be monitored by a client.
- Human Interaction: Workflows that require human approval or input.
- Aggregator: Collecting events from multiple sources and processing them together.
Example: Function Chaining
Here's a simplified C# example of a function chaining orchestrator:
public static class ChainingOrchestrator
{
[Function("ChainingOrchestrator")]
public static async Task<string> RunAsync(
[OrchestrationTrigger] TaskOrchestrationContext context)
{
// Call activity function 1
var result1 = await context.CallActivityAsync<string>(
"ActivityFunction1", "input1");
// Call activity function 2 with the result of function 1
var result2 = await context.CallActivityAsync<string>(
"ActivityFunction2", result1);
// Call activity function 3 with the result of function 2
var finalResult = await context.CallActivityAsync<string>(
"ActivityFunction3", result2);
return finalResult;
}
}
Understanding these core concepts is essential for building robust and scalable serverless workflows with Durable Functions.