Balancing Azure Cosmos DB Change Feed work across multiple workers
The Azure Cosmos DB Change Feed Processor spreads change processing across several .NET workers using a lease container for ownership and checkpoints. The article walks through the setup in the .NET SDK and explains when adding workers actually helps. It also covers why downstream operations must be idempotent, since changes can be delivered again after a failure.
Key points
- Workers that should cooperate must share one processor name and one lease container
- Different processor names create independent groups, and each one reads the whole feed
- Measure processing delay, retries and downstream capacity before adding instances
- Do not swallow handler exceptions; a failed batch can be delivered again
- Make side effects idempotent, for example by using the order ID as an idempotency key
- Bound concurrency and apply backoff when calling rate-limited downstream services
The Change Feed gives an ordered stream of item changes in a Cosmos DB container, so consumers do not need to poll. When one worker cannot keep up with a high-volume container, the Change Feed Processor shares the work across instances and stores progress in a lease container. Workers meant to cooperate need the same processor name and the same lease container; separate names create independent groups that each read the full feed.
Adding workers only helps when the feed can be split across more ranges and downstream systems can take the extra load. The processor handles ownership and checkpoints, but it cannot make your side effects safe to repeat. A batch can be redelivered after a crash, so handlers should be idempotent, should not swallow exceptions, and should cap concurrency toward downstream APIs to avoid throttling.
Real-world use
- A background service that updates a search index and reporting read model from an order container
- Several hosted .NET instances consuming order changes as one processing group
- An analytics consumer that must not double-count events when a batch is redelivered
Why it matters
If you scale a Change Feed consumer horizontally, the shared lease configuration and idempotent handlers matter as much as the number of instances. Checking lag and downstream limits first avoids paying for workers that do not raise throughput.