Introduction
BizTalk is well-known for its persistence engine and ability to handle long-running, stateful workflows — from multi-day approval processes to complex supply chain transactions.
But with great state comes great responsibility: if implemented carelessly, these workflows can turn into sluggish, resource-hogging monsters.
In this post, we’ll walk through:
- What “highly stateful” means in BizTalk
- The pitfalls that slow them down
- Best practices to keep them performant
- A sample implementation pattern
1. What “Highly Stateful” Means in BizTalk
A highly stateful workflow:
- Keeps a correlation set alive for hours, days, or even weeks.
- Waits for multiple related messages (scatter/gather patterns).
- Persists data between processing steps.
- Handles compensation logic for failures.
Example scenario:
A Global Purchase Order Approval process:
- Receive initial PO.
- Wait for all subsidiary approvals.
- Aggregate results and send final confirmation.
BizTalk Orchestration Lifecycle
The diagram below shows when BizTalk persists state:
Receive --> Persist --> Process --> Persist at Wait Points --> Process Next Step --> Persist Before Sending
Persistence points are the performance cost centers — avoid adding more than you need.
2. Common Pitfalls
| Pitfall | Impact |
|---|---|
| Too many persistence points | Slows throughput dramatically |
| Large message persistence | Bloats the MessageBox database |
| Unnecessary orchestration shapes | Increases dehydration/re-hydration overhead |
| Overusing correlation sets | More DB work per message |
| Holding messages too long | Larger suspended queue, more DB growth |
3. Performance Best Practices for Stateful Workflows
A. Reduce Persistence Points
- Avoid unnecessary
Suspend,Listen, or extraReceiveshapes if a port filter can do the work. - Combine multiple decisions into one
Decideblock.
B. Use Message References, Not Copies
Instead of duplicating messages, use MessageRef pattern:
// Instead of creating a full copy:
msgCopy = msgOriginal; // This still makes a copy internally
// Use direct assignment where possible:
msgOriginal(*) = msgTransformed(*);
This reduces message size and persistence cost.
C. Offload Large Payloads Early
If the stateful part only needs metadata:
- Store the large payload in an external store (SQL, Blob storage).
- Keep only the reference (URL, ID) in BizTalk.
D. Use Correlation Wisely
- Define the smallest possible correlation set.
- Avoid correlation on large context properties (e.g., entire XML node values).
E. Minimize Orchestration Shapes
Fewer shapes = fewer persistence checkpoints.
4. Implementation Example
Let’s say we’re building a 3-step loan approval workflow that waits for:
- Customer Documents
- Credit Check
- Manager Approval
Diagram: Workflow Flow
[Receive Initial Loan Request]
|
[Fan-out Request]
|
<Wait for all 3 Responses>
|
[Aggregate + Final Decision]
|
[Send Final Approval/Reject]
Step-by-Step BizTalk Orchestration
Step 1: Receive and Initialize Correlation
// Declare Correlation Set on LoanID
CorrelationSet LoanCorrSet;
// Receive initial loan request
Receive_LoanRequest.Activate = true;
InitializeCorrelation(LoanCorrSet);
Step 2: Parallel Listening for Responses
// Listen shape with parallel branches
Listen(
Receive_CustomerDocs.FollowCorrelation(LoanCorrSet),
Receive_CreditCheck.FollowCorrelation(LoanCorrSet),
Receive_ManagerApproval.FollowCorrelation(LoanCorrSet)
);
Step 3: Aggregate Results Without Copying Messages
// Aggregate into a single decision message
msgDecision(*) = msgCustomerDocs(*);
msgDecision(*) = msgCreditCheck(*);
msgDecision(*) = msgManagerApproval(*);
Step 4: Send Decision
Send_FinalDecision(msgDecision);
Diagram: Persistence Points Optimized
[Receive_LoanRequest] --> PERSIST
[Listen for 3 Messages] --> PERSIST (only once per message arrival)
[Send_FinalDecision] --> PERSIST (final)
By designing it this way:
- Only 3 main persistence points exist (instead of 6–8 in naive implementations).
- Large payloads are kept outside orchestration state.
Summary
Highly stateful workflows are BizTalk’s superpower — but they come with a cost.
To keep them fast and maintainable:
- Minimize persistence points
- Keep payloads small
- Use correlation efficiently
- Avoid unnecessary orchestration shapes
By applying these practices, you’ll build workflows that can run for weeks without turning your MessageBox into a black hole.
Rule of Thumb: Every extra persistence point is a debit from your performance account — spend wisely.
Views: 9
