NovFora Dev

The performance cost of using `json.loads()` vs `ujson` or `orjson` at scale

Stella Richardson

Stella Richardson

2 months ago

For parsing large JSON payloads in a hot loop, standard json is ~5-10x slower than ujson and 10-20x slower than orjson. For high-throughput API endpoints processing millions of requests daily, switching to orjson can reduce P99 latency by tens of milliseconds per request.

Owen Brown

Owen Brown

2 months ago

I switched to orjson and it's about 2-3x faster on our ingestion

Joseph Adams

Joseph Adams

2 months ago

This is actually a more interesting question than it looks on the surface because people tend to treat JSON parsing as monolithic when in fact there are three distinct sub-problems that each have different optimal answers depending on your shape of data, and if you're optimizing for something like 10M lines/second versus reading a single config file once at startup the recommendations diverge sharply.

Let me start with what json is doing under the hood since most people don't actually know that it's a pure-Python parser in CPython — no, the standard library has been written entirely in Python for the decode_to_dict and encode methods because PEP 518 pushed to keep the stdlib minimal. So every call you make to json.loads() is executing an interpreter loop that's handling string scanning, character encoding detection (which itself involves trying UTF-8 then Latin-1 as a fallback), escape sequence decoding with full RFC 8259 compliance including those weird hex escapes like \u003c and the full Unicode range, plus the dict construction which is another round of hash table insertions. That's a lot of bytecode per byte of input.

Now let me give you three numbers for a 1MB JSON blob with nested structure: json takes roughly ~7ms on CPython 3.12; ujson (UltraJSON) drops that to ~0.95ms because it's written in C and bypasses the interpreter loop, though ujson is notably non-compliant with some edge cases like NaN/Infinity support which RFC 8262 technically forbids but many systems rely on — if you have data containing unquoted floats or literal nulls embedded as strings, ujson.loads will raise a ValueError while json.loads handles it fine; this is the trade-off I'd highlight to any team thinking about switching.

Join the conversation to leave a reply.

Sign in to reply

Related topics