Azure Table Persistence supports two underlying storage services, each with a distinct pricing model:
- Azure Table storage: Billed per storage transaction. Each read, write, or delete counts as one transaction at a flat rate, billed per 10,000 operations.
- Azure Cosmos DB for Table: Billed based on Request Units (RUs). Read and write operations are priced differently, and actual RU consumption depends on the size of the stored entity. See the rate limiting documentation and the Microsoft Cosmos DB capacity calculator for Azure Cosmos DB Table API sizing guidance.
Operations per message
The tables below show the number of storage operations performed by the persistence for each message processing scenario. Use these counts together with the expected message throughput to estimate the total daily transactions or the required provisioned RUs.
Entity group transactions (batch commits) are billed as one transaction per entity in the batch, not as a single transaction for the entire batch.
Without Outbox
| Incoming message scenario | Read operations | Write operations | Total per message |
|---|---|---|---|
| No Saga | 0 | 0 | 0 |
| Saga (new) | 1 | 1 | 2 |
| Saga (update) | 1 | 1 | 2 |
| Saga (complete) | 1 | 1 | 2 |
- Read: One
GetEntitycall to load the saga. - Write: One entity group transaction containing the saga insert, update, or delete.
With Outbox
| Incoming message scenario | Read operations | Write operations | Total per message |
|---|---|---|---|
| No Saga | 1 | 2 | 3 |
| Saga (new) | 2 | 3 | 5 |
| Saga (update) | 2 | 3 | 5 |
| Saga (complete) | 2 | 3 | 5 |
- Reads: One
GetEntityfor the outbox deduplication check, and one for the saga load. - Writes: The outbox record insert and saga operation are committed together in one entity group transaction (counted as two individual write transactions). After outgoing messages are dispatched, a separate write updates the outbox record to mark it as dispatched.
All write types — inserts, updates, and deletes — count equally as write transactions. In the saga complete + outbox scenario, the three write transactions are: the outbox record insert, the saga delete (both in the same entity group transaction), and the outbox set-as-dispatched update.
Item size estimation
The following sizes can be used as a starting point for storage capacity estimates. Actual sizes depend on the saga data model and the size of outgoing message bodies and headers.
| Record type | Estimated base size |
|---|---|
| Outbox record (pending dispatch) | ~300 bytes + outgoing message bodies and headers |
| Outbox record (dispatched) | ~200 bytes (operations payload is cleared after dispatch) |
| Saga record | ~300 bytes + saga data |
For Azure Cosmos DB Table API, item size directly affects RU consumption. See request unit considerations for details.
Outbox storage growth
Unlike Azure Cosmos DB, Azure Table storage has no native time-to-live (TTL) mechanism. Dispatched outbox records are updated to clear the operations payload but are not automatically deleted from the table.
The number of outbox records retained at steady state is proportional to message throughput and the outbox deduplication period:
Retained outbox records ≈ Message throughput (per second) × Deduplication period (seconds)
With the default seven-day deduplication period (604,800 seconds), an endpoint processing ten messages/second accumulates approximately six million outbox records. A cleanup process should be scheduled to delete outbox records older than the configured deduplication period.
Monitoring
Azure Table storage
Azure Monitor Storage Metrics provides per-table transaction counts observable from the Azure portal. Use these metrics to validate estimated operation counts against real traffic and to detect unexpected growth.
Azure Cosmos DB Table API
The Azure Cosmos DB Diagnostic Settings can route diagnostic logs to an Azure Log Analytics workspace, where they can be queried to observe RU consumption per operation. The Cosmos DB capacity calculator can also be used with the operation counts from the tables above to estimate the required provisioned throughput.
Capacity planning approach
- Measure saga and outbox item sizes in a test environment.
- Apply the formulas above to calculate Request Units.
- Multiply by expected message throughput (messages per second) to estimate costs.
- Account for retries due to optimistic concurrency conflicts or transient throttling — each retry adds one full set of operations.