Azure Functions Durable

Build stateful, reliable, and long-running serverless applications.

What are Durable Functions?

Durable Functions is an extension of Azure Functions that lets you write stateful functions in a serverless compute environment. It allows you to orchestrate and manage complex workflows, execute long-running processes, and handle retries and error handling in a robust and scalable manner.

Traditionally, Azure Functions are stateless. This means each execution is independent and doesn't inherently remember past executions. Durable Functions address this by providing a stateful programming model, enabling you to build applications that:

Core Concepts

Durable Functions introduce a few key programming constructs to manage state and orchestration:

Orchestrator Functions

These functions define the workflow logic. They are deterministic and describe the sequence and conditions under which other functions (activity functions) should be executed. Orchestrators don't perform I/O operations directly; they call activity functions to do so.

Activity Functions

These are the standard Azure Functions that perform the actual work. They can be any type of Azure Function (HTTP, queue, timer, etc.) and are invoked by orchestrator functions. Activity functions can perform I/O-bound operations like calling external services, querying databases, or writing to storage.

Entity Functions

Used for managing and querying state for a specific entity. They are ideal for implementing simple stateful entities like counters, aggregates, or configuration data.

Client Functions

These are typically HTTP-triggered functions that start, query, or terminate orchestrations. They act as the entry point for initiating workflows.

How it Works: The Durable Task Framework

Durable Functions are built on top of the Durable Task Framework. This framework uses Azure Storage (like Azure Storage Queues, Tables, and Blobs) to durably store the state of orchestrations and activity functions. When an orchestrator executes, it logs its actions to a history table. If the orchestrator needs to wait for an activity to complete or for a timer to expire, it checkpoints its state and yields control. When the awaited event occurs, the orchestrator replays its execution from the last checkpoint, using the history to determine which actions have already been performed.

This replay mechanism is crucial:

Use Cases

Durable Functions are well-suited for a variety of scenarios, including:

By leveraging Durable Functions, developers can build sophisticated, resilient, and scalable serverless applications with a familiar programming model. Explore the documentation to learn more about building your first orchestration!

Example Snippet (Conceptual)

Here's a simplified conceptual example of an orchestrator function:


// C# Example (Conceptual)
[FunctionName("MyOrchestrator")]
public static async Task RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    // Start an activity function
    var result1 = await context.CallActivityAsync<string>("ActivityFunction1", "input1");

    // Call another activity, passing the result from the first
    var result2 = await context.CallActivityAsync<string>("ActivityFunction2", result1);

    // Wait for a timer
    await context.CreateTimer(context.CurrentUtcDateTime.AddHours(1), CancellationToken.None);

    // Fan-out/Fan-in pattern example
    var tasks = new List<Task<string>>();
    for (int i = 0; i < 5; i++)
    {
        tasks.Add(context.CallActivityAsync<string>("FanOutActivity", i));
    }
    var fanOutResults = await Task.WhenAll(tasks);

    // ... process fanOutResults and potentially call more activities ...

    return "Orchestration completed.";
}