How can Durable Functions orchestrate long-running business processes while maintaining state?
Question
Answers
Traditional serverless functions are excellent for short-lived event-driven operations, but many enterprise processes don't finish in a few seconds.
Consider:
Submit Loan Application
|
v
Validate Documents
|
v
Credit Check
|
v
Wait for Human Approval
|
v
Perform Compliance Check
|
v
Create Account
|
v
Send NotificationThe process may take minutes, hours, or even days.
This is where Azure Durable Functions becomes particularly useful.
Microsoft describes Durable Functions as an extension of Azure Functions for building stateful workflows. The runtime manages state, checkpoints, retries and recovery so workflows can run reliably for long periods.
The fundamental architecture
A Durable Functions solution commonly consists of:
HTTP/Event
|
v
Starter Function
|
v
+-------------------+
| Orchestrator |
| Function |
+-------------------+
/ | \
/ | \
v v v
Activity Activity Activity
Function Function FunctionThe orchestrator controls the workflow.
Activity functions perform the actual work.
The Durable Functions runtime maintains execution history and state.
Why is this different from a normal function?
A normal function might do this:
Validate();
CallExternalSystem();
Wait();
ProcessApproval();
SendEmail();You generally don't want a serverless function sitting there waiting for hours.
Instead, Durable Functions models the process as a sequence of durable operations:
Orchestrator
|
+--> Activity: Validate
|
+--> Activity: Credit Check
|
+--> Durable Timer / External Event
|
+--> Activity: Process Approval
|
+--> Activity: Complete OrderWhen the workflow reaches a durable wait, the orchestration can unload from memory and resume later. Microsoft documents this checkpointing and replay model as a core part of Durable Functions.
How state is maintained
This is one of the most important concepts to understand.
Durable Functions uses execution history and replay.
When an orchestration resumes, the orchestrator can execute again from the beginning while the Durable Task runtime uses the recorded history to reconstruct what has already happened.
Conceptually:
Orchestrator starts
|
v
Activity A completed
|
v
Activity B completed
|
v
Wait for approval
|
| --- hours pass ---
|
v
Orchestrator resumes
|
v
Replay history
|
v
Continue from workflow stateThis is why orchestrator code has an important requirement:
It must be deterministic.
Microsoft specifically warns that nondeterministic code inside orchestrators can cause runtime errors or unexpected behavior.
What should NOT be done inside the orchestrator?
Avoid putting arbitrary side effects directly inside orchestration code.
For example, don't treat this as normal application code:
var customer = database.GetCustomer();
SendEmail();
var currentTime = DateTime.Now;
var randomNumber = new Random().Next();Instead, external side effects should normally be isolated into activities or other durable operations.
Think:
Orchestrator
|
+--> Activity: Read Customer
|
+--> Activity: Send Email
|
+--> Activity: Update CRMThe orchestrator should primarily coordinate, not perform every piece of business work itself.
Durable timers
A powerful capability is the durable timer.
Imagine:
If the customer doesn't respond within 48 hours, automatically escalate the case.
Conceptually:
Send Request
|
v
Wait for External Event
|
+------ Customer responds ------> Continue
|
+------ 48-hour timer ----------> EscalateThis is much more appropriate than continuously polling a database.
External events
Human approval workflows are a common enterprise scenario.
For example:
Purchase Request
|
v
Manager Approval
|
| wait
|
v
Approval Event
|
v
Continue WorkflowThe orchestration can wait for an external event rather than consuming compute while waiting.
Retry and recovery
Suppose an activity calls an external service:
Create Invoice
|
v
External ERP API
|
v
Temporary failureA Durable Function can model retry behavior.
But retry strategy should be designed carefully.
Ask:
- Is the operation idempotent?
- Can duplicate requests create duplicate business records?
- Is the failure transient?
- How many retries are appropriate?
- Should exponential backoff be used?
- When should the workflow move to a compensation path?
A retry without idempotency can turn a reliability feature into a duplication problem.
Sub-orchestrations
Large business processes can be decomposed.
For example:
Order Orchestrator
|
+--> Customer Validation Orchestrator
|
+--> Payment Orchestrator
|
+--> Inventory Orchestrator
|
+--> Shipping OrchestratorThis helps separate business capabilities and makes large workflows easier to understand and test.
Enterprise scenario
Imagine a Dynamics 365 + Azure architecture:
Dynamics 365
|
| Business event
v
Azure Function
|
v
Durable Orchestrator
|
+----> Validate Customer
|
+----> Call Credit Service
|
+----> Wait for Approval
|
+----> Create/Update Dataverse Data
|
+----> Call ERP
|
+----> Notify UserThis pattern is particularly useful when the process spans multiple systems and contains long waits, retries, human decisions or asynchronous operations.
Performance consideration
Durable Functions rely on orchestration history and replay.
Microsoft notes that replay overhead can become significant for orchestrations with many episodes; instance caching can reduce some history I/O and replay overhead depending on the storage provider and hosting configuration.
Therefore, don't design one enormous orchestration containing thousands of fine-grained steps without considering:
- history size
- replay cost
- activity granularity
- sub-orchestrations
- payload size
- storage
- throughput
- observability
Common mistakes
Putting business logic directly into the orchestrator
The orchestrator should coordinate.
Using nondeterministic APIs
Examples include uncontrolled use of:
- current time
- random numbers
- external I/O
- non-deterministic APIs
Microsoft explicitly documents deterministic-code requirements for orchestrators.
Ignoring duplicate execution
Design activities so retries and replay don't create unintended side effects.
Treating Durable Functions as a replacement for every workflow engine
The correct technology depends on the workflow's characteristics.
Evaluate:
- code-centric vs designer-centric workflow
- event-driven vs approval-heavy
- integration complexity
- operational requirements
- human interaction
- state management
- monitoring
Key takeaway
Durable Functions is fundamentally about reliable stateful orchestration, not simply "running a function for a long time."
The key concepts are:
- Orchestrator
- Activity
- State
- Event sourcing
- Replay
- Determinism
- Durable timers
- External events
- Retries
- Compensation
- Sub-orchestrations