Table of Contents

Introduction

In today’s post, I would like to discuss the Patch API (a.k.a. Partial Document Update), because I believe it is an excellent feature that every developer working with Azure Cosmos DB should be familiar with.

I have personally experienced situations where this feature helped solve issues that arise from the fact that normally documents in Azure Cosmos DB are updated as a whole.

Basics

The Patch API in Azure Cosmos DB enables partial document updates, meaning you can modify only specific fields instead of replacing the entire document. Traditionally, Cosmos DB updates required sending back the full document, which could be inefficient and costly, especially for large records or frequent changes.

Let’s analyze a specific example to better understand the possibilities offered by the Patch API.

Imagine you are building a knowledge enrichment platform for space entities. Whenever a new star, planet, or galaxy is added to your system, you want to automatically enrich its record with extra context that makes it useful for different audiences.

Instead of relying on manual updates, you deploy AI agents as background processes (using Microsoft Agent Framework). Each agent specializes in one type of enrichment:

  • The Mythology Agent checks if the name comes from Greek mythology (the isNameFromGreekMythology field).
  • The Storytelling Agent generates a short description understandable by a 7‑year‑old (the descriptionForChildren field).

Assume that we store space entities in Azure Cosmos DB in the following form.

{
  "id": "1",
  "Name": "Sirius",
  "Type": "Star",
  "Description": "Sirius is the brightest star in the night sky, located in the constellation Canis Major.",
  "DistanceLightYears": 8.6
}

When a new space entity is created, a SpaceEntityCreated message is published to an Azure Service Bus topic that has two subscribers (A and B). The message contains only one field: the ID of the space entity (in this case 1).

Architecture diagram showing 2 AI agents deployed in Azure Function Apps reading and writing data to Azure Cosmos DB.

Everything seemed smooth at first. The SpaceEntityCreated message triggered both subscribers:

  • Subscriber A (Mythology Agent) updated the IsNameFromGreekMythology field.
  • Subscriber B (Storytelling Agent) updated the DescriptionForChildren field.

And while you are ready to sip your coffee and dive into the next exciting AI feature… suddenly, a notification pops up.

Bug report…

“The IsNameFromGreekMythology field sometimes disappears.”

“Wait – now the DescriptionForChildren field is missing too!”

Confused, you dig deeper and quickly realize what is hapening:

  • The document is initially created without IsNameFromGreekMythology or DescriptionForChildren.
  • Each agent reads the full document (which doesn’t yet contain the other agent’s field).
  • Each agent adds its own field locally.
  • Each agent then writes back the entire document.
  • The last save overwrites the other agent’s addition.
  • Sometimes it works but only by chance, when the agents don’t collide…

After reading Concurrency in Azure Cosmos DB: Mastering ETag, IfMatch and IfNoneMatch, you already know you could address this issue by using ETag – catching the conflict and retrying when needed. But what if I told you there’s an even better way to do it: the partial document update.

Instead of replacing the whole document and risking collisions, Cosmos DB’s Patch API lets each agent update only its own field. No overwrites, no wasted retries, no accidental loss of data. It’s leaner, faster, and far more reliable when multiple agents (or processes in general) are working in parallel.

This is how SpaceEntitiesRepository could look like in its simplest form:

using Microsoft.Azure.Cosmos;

namespace DeployedinAzure.PatchApi
{
    public class SpaceEntitiesRepository(Container container)
    {
        public async Task PatchIsNameFromGreekMythologyAsync(
            string documentId,
            string partitionKey,
            bool isNameFromGreekMythology,
            CancellationToken token = default)
        {
            var patchOperations = new[]
            {
                PatchOperation.Set($"/{nameof(SpaceEntityDocument.IsNameFromGreekMythology)}", isNameFromGreekMythology)
            };

            await container.PatchItemAsync<SpaceEntityDocument>(documentId, new PartitionKey(partitionKey), patchOperations, cancellationToken: token);
        }

        public async Task PatchDescriptionForChildrenAsync(
            string documentId,
            string partitionKey,
            string description,
            CancellationToken token = default)
        {
            var patchOperations = new[]
            {
                PatchOperation.Set($"/{nameof(SpaceEntityDocument.DescriptionForChildren)}", description)
            };

            await container.PatchItemAsync<SpaceEntityDocument>(documentId, new PartitionKey(partitionKey), patchOperations, cancellationToken: token);
        }
    }
}

In the example above I used the PatchOperation.Set operation, which is the most common way to update a field. But the Cosmos DB Patch API supports several other operations too – such as Add, Remove, Replace, Increment, and Move – giving you flexibility to manipulate documents without replacing them entirely. I encourage you to get familiar with these methods by reading the documentation!

Also keep in mind that a single Patch request can include up to 10 operations. If you need to update more than 10 fields at once, you’ll need to split them across multiple requests.

3 reasons to use it

Now, once we understand the mechanics of partial document updates and how they differ from the full “default” document updates, let’s turn our attention to the advantages of this approach.

Performance improvements

Partial document updates are lighter than full replacements. Instead of sending the entire JSON payload back and forth, you only transmit the fields that change.

This leads to:

  • Lower latency
  • Minimized network overhead

Multi-region writes

First of all, I encourage you to read Concurrency in Azure Cosmos DB: Handling Conflicts in Multi-Write Regions to understand conflicts in mutli-region writes. Without understanding concepts explained in this blog post, you may not fully understand what is written below.

The key point to understand about multi-region writes and the Patch API in Azure Cosmos DB is that conflict resolution normally considers the entire document. With the default Last Writer Wins (LWW) policy, whichever write has the later _ts wins even if the two updates touched completely different fields but…

Because Patch API updates only specific JSON paths, Cosmos DB can recognize when two writes modify different parts of the document. In that case, the operations are not considered conflicting at all.

Here’s what actually happens:

  • If two updates modify different JSON paths (like isNameFromGreekMythology and DescriptionForChildren from our example): Cosmos DB treats them as independent changes and merges them automatically – no conflict!
  • If two updates modify the same JSON path: A real conflict exists, and the configured conflict resolution policy (e.g., LWW) applies as usual.

Conditional update

One of the most powerful features of partial updates is the ability to add a filter predicate. Instead of blindly applying a patch, you can enforce rules directly at the database level.

  • What it does: A filter predicate ensures the patch only executes if the document matches a condition (e.g., a property exists, equals a certain value, or is null).
  • Why it matters: This prevents race conditions and enforces business rules without extra round‑trips to check state in your application.

This is how the updated PatchIsNameFromGreekMythologyAsync method could look like:

        public async Task PatchIsNameFromGreekMythologyAsync(
            string documentId,
            string partitionKey,
            bool isNameFromGreekMythology,
            CancellationToken token = default)
        {
            var patchOperations = new[]
            {
                PatchOperation.Set($"/{nameof(SpaceEntityDocument.IsNameFromGreekMythology)}", isNameFromGreekMythology)
            };

            var options = new PatchItemRequestOptions
            {
                FilterPredicate = $"FROM c WHERE IS_NULL(c.{nameof(SpaceEntityDocument.IsNameFromGreekMythology)})"
            };

            try
            {
                await container.PatchItemAsync<SpaceEntityDocument>(documentId, new PartitionKey(partitionKey), patchOperations, options, token);
            }
            catch (CosmosException ex) when (ex.StatusCode == System.Net.HttpStatusCode.PreconditionFailed) // -> 412
            {
                // you may log or handle the case where the condition was not met
                // you may also do nothing and simply return
            }
        }

When the FilterPredicate is not satisfied then 412 – PreconditionFailed status is returned.

Summary

I hope you find this post helpful and already see opportunities to use the Patch API in Azure Cosmos DB in your own projects. Instead of replacing entire documents, Patch API lets you update only the fields that matter, which makes your system more efficient and resilient. In the space‑entity enrichment example, you saw how multiple agents can safely add their own data without overwriting each other’s changes. With targeted patch methods and conditional updates through FilterPredicate, you can keep your updates lean, reliable, and better suited for real‑world scenarios where many processes work in parallel.

Thanks for taking the time to read this post. I hope you found it useful. See you in the next one!

P.S. If after reading this post you’ve wondered whether Sirius comes from Greek mythology, the answer is yes 🙂

Categorized in:

Databases,