ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 06

  1. Blog

pickle vs json: Round-trip Lab

Hands-on pickle vs json local round-trip lab: real throughput and size for modest dict/list payloads (trusted data), measured on Linux localhost (lab).

Aditya Challa·30 September 2026·4 min read

Summary
On this page
  1. Intro — what this post promises
  2. Arms
  3. Lab topology
  4. Lead table — small payload (p50)
  5. Medium scale & size
  6. Reading it
  7. Trust boundary checklist
  8. Protocol 4 vs 5
  9. Pitfalls
  10. When to pick what
  11. Reproduce
  12. Closing

Intro — what this post promises

Local object cache / same-host IPC: is pickle faster and smaller than compact json for modest dict/list trees? This lab measures dumps / loads / round-trip ops/s and byte size on Linux localhost.

Security warning: pickle.loads on untrusted bytes is a remote-code-execution hazard. Use pickle only for trusted local data you wrote yourself.

Related links:

  • json vs orjson vs msgpack localhost lab
  • json dumps compact vs indent localhost lab
  • csv reader vs split localhost lab
  • copy vs deepcopy localhost lab
  • hashlib md5 vs blake2b localhost lab
  • bytes vs bytearray localhost lab
  • shutil copyfile vs manual localhost lab
  • perf_counter vs time localhost lab

Lab honesty (1 Oct 2026 IST): Python 3.13.5; protocols [4, 5] (HIGHEST=5). JSON uses compact separators. Affiliates: 0. Not a rematch of orjson/msgpack (lab 36) or indent formatting (lab 75).

Verdict up front (small, 100 rows): pickle p5 dumps ~25433/s vs json ~7640 (~3.33×); round-trip ~2.64×; size 7,342 B vs 11,368 B (pickle/json ~0.65×). Prefer pickle for trusted local caches; JSON for anything crossing a trust boundary.


Arms

ArmNotes
json.dumps/loadscompact separators=(',', ':')
pickle protocol 4 / 5binary
dumps / loads / round-tripseparate timings

Payloads: tiny (10), small (100), medium (1000) nested row dicts.


Lab topology

trials: tiny 5k / small 1k / medium 100
metric: p50 ops/s + out bytes

Script: lab-evidence/79-pickle-vs-json-roundtrip/results/run_lab.py.


Lead table — small payload (p50)

Armops/sbytes
pickle p5 dumps25,4337,342
pickle p5 loads21,7887,342
pickle p5 round-trip11,6137,342
json dumps7,64011,368
json loads10,40011,368
json round-trip4,39511,368

Medium scale & size

Formdumps/sround-trip/sbytes
pickle p51,88187474,612
json compact776419115,481

pickle÷json dumps medium ~2.42×; size ratio ~0.65×. Protocol 5 ≈ 4 here (dumps p5÷p4 small ~0.99×).


Reading it

  • Pickle wins trusted local encode/decode on these JSON-friendly dict trees — binary, no UTF-8 number formatting.
  • JSON stays the interchange format for APIs, logs, and anything untrusted readers touch.
  • Size — pickle was ~35% smaller than compact JSON on small/medium.
  • Never pickle.loads from the network, a user upload, or a shared queue without a hard trust boundary.

Trust boundary checklist

  1. Did your process write these bytes in this deployment? → pickle may be OK for a local cache file under your lock.
  2. Did they cross a network, user upload, or multi-tenant queue? → JSON/msgpack/protobuf — never pickle.
  3. Do non-Python readers need the blob? → JSON (or a schema’d binary format).

Round-trip speed does not override that checklist.


Protocol 4 vs 5

On these pure-dict payloads, protocol 5 was essentially tied with 4. Prefer protocol=5 (or HIGHEST_PROTOCOL) for new local caches anyway — newer opcodes help other object graphs (e.g. large binary out-of-band in some cases). Re-bench if your payload is numpy-heavy or self-referential.


Pitfalls

  1. Unpickling untrusted input — classic RCE.
  2. Using pickle across Python major versions / non-Python clients — fragile.
  3. Pretty JSON as a cache format — waste (see lab 75).
  4. Assuming protocol 5 always faster — measure; often a wash for pure-Python dicts.

When to pick what

NeedPrefer
Trusted process-local cachepickle (protocol 5)
Human/debuggable / cross-languageJSON
Untrusted or multi-tenant datanever pickle
Max wire speed + schemamsgpack/orjson (lab 36)

Reproduce

python3 lab-evidence/79-pickle-vs-json-roundtrip/results/run_lab.py

Evidence: /workspace/lab-evidence/79-pickle-vs-json-roundtrip/results/.


Closing

Pickle for trusted local speed/size; JSON for boundaries. On this box small pickle p5 dumps beat compact JSON by ~3.3× with ~0.65× the bytes — and still must never load strangers’ pickles.

picklejsonround-tripserializationlocal cachepythonlocalhost labsre

Lab evidence

What I found running this

Lab 1 Oct 2026 IST. Python 3.13.5; pickle protocol=5. small: pickle dumps 25433/s vs json 7640 (~3.33x); roundtrip ~2.64x; size pickle/json ~0.65x. UNSAFE to unpickle untrusted data. Affiliates: 0. Evidence: lab-evidence/79-pickle-vs-json-roundtrip/.

Notes when a lab post goes up

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

Related links

  • 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 50

    signal vs threading.Event Wakeup: Localhost Lab

    Hands-on signal SIGUSR1 vs threading.Event wakeup lab: real p50 latency in microseconds, measured on Linux localhost today in this hands-on lab for SREs.

    1 Oct 2026

  • Plate 76

    cmath vs math.hypot Magnitudes: Localhost Lab

    Hands-on cmath vs math.hypot magnitude ops lab: real ops/s for abs, polar, and phase, 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 — small payload (p50)
  5. Medium scale & size
  6. Reading it
  7. Trust boundary checklist
  8. Protocol 4 vs 5
  9. Pitfalls
  10. When to pick what
  11. Reproduce
  12. Closing
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove