Back to blog
Guides9 min read

JSON Patch vs JSON Merge Patch: Update JSON the Right Way

Two standards for partial JSON updates compared: JSON Patch (RFC 6902) operations and JSON Pointer, JSON Merge Patch (RFC 7386) semantics, the null trap, array handling, and when to use each with HTTP PATCH.

By Saifur Rahman Shochib

When a client needs to change one field of a large resource, sending the whole object back is wasteful and race-prone. Two IETF standards solve partial updates differently: JSON Patch (RFC 6902) sends a precise list of operations, while JSON Merge Patch (RFC 7386) sends a sparse copy of just the changes. They look similar but behave very differently, and choosing wrong leads to subtle bugs. This guide compares them and shows when to use each.

The partial-update problem

HTTP PUT replaces an entire resource; HTTP PATCH updates part of it. But PATCH does not define a body format — it just says 'apply these changes'. That is the gap JSON Patch and JSON Merge Patch fill: both are standardized media types that describe how to mutate a JSON document, so clients and servers agree on what a partial update means.

JSON Patch (RFC 6902)

JSON Patch is an ordered array of operations applied like a transaction. Each operation names an op and a target location written as a JSON Pointer (RFC 6901), such as /user/name. The six operations are add, remove, replace, move, copy, and test. A test operation asserts a value before proceeding, enabling optimistic concurrency — if the document is not what you expected, the patch fails.

Crucially, JSON Patch is all-or-nothing: a compliant implementation applies the whole array atomically, and if any operation fails, the document is left unchanged. That makes it safe for HTTP PATCH with no partial-write surprises. Its media type is application/json-patch+json.

JSON Patch: an explicit list of operationsjson
[
  { "op": "replace", "path": "/email", "value": "a@b.com" },
  { "op": "add",     "path": "/tags/-", "value": "new" },
  { "op": "remove",  "path": "/temp" }
]

JSON Merge Patch (RFC 7386)

JSON Merge Patch takes the opposite, simpler approach: the patch is just a sparse version of the document containing only the fields that should change. To update a user's email, you send an object with only that email field. The server merges it into the existing resource, recursing into nested objects. Its media type is application/merge-patch+json.

This is intuitive and compact for object updates, which is why it is popular for simple APIs. But the simplicity hides two important limitations.

JSON Merge Patch: a sparse copy of the changesjson
{ "email": "a@b.com", "temp": null }
// null here means: delete the "temp" field

The null trap and array limitation

In JSON Merge Patch, null is overloaded: setting a field to null means 'delete this field', not 'set it to null'. That means you cannot use Merge Patch to store an actual null value — the two intentions are indistinguishable. JSON Patch has no such ambiguity, because remove and replace are separate explicit operations.

Arrays are the second limitation. Merge Patch can only replace an entire array wholesale; it cannot append one item or change one element. JSON Patch can target a specific array index and add, remove, or replace individual elements. If your updates touch arrays, JSON Patch is usually the only correct choice.

The null traptext
Merge Patch:  { "nickname": null }   → DELETES nickname (cannot store null)
JSON Patch:   { "op": "replace", "path": "/nickname", "value": null } → sets null

Atomicity and concurrency

JSON Patch's test operation plus its atomic application make it well suited to optimistic concurrency: assert the current value, then change it, and the whole patch aborts if another writer got there first. JSON Merge Patch has no test operation and no built-in concurrency check, so guarding against lost updates is left to other mechanisms like ETags and If-Match headers.

When to use each

  • Use JSON Merge Patch for simple, object-shaped updates where you never need to store null, never modify individual array elements, and want the smallest, most intuitive payload.
  • Use JSON Patch when you need to add or remove array elements, store explicit null values, move or copy data, or assert preconditions for safe concurrent updates.
  • When in doubt for a public API, JSON Patch's explicitness avoids the null and array ambiguities that quietly bite Merge Patch users.

Generating a patch from two documents

You rarely hand-write patches — you compute them from a before and an after version of the document. A patch generator diffs the two and emits the operation list that transforms one into the other, which you can then send as the body of an HTTP PATCH request. The JSON Patch Generator produces RFC 6902 operations from two JSON documents, and the JSON Merge tool helps when you want merge-style combination instead of an operation list.

Frequently asked questions

What is the difference between JSON Patch and JSON Merge Patch?

JSON Patch (RFC 6902) is an ordered list of explicit operations (add, remove, replace, move, copy, test) targeting locations via JSON Pointer. JSON Merge Patch (RFC 7386) is a sparse copy of the document containing only changed fields. Patch is precise and atomic; Merge Patch is simpler but limited.

Why can't JSON Merge Patch set a field to null?

Because in Merge Patch, null means 'delete this field'. There is no way to distinguish deleting a field from setting it to an actual null value. If you need to store null, use JSON Patch, where remove and replace are separate operations.

Which should I use for an HTTP PATCH API?

Use JSON Merge Patch for simple object updates with no null storage and no per-element array changes. Use JSON Patch when you need array element operations, explicit nulls, moves, or precondition tests for safe concurrency. For public APIs, JSON Patch's explicitness avoids common pitfalls.

How does JSON Patch handle arrays?

JSON Patch can target a specific array index via JSON Pointer to add, remove, or replace individual elements. JSON Merge Patch cannot — it can only replace an entire array, which is a key reason to prefer JSON Patch for array-heavy updates.

How do I create a JSON Patch?

Compute it from a before and after version of the document with a patch generator, which diffs the two and emits the RFC 6902 operation list. Send that array as the body of your HTTP PATCH request with the application/json-patch+json media type.

Related tools

Try these tools

Keep reading

Related guides