ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 78

  1. Blog
  2. /Observability & SRE

json.dumps Compact vs Indent Lab

Hands-on json.dumps separators vs indent lab: real time and byte-size tradeoffs for compact vs pretty JSON encoding, measured on Linux localhost (lab).

Aditya Challa·30 September 2026·4 min read

Lab
On this page
  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — medium payload (p50)
  5. Size tradeoffs (medium)
  6. Reading it
  7. Relation to the orjson lab
  8. Indent throughput illusion
  9. Pitfalls
  10. When to pick what
  11. Reproduce
  12. Closing

Intro — what this post promises

json.dumps formatting: how much do separators=(',', ':'), default spaced separators, and indent=2 cost in time and bytes? This lab focuses on dumps options (not a rematch of the json-vs-orjson codec war). orjson is measured only because it is installed on this box.

Related links:

  • json vs orjson vs msgpack localhost lab
  • shutil copyfile vs manual localhost lab
  • str translate vs replace localhost lab
  • bytes vs bytearray localhost lab
  • setdefault vs defaultdict localhost lab
  • string concat vs join localhost lab
  • statistics vs manual mean localhost lab
  • perf_counter vs time localhost lab

Lab honesty (1 Oct 2026 IST): Python 3.13.5. orjson installed: True (ujson: no). Affiliates: 0. Wire JSON should be compact; indent is for humans.

Verdict up front (medium ~200 rows): compact ~2497 dumps/s (34,035 B) vs default ~2527 (39,837 B, speed ~0.99×, size compact/default ~0.85×). indent=2 ~2155 dumps/s (86,647 B, ~2.55× compact size; compact ~1.16× faster). orjson compact ~7.4× stdlib compact.


Arms

ArmOptions
defaultjson.dumps(obj) — separators ', ' / ': '
compactseparators=(',', ':')
indent2indent=2
indent2 + compact sepunusual hybrid
sort_keys compactsort_keys=True
orjson compact / indentif installed

Payloads: small (20 rows), medium (200), large (2000).


Lab topology

nested dict/list records; trials scale with size
metric: dumps/s + output UTF-8 bytes

Script: lab-evidence/75-json-dumps-compact-vs-indent/results/run_lab.py.


Lead table — medium payload (p50)

Armdumps/sout bytes
stdlib default2,52739,837
stdlib compact2,49734,035
stdlib indent=22,15586,647
sort_keys compact2,03134,035
orjson compact18,56034,035
orjson indent=214,29286,647

Size tradeoffs (medium)

Formbytesvs compact
compact34,0351.00×
default (spaced)39,8371.17×
indent=286,6472.55×

Pretty JSON more than doubled payload size here — bandwidth and disk tax, not just CPU.


Reading it

  • Compact separators are nearly free in time vs default (~0.99×) but save ~15% bytes — always use for APIs/logs on the wire.
  • indent=2 costs CPU (compact ~1.16×) and ~2.5× size — debug/pretty only.
  • sort_keys adds measurable overhead (compact ~1.23×) — use for deterministic diffs, not hot paths.
  • orjson still dominates encode when installed (~7.4×); indent remains costly even there (~1.30×).

Relation to the orjson lab

Lab 36 compared codecs end-to-end. This lab answers: within json.dumps, which kwargs blow up size/time? Use both posts together — pick a library, then pick formatting.


Indent throughput illusion

Indent arms can show high “MB/s out” because they emit more bytes per dump — that is not a win. Compare dumps/s and bytes per document separately. For APIs, optimize for compact dumps/s and small out_bytes, not pretty MB/s.


Pitfalls

  1. Shipping indent=2 in production APIs — multiplies bytes.
  2. Forgetting separators=(',', ':') — default inserts spaces.
  3. Sorting keys on every response — pay only when you need stable output.
  4. Inventing orjson numbers when it is not installed — we only report it because import orjson succeeded here.

When to pick what

NeedPrefer
Wire / storage JSONcompact separators
Human debug dumpindent=2 (locally)
Canonical/diffablesort_keys=True + compact
Max encode speedorjson (if dependency OK)

Reproduce

python3 lab-evidence/75-json-dumps-compact-vs-indent/results/run_lab.py

Evidence: /workspace/lab-evidence/75-json-dumps-compact-vs-indent/results/.


Closing

Compact on the wire; indent for eyeballs. On this box medium compact matched default speed (~0.99×) at ~15% fewer bytes, while indent=2 grew size ~2.5× and slowed dumps ~1.16×. orjson added another ~7× on compact encode when available.

json.dumpsseparatorsindentcompact jsonorjsonpythonlocalhost labsre

Lab evidence

What I found running this

Lab 1 Oct 2026 IST. Python 3.13.5; orjson installed True, ujson no. Measured small, medium, and large nested records. Medium compact: ~2497 dumps/s and 34,035 bytes; indent=2: ~2155 dumps/s and 86,647 bytes, about 2.55x larger. Compact was ~1.16x faster. Affiliates: 0. Evidence: lab-evidence/75-json-dumps-compact-vs-indent/results/.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 18

    fnmatch vs re Name Filter: Localhost Lab

    Hands-on fnmatch.filter vs re.compile name-list filtering measured on Linux localhost.

    Observability & SRE · 30 Sept 2026

  • Plate 84

    tarfile vs zipfile Create+Extract: Localhost Lab

    Hands-on tarfile vs zipfile create+extract lab: real MB/s on a mixed small-file fixture (uncompressed tar vs zip), measured on Linux localhost for SREs.

    Observability & SRE · 30 Sept 2026

  • Plate 85

    scandir vs listdir vs iterdir: Localhost Lab

    Hands-on os.scandir vs listdir vs Path.iterdir lab: real entries/s for names and is_file on a synthetic tree, measured on Linux localhost (lab) for SREs.

    Observability & SRE · 30 Sept 2026

On this page

  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — medium payload (p50)
  5. Size tradeoffs (medium)
  6. Reading it
  7. Relation to the orjson lab
  8. Indent throughput illusion
  9. Pitfalls
  10. When to pick what
  11. Reproduce
  12. Closing
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove