Introduction
orjson is a drop-in replacement for Python's json module that achieves significant speedups through a Rust implementation. It natively serializes types the standard library cannot (datetime, dataclass, UUID, NumPy) without custom encoders.
What orjson Does
- Serializes Python objects to JSON bytes 3-10x faster than stdlib json
- Deserializes JSON bytes/str to Python objects with strict RFC 8259 compliance
- Natively handles datetime, date, time, UUID, dataclass, and enum types
- Serializes NumPy arrays directly without manual conversion
- Provides option flags for pretty printing, sorted keys, and non-string dict keys
Architecture Overview
orjson is compiled from Rust using PyO3 bindings. The serializer walks Python objects through the C API, formats them directly into a byte buffer without intermediate string allocations. The deserializer uses a SIMD-accelerated JSON parser (simd-json inspired) for fast number and string parsing on modern CPUs.
Self-Hosting & Configuration
- Install via pip; pre-built wheels available for Linux, macOS, and Windows
- Requires no configuration; use
orjson.dumps()andorjson.loads()directly - Control output format via option flags:
orjson.OPT_INDENT_2,OPT_SORT_KEYS,OPT_NON_STR_KEYS - Handle custom types with the
defaultparameter (a callable for unrecognized types) - Returns bytes (not str) from dumps(); use
.decode()if a string is needed
Key Features
- Strict RFC 8259 compliance with correct Unicode surrogate handling
- Native datetime serialization to ISO 8601 format
- Direct NumPy ndarray serialization without .tolist() conversion
- Dataclass serialization without dict overhead
- Consistent 3-10x performance advantage in benchmarks across data shapes
Comparison with Similar Tools
- json (stdlib) — slower and cannot serialize datetime/dataclass without custom encoders
- ujson — faster than stdlib but slower than orjson; less strict on edge cases
- rapidjson — C++ based; comparable speed but lacks native datetime/NumPy support
- msgspec — similar performance with schema validation but different API design philosophy
FAQ
Q: Is orjson a true drop-in replacement for json?
A: Nearly. The main difference is dumps() returns bytes instead of str, and it does not support the cls parameter. Use the default kwarg for custom types.
Q: Why does dumps() return bytes? A: Avoiding the bytes-to-str decode step improves performance. Most web frameworks (FastAPI, Starlette) accept bytes directly for responses.
Q: Does orjson support streaming or incremental parsing? A: No. orjson processes complete documents in memory. For streaming JSON, use ijson or the stdlib json.JSONDecoder with raw_decode.
Q: Can I use orjson with FastAPI?
A: Yes. FastAPI supports custom JSON encoders. Set ORJSONResponse as the default response class for automatic orjson usage.