Skip to main content

Orchestration Performance

Recommendations for Optimizing Orchestration Performance

This includes information about persistence points, nesting orchestrations, inline sends and messaging only patterns, and design patterns.

Persistence Points

An orchestration scope only needs to be marked as “long-running transactional” if you want to use compensation or scope timeouts. A long-running transactional scope causes an extra persistence point at the end of the scope, so should be avoided when you don’t need the extra functionality.
An atomic scope causes a persistence point at the end of the scope, but also guarantees that no persistence points will occur inside the atomic scope. This side-effect of no persistence inside the scope can sometimes be used to your advantage to batch persistence points (when doing multiple sends, for example). In general, though, we recommend avoiding atomic scopes, if possible.
The orchestration engine saves to persistent storage the entire state of a running orchestration instance at various points, so that the instance can later be restored in memory and carried out to completion. The number of persistence points is one of the key factors that influences the latency of messages flowing through orchestrations. Each time the engine hits a persistence point, the internal state of a running orchestration is serialized and saved on the MessageBox database, and this operation incurs a latency cost. The serialization of the internal state includes all messages and variables instantiated and not yet released in the orchestration. The larger the messages and variables, and the greater the number of these, the longer it will take to persist the internal state of an orchestration.

An excessive number of persistence points can lead to significant performance degradation. For this reason, we recommend eliminating unnecessary persistence points from orchestrations, and reducing the number of transactional scopes and Send shapes. This approach decreases the contention on the MessageBox due to orchestration dehydration and rehydration, increases the overall scalability, and reduces the orchestration latency. Also, always keep the internal state of an orchestration as small as possible. This technique can significantly reduce the time spent by the XLANG Engine to serialize, persist and restore the internal state of an orchestration in case of persistence point. One way to achieve this is to create variables and messages as late as possible, and release them as early as possible; for example, introducing nontransactional scopes inside your orchestrations and declaring variables and messages within these inner scopes instead of declaring them at the top-most level.

For more information, see the following resources:

Nesting Orchestrations


It is better to use the Call Orchestration shape rather than asynchronous mechanisms (Direct Bound Ports, Self-Correlating Ports, and the Start Orchestration shape). The use of the Call Orchestration shape has some disadvantages since it introduces a strong dependency between parent and child orchestrations and enables only synchronous calls between these components; however, it is best strategy for maximizing scalability and performance. In fact, the use of mechanisms such as Direct Bound Ports, Self-Correlating Ports and the Start Orchestration shape allows for loosely decoupled caller orchestrations from caller orchestrations, and also allows implement asynchronous communication patterns between them. However, all these techniques require multiple roundtrips to the MessageBox database to persist and rehydrate the internal state of the caller orchestration and to exchange messages between these components. Consequently, the use of asynchronous patterns improves the flexibility of a BizTalk application, but can significantly increase the contention on the MessageBox, and can reduce the overall throughput and speed of the application.

For more information, see the following resources:

Inline Sends and Messaging-Only Patterns


Whenever possible, minimize the use of orchestrations and privilege messaging-only patterns to increase the overall throughput and reduce the latency of the business processes. If there is no need to run long-running transactions or to invoke several systems for each request, you could consider eliminating orchestrations and moving business logic to Receive and Send ports. In this case, implement custom pipelines and reuse the helper classes invoked inside orchestrations. To achieve better performance in low latency scenarios, adopt one of the following approaches:

  • Eliminate unnecessary orchestrations and adopt messaging-only patterns to reduce the total amount of round trips to the MessageBox database, and to decrease the latency due to database access. The diagram below shows how a messaging-only pattern can be implemented.

  • Inside orchestrations, eliminate logical ports bound to physical ports and use inline sends in their place (for example, an instance of a SOAP or WCF proxy class to invoke a downstream Web service, or an ADO.NET component to invoke a SQL Server database or an Oracle database) invoked inside an Expression shape. Until this technique is adopted, by not using adapters and physical ports, the application will not benefit from their functional capabilities such as batching, retries, correlation sets initialization, declarative configuration, and secondary transports. The diagram below shows how an inline send can be accomplished.

Design Patterns


The Orchestration Designer allows developers to implement a wide range of enterprise integration patterns (such as Aggregator, Exception Handling and Compensation, Message Broker, Scatter and Gather, Sequential and Parallel Convoy). Those patterns can eventually be combined to realize complex Enterprise Application Integration (EAI), Service Oriented Architecture (SOA), and Business Process Management (BPM) solutions with BizTalk Server.

For more information, see the following resources: