Skip to main content

fastjsonpatch

A drop-in, faster jsonpatch (RFC 6902 JSON Patch) for Python. make_patch and apply run in Rust and return the same patches, the same documents and the same exceptions as jsonpatch 1.34: typically 10-50x faster to make a patch and 6-15x faster to apply one.

pip install fastjsonpatch
import fastjsonpatch as jsonpatch      # the only line you change

src = {"name": "web", "replicas": 3, "ports": [80, 443]}
dst = {"name": "web", "replicas": 5, "ports": [80, 443, 8080]}

patch = jsonpatch.make_patch(src, dst)
patch.patch
# [{'op': 'replace', 'path': '/replicas', 'value': 5},
#  {'op': 'add', 'path': '/ports/2', 'value': 8080}]

patch.apply(src) == dst                # True; src is not modified
jsonpatch.apply_patch(src, [{"op": "remove", "path": "/ports/0"}])
# {'name': 'web', 'replicas': 3, 'ports': [443]}

Python 3.12+ (CPython). Prebuilt wheels for Linux (x86_64 and aarch64, glibc and musl), macOS (Apple Silicon and Intel) and Windows (x64); one wheel per platform covers every Python from 3.12 on. The only dependency is jsonpointer.

Why

JSON Patch describes a change to a JSON document as a list of operations (add, remove, replace, move, copy, test). It is how HTTP PATCH requests, Kubernetes and many APIs express partial updates, and how tools store or send the difference between two versions of a document.

jsonpatch is the standard Python implementation, and it is written in pure Python. That is fine for small documents, but the cost grows quickly:

  • make_patch on a 10,000-record document takes about 300 ms (on a fast machine), and diffing two Kubernetes OpenAPI specs (3.7 MB) takes about 140 ms.
  • apply deep-copies the whole document first, so even a one-operation patch on a large document costs tens of milliseconds.
  • A web service that applies or computes a patch per request spends 40-75 µs on each call, even for small resources.

fastjsonpatch keeps jsonpatch's behaviour exactly and moves these hot paths to Rust, so existing code gets faster without changes.

Speed

Measured on Linux x86_64, Python 3.13 (times are the best of several runs).

Real-world data:

scenario size jsonpatch fastjsonpatch speedup
Kubernetes OpenAPI v1.33 → v1.34: make_patch 3.7 MB, 283 ops 136.4 ms 9.6 ms 14x
Kubernetes OpenAPI v1.33 → v1.34: apply 283 ops 78.0 ms 11.4 ms 7x
3-op patch on the 3.8 MB spec 71.1 ms 10.1 ms 7x
3-op patch on the 3.8 MB spec, in_place=True 21.2 µs 4.7 µs 4x
PyPI metadata snapshots (8k records): make_patch 2,487 ops 255.2 ms 12.1 ms 21x
PyPI metadata snapshots: apply 2,487 ops 91.7 ms 14.0 ms 7x
REST resource, apply_patch per request ×1000 47.4 ms 7.5 ms 6x
REST resource, make_patch per request ×1000 74.4 ms 5.6 ms 13x

Synthetic records shaped like {"id", "name", "score", "tags": [..], "meta": {..}}:

workload ops make_patch: jsonpatch fastjsonpatch speedup apply: jsonpatch fastjsonpatch speedup
10k records, 100 field edits 100 292.61 ms 5.26 ms 56x 89.38 ms 7.90 ms 11x
10k records, insert 1 at front 49911 669.77 ms 42.78 ms 16x 535.21 ms 72.35 ms 7x
10k records, delete 50 44900 636.53 ms 40.46 ms 16x 563.20 ms 63.45 ms 9x
10k records, move 20 26305 434.93 ms 24.38 ms 18x 325.64 ms 41.03 ms 8x
2k ints, insert 1 at front 1 17.04 ms 1.91 ms 9x 581 µs 21 µs 27x
small config (200 keys), 1 edit 1 1.98 ms 35 µs 57x 464 µs 32 µs 15x

Python 3.14 made copy.deepcopy about 1.6x faster, so on 3.14 jsonpatch's apply on a large document is faster too and the gap shrinks to about 6x. make_patch is not affected. Run python bench/compare.py (from the source distribution) to measure on your own machine.

Why it is faster

make_patch. jsonpatch walks both documents in Python and compares every scalar with json.dumps(a) == json.dumps(b). That serialisation is about half of the runtime; the rest is isinstance checks against abstract base classes and path tuples rebuilt at every level. fastjsonpatch walks the documents in Rust over the CPython objects directly (no conversion to a Rust data structure), compares values natively with the same rules as the json.dumps comparison (1, 1.0 and True are all different, -0.0 != 0.0, NaN equals NaN), keeps the current path on a stack, and takes a single lockstep pass when two dicts have the same keys in the same order. It is a port of jsonpatch's DiffBuilder, so it produces the same operations in the same order, including detected moves.

apply. jsonpatch first runs copy.deepcopy on the document (so the original is not modified), then builds a JsonPointer and an operation object for each operation. For a small patch on a large document the copy is nearly all of the time. fastjsonpatch copies each dict and list with one C call and only recurses into values that are themselves containers; it keeps deepcopy's semantics (shared and cyclic references are copied once) but skips the bookkeeping for containers referenced only once. It then resolves the paths and runs the operations without creating intermediate objects.

Compatibility

fastjsonpatch is jsonpatch's own module (BSD licensed) with three methods routed to Rust: JsonPatch.__init__ (validation), JsonPatch.from_diff (make_patch) and JsonPatch.apply (apply_patch). Everything else is jsonpatch's code, so the public API is identical: JsonPatch, make_patch, apply_patch, JsonPatch.from_string, the operation classes, DiffBuilder, multidict, and the exceptions JsonPatchException, InvalidJsonPatch, JsonPatchConflict, JsonPatchTestFailed (with the same hierarchy, and JsonPointerException from jsonpointer).

The Rust code handles the common case and hands anything else back to the original Python code, so results never differ:

  • make_patch: values it cannot reproduce exactly (non-JSON types that need comparing, dict or list subclasses, a custom dumps=, nesting deeper than 1000) are diffed by the original DiffBuilder.
  • apply: works on plain dicts and lists. An operation that would fail, or that touches anything else, is run by the original operation classes before anything is mutated, so errors have the same type and message.
  • Subclasses of JsonPatch with custom operations, pointer_cls or json_dumper, and patches that are not lists or tuples, use the original code.

Known differences:

  • The exception classes belong to fastjsonpatch. An exception raised by the original jsonpatch package (for example inside another library that imports it) is not caught by except fastjsonpatch.JsonPatchConflict, and vice versa.
  • A value that is not a dict, list or JSON scalar inside a document being applied to is copied with copy.deepcopy on its own, so aliasing between such values is not preserved.

fastjsonpatch.__jsonpatch_version__ says which jsonpatch release the behaviour matches (currently 1.34).

How it is tested

About 1,570 tests, run on every supported OS and Python version:

  • Parity: random documents, mutations and patches (valid and invalid) run through both fastjsonpatch and jsonpatch 1.34, comparing the resulting patches and documents by repr and errors by type and message. Also covers aliasing, cycles, non-JSON values, subclasses, deep nesting and every fallback path.
  • jsonpatch's own test suite and doctests, run against fastjsonpatch.
  • RFC 6902 conformance: the json-patch-tests suite.

The source distribution includes the tests and the benchmark.

Development

pip install maturin
maturin develop --release
pip install "jsonpatch==1.34" pytest   # jsonpatch is the reference for the parity tests
pytest tests
python bench/compare.py                # speed vs jsonpatch on this machine

See MAINTAINING.md for releases and upkeep.

License

BSD-3-Clause. The Python module and the diff algorithm come from jsonpatch (Copyright (c) 2011 Stefan Kögl, BSD). The licenses of the Rust crates compiled into the wheels are in THIRD_PARTY_LICENSES.md.

Metadata

Release files for fastjsonpatch 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fastjsonpatch 0.1.0
File Size Uploaded
fastjsonpatch-0.1.0.tar.gz 58.0 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for fastjsonpatch 0.1.0
File
fastjsonpatch-0.1.0-cp312-abi3-win_amd64.whl CPython 3.12 abi3 Windows x86-64 Details
fastjsonpatch-0.1.0-cp312-abi3-musllinux_1_2_x86_64.whl CPython 3.12 abi3 Linux musl 1.2+ x86-64 Details
fastjsonpatch-0.1.0-cp312-abi3-musllinux_1_2_aarch64.whl CPython 3.12 abi3 Linux musl 1.2+ ARM64 Details
fastjsonpatch-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.12 abi3 Linux glibc 2.17+ x86-64 Details
fastjsonpatch-0.1.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.12 abi3 Linux glibc 2.17+ ARM64 Details
fastjsonpatch-0.1.0-cp312-abi3-macosx_11_0_arm64.whl CPython 3.12 abi3 macOS 11.0+ ARM64 Details
fastjsonpatch-0.1.0-cp312-abi3-macosx_10_12_x86_64.whl CPython 3.12 abi3 macOS 10.12+ x86-64 Details

Total release size: 2.1 MB

Release files / fastjsonpatch-0.1.0.tar.gz

Download URL fastjsonpatch-0.1.0.tar.gz
Size 58.0 kB
Tags Source
SHA-256 checksum
How to use checksums
c3efe2853403213e0e53d831b5b62aa4bbded61dfd06a6eb20a812540363a5f1
BLAKE2b-256 checksum
How to use checksums
9d1aa70ef9fad1a5dfd935ec0a55fafd51b6489d71fa23352b2cac11a351d312
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / fastjsonpatch-0.1.0-cp312-abi3-win_amd64.whl

Download URL fastjsonpatch-0.1.0-cp312-abi3-win_amd64.whl
Size 152.3 kB
Tags CPython 3.12 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
40e6517de168c66b8eac86fa7c95804c144fc046a7a044c10caa0cfc2adcaa1f
BLAKE2b-256 checksum
How to use checksums
0dc3a76c0662cc3d562229bbf573bf52c1a5c77b8f739f0363dbe2900527c8cd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / fastjsonpatch-0.1.0-cp312-abi3-musllinux_1_2_x86_64.whl

Download URL fastjsonpatch-0.1.0-cp312-abi3-musllinux_1_2_x86_64.whl
Size 470.6 kB
Tags CPython 3.12 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
f6a748b61cb8572c208e18448e2d321a2b8845dfc56485939055b81f88a78de5
BLAKE2b-256 checksum
How to use checksums
0048bca0131e19dc247f1e03384a3a475008e0d1a34cefeccf025dd76b1ef8d3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / fastjsonpatch-0.1.0-cp312-abi3-musllinux_1_2_aarch64.whl

Download URL fastjsonpatch-0.1.0-cp312-abi3-musllinux_1_2_aarch64.whl
Size 435.2 kB
Tags CPython 3.12 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
c2fd197d8f6c0f1383a85cf8b7bf693d70777ad4c1c3377b2310cc86fd64f64a
BLAKE2b-256 checksum
How to use checksums
f3b568bb9e4675c0af534092c41c9e5cf865db36edb85a47e807d76257407f87
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / fastjsonpatch-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL fastjsonpatch-0.1.0-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 259.1 kB
Tags CPython 3.12 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
f23bdae53031792430b1e0aa680084eb32791da61efca02856e635473d7a78ad
BLAKE2b-256 checksum
How to use checksums
1208390871e3309a08fed527def8fb36c1f2b64967e85cf7467811aeccafee4d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / fastjsonpatch-0.1.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL fastjsonpatch-0.1.0-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 256.4 kB
Tags CPython 3.12 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
55a0ae98d893f49f759e08f4bbe694778923fb078d1034e21bfbee3204838099
BLAKE2b-256 checksum
How to use checksums
866f900c82d1fa1f6afd80690415bed792cd065c3eaaf197dfc1735d12a4f9f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / fastjsonpatch-0.1.0-cp312-abi3-macosx_11_0_arm64.whl

Download URL fastjsonpatch-0.1.0-cp312-abi3-macosx_11_0_arm64.whl
Size 241.4 kB
Tags CPython 3.12 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
96a07e87dffd6c9fce2954692051eb2bf2f0570ba705becfb51d8773b91cc15f
BLAKE2b-256 checksum
How to use checksums
f3f9c3346e7a7886b560b650b62d1dcc9526895396801946c9a1f641e7d9163e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release files / fastjsonpatch-0.1.0-cp312-abi3-macosx_10_12_x86_64.whl

Download URL fastjsonpatch-0.1.0-cp312-abi3-macosx_10_12_x86_64.whl
Size 254.3 kB
Tags CPython 3.12 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
ef1e56f23ea4279dc2ca9c9f44dc8226a44a93bc0845d06f8dd69b0bb1b85979
BLAKE2b-256 checksum
How to use checksums
c3f39653a08b69cb21281859a541f0c54ebd935c597cb1cc44010895e3be53e6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 11, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.4

8 release files

0.1.3

8 release files

0.1.2

8 release files

This release

0.1.0 This release

8 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page