ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 95

  1. Blog

tomllib vs JSON Config Load: Localhost Lab

Hands-on tomllib vs json.load nested config lab: real loads/s (stdlib TOML read-only), measured on Linux localhost today in this hands-on lab for SREs.

Aditya Challa·1 October 2026·4 min read

Lab
On this page
  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — medium (p50)
  5. Scale sketch (file load)
  6. TOML vs JSON product tradeoffs
  7. Write-path reminder
  8. Reading it
  9. Types and comments
  10. vs configparser
  11. Binary open footgun
  12. Pitfalls
  13. Reproduce
  14. Limits
  15. Takeaway

Intro — what this post promises

Load equivalent nested app config from TOML via tomllib vs JSON via json. This lab reports loads/s on Linux localhost.

Stdlib tomllib is read-only (no dumps). It is not configparser-vs-json (lab 104) and not json dumps compact/indent (lab 75).

Related links:

  • configparser vs json localhost lab
  • json dumps compact vs indent localhost lab
  • heapq merge vs sorted localhost lab
  • islice vs list slice localhost lab
  • dataclass replace vs manual localhost lab
  • zoneinfo vs utc offset localhost lab
  • stat vs path stat localhost lab
  • html escape vs manual localhost lab

Lab honesty (1 Oct 2026 IST): Python 3.13.5. Affiliates: 0. Same logical tables/objects in .toml and .json.

Verdict up front (medium ≈ 22 sections / 306 keys, TOML 5260 B / JSON 5917 B): json.loads ~31027.0 loads/s; json.load file ~22155.3; tomllib.loads ~1054.1; tomllib.load file ~1021.4.


Arms

ArmAPI
tomllib.load(binary_file)stdlib TOML file
tomllib.loads(str)TOML string
json.load / json.loadsJSON file/string
json.loads on indentedwhitespace sensitivity

Lab topology

small / medium / large nested tables · 7 rounds · p50
metric: loads/s = 1 / p50_s

Script: lab-evidence/112-tomllib-vs-json/results/run_lab.py.


Lead table — medium (p50)

Armloads/s
json.loads31027.0
json.loads (indent=2 text)29808.0
json.load file22155.3
tomllib.loads1054.1
tomllib.load file1021.4

JSON file load is roughly ~22× tomllib here.


Scale sketch (file load)

Sizetomllib.loadjson.load
small6818.758524.0
medium1021.422155.3
large160.44290.0

TOML vs JSON product tradeoffs

  • TOML: comments, dates, human-friendly configs (pyproject.toml style); stdlib can only read.
  • JSON: faster parse here; ubiquitous interchange; write with json.dumps; no comments.
  • Need to emit TOML from Python? Use a third-party writer — not tomllib.

Write-path reminder

Teams often prototype in TOML then discover they need to serialize overrides at runtime. Budget a writer library early, or keep JSON/YAML for generated overlays while humans still edit a TOML base — this lab only measures load.


Reading it

  • Prefer TOML for hand-edited app/tooling config when comments matter.
  • Prefer JSON when load rate or machine interchange dominates.
  • Do not confuse with INI/configparser (lab 104) or dumps formatting (lab 75).
  • Open TOML files binary ("rb") for tomllib.load.

Types and comments

TOML preserves richer literal types (booleans/ints without quotes in our fixture) and allows # comments in real files — JSON does not. That ergonomics win is why pyproject.toml exists even when JSON parses faster on this box. If your config is generated and consumed only by machines, JSON’s speed and dumps symmetry usually win.


vs configparser

Lab 104 compared INI/configparser to JSON. TOML sits closer to JSON’s nested data model while staying human-editable. Do not treat tomllib numbers as interchangeable with configparser numbers — different parsers, different fixtures, different features (interpolation, etc.).


Binary open footgun

tomllib.load requires a binary file object. Passing open(path, "r") raises. Prefer Path.open("rb") or tomllib.loads(path.read_text()) when you already have str text (slightly different decode path — both measured).


Pitfalls

  • Expecting tomllib.dumps in stdlib (it does not exist).
  • Passing text mode file objects to tomllib.load.
  • Comparing against configparser without noting different data models.
  • Hot-reloading huge TOML on every request.

Reproduce

python3 lab-evidence/112-tomllib-vs-json/results/run_lab.py

Evidence: summary.json, summary.txt, fixtures/.

Cold-start services that parse config once can ignore the loads/s gap; hot reloaders and per-request overlays should prefer JSON or a cached dict.


Limits

One Linux box. Synthetic nested tables. Not TOML datetime/array-of-tables stress. Not orjson.


Takeaway

On medium nested config, json.load ~22155.3 loads/s beat tomllib.load ~1021.4 loads/s. Pick TOML for editable configs (read-only stdlib), JSON for speed/write path.

tomllibtomljson.loadapp configpython 3.13localhost labsreloads/s

Lab evidence

What I found running this

Lab 1 Oct 2026 IST. Python 3.13.5. medium: json_load_file 22155.3 loads/s; tomllib_load_file 1021.4; json_loads 31027.0. tomllib read-only. Not lab 104/75. Affiliates: 0. Evidence: lab-evidence/112-tomllib-vs-json/.

Notes when a lab post goes up

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

Related links

  • Plate 35

    configparser vs JSON Config Load: Localhost Lab

    A hands-on localhost lab comparing configparser and json.load for nested application configuration.

    Observability & SRE · 30 Sept 2026

  • Plate 17

    platform vs os.uname Inventory: Localhost Lab

    Hands-on platform.platform vs os.uname host inventory lab: real ops/s plus cache notes, measured on Linux localhost today in this hands-on lab for SREs.

    1 Oct 2026

  • Plate 75

    uuid.uuid4 vs uuid.uuid1: Localhost Lab

    Hands-on uuid.uuid4 vs uuid.uuid1 ID generation lab: real ops/s plus version/node checks, measured on Linux localhost today in this hands-on lab for SREs.

    1 Oct 2026

On this page

  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — medium (p50)
  5. Scale sketch (file load)
  6. TOML vs JSON product tradeoffs
  7. Write-path reminder
  8. Reading it
  9. Types and comments
  10. vs configparser
  11. Binary open footgun
  12. Pitfalls
  13. Reproduce
  14. Limits
  15. Takeaway
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove