Change Feed Processor

Earn 25 points (50 with Pro) in two steps

  1. ① Read through the lesson — each section gets a ✓ as you scroll through it.
  2. ② When every section has a ✓, tap Complete lesson.

0 of 12 read · keep scrolling

✦ See fewer ads and earn double points — 50 a lesson instead of 25 — with Pro

Mastering the Azure Cosmos DB Change Feed Processor

Introduction: Why Event-Driven Architectures Matter

In modern distributed systems, data is rarely static. When an application updates a user profile, logs a sensor reading, or processes a financial transaction, that data change often serves as a trigger for a chain of subsequent actions. In the context of Azure Cosmos DB, the Change Feed is the backbone of this event-driven behavior. It provides a persistent, ordered, and reliable record of changes made to your data within a container.

The Change Feed Processor is a high-level library built on top of the Change Feed API. It abstracts away the complexities of managing state, load balancing across multiple instances, and tracking progress, allowing developers to focus on business logic rather than infrastructure plumbing. Understanding how to implement and scale the Change Feed Processor is essential for building reactive, decoupled, and highly responsive AI-driven applications. Whether you are building a real-time analytics engine, synchronizing data across microservices, or triggering machine learning inference pipelines, the Change Feed Processor is the tool that makes it happen.


Not read yet

Understanding the Fundamentals of the Change Feed

At its core, the Change Feed is a sorted list of documents within a Cosmos DB container, ordered by the time they were modified. When you enable the Change Feed, the database effectively exposes a stream of operations—inserts and updates—that occur on your data. It does not include deletes by default, though you can enable "soft deletes" to track those as well.

How the Change Feed Differs from Standard Queries

Unlike a standard query that returns the current state of your data, the Change Feed is an append-only log. It maintains a cursor (or "continuation token") that allows your application to resume reading from exactly where it left off, even if the application restarts or the connection drops. This persistent state makes it the ideal mechanism for maintaining data consistency across different storage systems or triggering asynchronous background tasks.

Callout: Change Feed vs. Queries A standard query in Cosmos DB answers the question, "What does the data look like right now?" In contrast, the Change Feed answers the question, "What has changed, and in what order?" This distinction is critical for architects; while queries are for point-in-time retrieval, the Change Feed is for state transitions and event-driven workflows.


Not read yet

The Role of the Change Feed Processor Library

While you can consume the raw Change Feed using the Cosmos DB SDK directly, this is rarely recommended for production workloads. The Change Feed Processor (CFP) library simplifies this by managing the "lease" mechanism. To process changes in parallel across multiple compute nodes, the CFP uses a separate container (the "Lease Container") to track which instance is processing which partition range.

Key Benefits of Using the Processor Library:

  • Automatic Load Balancing: As you add or remove compute instances, the library automatically redistributes the work.
  • Checkpointing: It automatically saves the progress (continuation token) of your processing, ensuring that no events are missed in the event of a crash.
  • Scalability: You can scale your processing power by simply spinning up more instances of your application; the library detects the change in topology and balances the load.
  • Fault Tolerance: If a processing instance fails, other instances automatically pick up the work that the failed instance was responsible for.

Not read yet

Step-by-Step Implementation Guide

Implementing the Change Feed Processor requires two containers: the Monitored Container (where your data lives) and the Lease Container (where the processor stores its state).

Step 1: Set Up the Lease Container

The lease container is a small, low-throughput collection that acts as a coordination store. It stores the metadata about which instance is processing which physical partition. You should create this container with a small amount of Request Units (RUs), as it is not meant for heavy query traffic.

Step 2: Configure the Change Feed Processor

To initialize the processor, you need the CosmosClient and references to both the monitored and lease containers. You then use the ChangeFeedProcessorBuilder to define your logic.

// Example: Initializing the Change Feed Processor in C#
Container monitoredContainer = client.GetContainer("Database", "Items");
Container leaseContainer = client.GetContainer("Database", "Leases");

ChangeFeedProcessor processor = monitoredContainer
    .GetChangeFeedProcessorBuilder<MyDataModel>(
        processorName: "myProcessor",
        onChangesDelegate: HandleChangesAsync)
    .WithInstanceName("instance-01")
    .WithLeaseContainer(leaseContainer)
    .Build();

await processor.StartAsync();

Step 3: Implement the Change Handler

The onChangesDelegate is where your business logic resides. This method receives a batch of changes as a list of items.

async Task HandleChangesAsync(
    IReadOnlyCollection<MyDataModel> changes, 
    CancellationToken cancellationToken)
{
    foreach (var item in changes)
    {
        // Process each item, for example, send to an AI service
        Console.WriteLine($"Processing item: {item.Id}");
        await CallAIModelAsync(item);
    }
}

Note: The HandleChangesAsync method should be idempotent. Because the Change Feed guarantees "at-least-once" delivery, it is possible for your code to receive the same item more than once under certain failure scenarios. Ensure your downstream logic can handle duplicate events without adverse effects.


Not read yet

Best Practices for Production Environments

When deploying the Change Feed Processor to production, you must account for latency, throughput, and error handling. A poorly configured processor can lead to "lag," where the processor falls behind the actual write operations in the database.

1. Optimize Your Lease Container

The lease container is essential for performance. Because it is accessed frequently, you should ensure it is located in the same region as your monitored container. Set the throughput to a minimum, but be prepared to scale it up if you have an extremely high number of physical partitions in your monitored container.

2. Implement Proper Error Handling

If your HandleChangesAsync method throws an unhandled exception, the processor will retry the batch indefinitely. If the error is transient (like a network timeout), this is good. However, if the error is due to a malformed document, the processor will be stuck in a retry loop. Always wrap your logic in a try-catch block and log the error.

3. Monitor the Lag

Lag is the time difference between the latest write in your database and the last processed item. You can monitor this using Azure Monitor. If your lag is consistently increasing, you are likely under-provisioned in terms of compute power (the number of instances running the processor) or your processing logic is too slow.

Tip: Scaling Strategies To scale your processing, you do not need to change the code. Simply deploy more instances of your application. The Change Feed Processor uses the InstanceName to identify itself. As long as all instances point to the same Lease Container, they will automatically partition the work among themselves.


Not read yet

Common Pitfalls and How to Avoid Them

Even experienced developers encounter challenges when working with the Change Feed. Below are the most frequent issues and strategies to mitigate them.

Pitfall 1: Long-Running Processing Logic

If your HandleChangesAsync method performs a heavy operation, such as an synchronous call to a slow third-party API, the entire batch processing for that partition will stall.

  • Solution: Perform heavy I/O operations asynchronously and, if possible, parallelize the processing within the batch. Never block the thread synchronously.

Pitfall 2: Ignoring the Partition Key

The Change Feed is ordered per partition key. If you are processing data that requires global ordering, you must be aware that the Change Feed only guarantees order within a logical partition.

  • Solution: Design your data model so that events that must be processed in strict sequence share the same partition key.

Pitfall 3: Inadequate Throughput on the Monitored Container

If you are pushing data into your monitored container faster than the Change Feed can read it, you might hit the RU limits of your container.

  • Solution: Ensure your monitored container has enough RU/s to handle both the incoming writes and the background reads from the Change Feed Processor.

Not read yet

Comparison: Change Feed Processor vs. Other Patterns

When building AI solutions, you might wonder if you should use the Change Feed or another pattern like a traditional ETL process.

Feature Change Feed Processor Traditional ETL
Latency Near real-time (ms) Scheduled (minutes/hours)
Complexity Low (managed library) High (custom scripts)
Reliability Native persistence Depends on custom state
Scale Automatic Manual
Trigger Event-based Time-based

Advanced Scenarios: Filtering and Projections

Sometimes, you do not want to process every single change in the database. You might only care about specific types of documents or specific fields.

Using Projections

While the Change Feed itself returns the full document, you can implement filtering logic inside your handler. However, if you want to reduce the data being transferred, you can maintain a secondary "summary" container where you only write the fields that are relevant to your AI model.

Handling Deletes

As mentioned previously, the standard Change Feed only tracks inserts and updates. If your AI model needs to know when a record has been deleted, you must implement a "soft delete" pattern. Instead of using the DELETE command, add a property like isDeleted: true to the document. The Change Feed will capture this update, allowing your processor to react accordingly.


Not read yet

Integrating with AI and Machine Learning

The primary use case for this module is developing AI solutions. The Change Feed Processor acts as the "Ingestion Layer" of your AI pipeline.

Example: Real-time Sentiment Analysis

Imagine you are storing customer reviews in Cosmos DB. You want to run a sentiment analysis model whenever a new review is added.

  1. Ingestion: Review is saved to Cosmos DB.
  2. Processor: The Change Feed Processor picks up the new document.
  3. Inference: The processor calls an Azure Machine Learning endpoint with the review text.
  4. Action: The processor writes the sentiment score back to the original document or a separate analytics collection.

This architecture ensures that your AI models are always working on the most recent data without requiring the user to wait for the analysis to complete during the initial write request.


Deep Dive: How the Lease Mechanism Works

The lease mechanism is arguably the most important part of the Change Feed Processor. It operates on a decentralized model. Each instance of the processor "claims" a lease for a specific physical partition of the monitored container.

  1. Initialization: When the processor starts, it looks at the lease container. If it finds unowned leases, it claims them.
  2. Heartbeat: The processor periodically updates the lease with a timestamp to prove it is still alive.
  3. Rebalancing: If a new instance comes online, it sees that other instances own too many leases and requests a share of them. The existing instances gracefully release some of their leases to the new instance.
  4. Expiration: If an instance crashes, it stops updating its heartbeats. After a timeout period, other instances detect the expired lease and take ownership of it.

This design ensures that your processing architecture is highly resilient. You never have to worry about a "master" node failing; the system is self-healing.


Not read yet

Best Practices for Configuration

When building your ChangeFeedProcessorBuilder, there are several configuration options that can significantly impact performance:

  • WithPollInterval: This defines how often the processor checks the Change Feed for new changes. For latency-sensitive apps, set this lower. For high-volume, lower-priority background tasks, set this higher to save on RU costs.
  • WithMaxItems: This sets the maximum number of items per batch. If your items are large, a smaller batch size is better to avoid hitting the 2MB response limit of the Cosmos DB SDK.
  • WithStartTime: You can specify a point in time to start processing from. By default, it starts from the beginning of the feed. In production, you often want to set this to DateTime.UtcNow to only process changes moving forward.

Warning: Processing from the Beginning If you start a processor without a specific StartTime and you have a large amount of historical data in your container, the processor will attempt to process every single document that has ever existed in that container. Always explicitly define your start time if you do not intend to re-process historical data.


Not read yet

Common Questions (FAQ)

1. Does the Change Feed consume my RU/s?

Yes. Reading from the Change Feed is a read operation. It consumes Request Units from the monitored container. If you have a high volume of changes, you must account for this in your RU/s provisioning.

2. Can I have multiple processors reading the same feed?

Yes, but they must use different lease containers and different "processor names." If two processors use the same lease container, they will compete for the same partitions, and your data will be processed inconsistently.

3. What happens if I rename my container?

Renaming a container breaks the Change Feed link. You would need to re-initialize your lease container and point it to the new container name.

4. How do I handle very large items?

Cosmos DB has a 2MB limit per document. The Change Feed handles these documents fine, but you should ensure your processing logic is optimized for memory usage. Do not load thousands of large documents into memory simultaneously.


Not read yet

Practical Example: A Scalable Processing Architecture

To visualize how this works in a real-world scenario, consider a microservices-based application.

  • Service A (Order Service): Writes orders to Cosmos DB.
  • Service B (Inventory Service): Uses a Change Feed Processor to listen to the Order container. When an order is processed, it updates the stock levels.
  • Service C (Notification Service): Uses a separate Change Feed Processor to listen to the same Order container. When an order is processed, it sends an email to the customer.

Because these services are decoupled, the Order Service does not need to know that the Inventory or Notification services exist. If the Notification Service goes down, the Order Service continues to function perfectly. When the Notification Service comes back online, it reads the Change Feed from where it left off and catches up on all the missed emails. This is the power of a decoupled, event-driven architecture using Cosmos DB.


Not read yet

Summary and Key Takeaways

The Azure Cosmos DB Change Feed Processor is a powerful tool for building reactive, scalable, and resilient systems. By mastering this component, you move from simple CRUD applications to sophisticated, event-driven architectures that can power complex AI solutions.

Key Takeaways:

  1. Event-Driven Design: The Change Feed is the primary way to trigger actions based on data modifications, making it essential for modern, reactive applications.
  2. Abstraction is Key: Always use the Change Feed Processor library instead of interacting with the raw API. It handles the difficult work of load balancing, checkpointing, and fault tolerance for you.
  3. Idempotency Matters: Because of the "at-least-once" delivery guarantee, your processing logic must be idempotent—able to handle the same data multiple times without creating side effects.
  4. Monitoring is Critical: Always monitor your "lag" to ensure your processors can keep up with the rate of data ingestion. If lag increases, scale your compute resources.
  5. Lease Management: The lease container is the source of truth for your processor's state. Keep it in the same region as your data and ensure it has adequate throughput.
  6. Avoid Blocking Calls: Keep your change handler logic non-blocking and asynchronous to maintain high throughput and low latency.
  7. Partition Awareness: Understand that the Change Feed is ordered per partition key. Design your data models to respect this if strict ordering is a requirement for your business logic.

By following these principles and patterns, you can confidently build robust data pipelines that feed your AI models, synchronize your microservices, and provide the real-time responsiveness that modern users expect. As you progress in your journey with Azure Cosmos DB, continue to experiment with different partition strategies and processor configurations to see how they impact your specific workload. The flexibility of this platform is one of its greatest strengths, and the Change Feed is the engine that unlocks that potential.

Not read yet

Each section gets a ✓ as you scroll through it. Tap the button to jump to the next one.