Overview
Well-designed transactions are the foundation of reliable, queryable, and maintainable tracking in Business Activity Monitoring (BAM). This article describes the principles and practical patterns that produce clean transaction models — ones that are easy to query, alert on, and extend as your integrations evolve.
Business value
Poorly structured transactions produce ambiguous query results, make SLA monitoring difficult to configure, and accumulate tracking noise that slows down the BAM portal. Applying these design patterns from the start reduces rework, improves stakeholder visibility, and keeps your BAM environment performant as volume grows.
How it works
A BAM transaction defines a discrete business operation within a business process. Each transaction contains stages — checkpoints at which data is logged as the operation progresses. BAM correlates all stage events for a given operation using the Transaction Instance ID, which must be a stable, unique identifier generated by your integration and passed consistently through every stage call.
The decisions made at design time — how many transactions to create, how to name stages, which properties to track — directly determine what you can query, alert on, and reprocess.
Key practices
1. Model transactions around business operations, not Azure resources
Each transaction should represent a meaningful business operation — not an Azure service call or a pipeline step. Operations that a business analyst would recognise as distinct units of work are good transaction candidates.
| ✓ Good transaction name | ✗ Avoid |
|---|---|
Booking Request |
Logic App Run |
Invoice Validation |
Service Bus Message |
Shipment Dispatch |
HTTP Call to Carrier API |
Naming transactions after Azure resources makes the BAM portal difficult for non-technical stakeholders to use and couples your monitoring model to your infrastructure — which changes more frequently than your business operations.
2. Use a stable, business-meaningful correlation identifier
The Transaction Instance ID is how BAM links all stage events for a single operation run together. It must be:
- Unique per operation instance — two concurrent instances of the same operation must never share the same ID.
- Stable across all stages — the same value must be passed at every stage of the same operation.
- Business-meaningful where possible — using a booking reference, invoice number, or order ID makes it possible to query instances by business key without needing a technical trace ID.
Avoid using Azure-generated identifiers (Logic App run IDs, Service Bus message IDs) as your sole correlation property when a business key is available. Azure IDs change on reprocessing; business keys do not.
3. Keep stage count proportional to business checkpoints
Add a stage for each meaningful checkpoint where knowing the status of an operation instance has operational value. Do not add a stage for every action or Azure resource call in your workflow.
A good stage is one where a support team would say "I need to know whether the operation reached this point" during an incident. Stages like Received, Validated, Dispatched, and Completed map to these checkpoints. Stages like Retrieved from queue, Logged to table, or Sent HTTP request are implementation details — they add noise without operational value.
Three to seven stages per transaction is a healthy range for most integration workflows. Fewer than three usually means the operation is under-instrumented; more than ten usually means implementation details are being tracked instead of business checkpoints.
4. Track only properties that have query or alert value
Each tracked property increases the data volume written to your BAM datastore and the number of columns in your query results. Track properties that you will actually filter on, alert on, or display to stakeholders.
Good candidates for tracked properties:
- Business identifiers: order reference, customer ID, invoice number
- Status or outcome values that vary meaningfully: carrier code, validation result, error code
- SLA-relevant timestamps: external API call start time, carrier confirmation receipt time
Avoid tracking:
- Internal system identifiers that are only meaningful in debug contexts
- Large payload values or message bodies (use message archival for this instead)
- Properties that are identical across every instance of a transaction
5. Name stages and properties consistently across transactions
If multiple transactions within a business process share conceptually equivalent stages — such as a Received stage at the start of each transaction — use consistent names. Consistent naming makes it easier to build cross-transaction query monitoring rules and reduces the learning curve for support staff who query instances across multiple processes.
6. Separate high-volume and low-volume operations into distinct transactions
If your business process includes both high-volume routine operations (such as status poll updates) and low-volume critical operations (such as order confirmations), model them as separate transactions. This allows you to:
- Apply different purging policies (shorter for high-volume, longer for critical)
- Set distinct duration monitoring thresholds calibrated to the expected rate
- Avoid high-volume instances burying critical ones in query results
7. Plan for reprocessing at stage level
If any stage in a transaction may need to be reprocessed — for example, submitting a message to a downstream system when that system was temporarily unavailable — configure the reprocess endpoint for that stage when you create it, not after an incident occurs.
Reprocess configuration requires knowing the target endpoint type (HTTP, Service Bus queue, Service Bus topic, Event Grid, SFTP, or Blob storage). Document this decision alongside your transaction design so it is available when BAM is being set up.
Example scenario
A payments team designs a Payment Processing business process with three transactions:
| Transaction | Stages | Key tracked property | Purging |
|---|---|---|---|
Payment Received |
Received, Validated, Queued | paymentReference |
90 days |
Payment Processed |
Dequeued, Authorised, Settled | paymentReference, authorisationCode |
365 days |
Payment Notification |
Sent, Acknowledged | paymentReference |
30 days |
Each transaction uses paymentReference as the Transaction Instance ID, allowing support staff to look up the complete history of any payment by reference number across all three transactions. The Payment Notification transaction uses a shorter purging period because notifications are high-volume and low-value for long-term audit purposes. The Payment Processed transaction uses a 365-day retention period to satisfy compliance requirements.