28 September 2026 · 6 min
The simdjson library is a C++ library to parse and generate JSON. It is used in Node.js, ClickHouse, Meta Velox, StarRocks, Apache Doris, the Ladybird browser and many other systems. We released version 4.0 a year ago, in September 2025. Its headline feature was C++26 static reflection: you could turn a C++ structure into JSON, and back, without writing any glue code.
Today we are releasing version 5.0.
-
Static reflection is no longer guarded and is an officially supported feature. When your compiler has reflection enabled (e.g.,
g++ -std=c++26 -freflectionwith GCC 16), simdjson detects it by itself and the reflection-based functions become available. -
When deserializing a C++ structure through reflection, simdjson now uses key selectors (see below) by default: it reads the object in a single pass, whatever the order of the keys. You can return to the previous approach (one lookup per member) with
-DSIMDJSON_DISABLE_KEY_SELECTOR_REFLECTION=1. -
A positive integer in
[2^64, 10^20)is now reported as a big integer (BIGINT_NUMBER), like other overflowing integers, instead of a malformed number. When big integers are parsed as strings, a token such as123456789123456789123xis now rejected.
One major change is the key selectors. A common task is to extract a few fields from a JSON object. In simdjson 5.0 (C++20 or better), you can name the keys at compile time and visit the object once:
using namespace simdjson;
auto json = R"({ "name": "Daniel", "age": 42, "city": "Montreal" })"_padded;
ondemand::parser parser;
auto doc = parser.iterate(json);
std::string_view name, city;
uint64_t age = 0;
auto result = doc.get_object().for_each<"name", "city", "age">(name, city, age);
// name == "Daniel", city == "Montreal", age == 42
The keys can appear in any order. At compile time, simdjson builds a perfect hash function for your set of keys. At run time, recognizing a key takes a hash computed from a couple of bytes and one comparison. You can also pass one callback per key instead of variables. The iteration stops as soon as all keys have been found.
We added annotations for the data structures for automated (C++26) serialization and deserialization: rename, rename_all, alias, skip, default_value, flatten, deny_unknown_fields, transparent, and so forth.
struct [[= simdjson::rename_all<simdjson::case_style::camel_case>]] User {
std::string first_name;
int64_t user_id;
[[= simdjson::rename<"KEY">]] int api_key;
};
// {"firstName":"Ann","userId":7,"KEY":8}
We often get many JSON documents in one file or one network message. simdjson has long supported streams of documents separated by white space (NDJSON). In 5.0 we added:
- RFC 7464 JSON text sequences (each document preceded by the record separator character) and comma-separated documents;
stream_format::newline_delimited: you promise that each document sits on its own line. When you only read part of a document, simdjson jumps to the next line instead of walking over the rest of the document.simdjson::slice_at, which cuts a stream into blocks at document boundaries so you can parse the blocks on as many threads as you like. The built-in threaded mode uses at most two threads.
We also fixed several bugs in document_stream, found in an audit by Francisco Geiman Thiesen.
There are many other smaller features.
- NaN and infinity: JSON does not allow
NaNorInfinity, but many systems produce them anyway. If you defineSIMDJSON_ENABLE_NAN_INF, simdjson parses them, and serializes them. - Narrow types:
get_uint8(),get_int8(),get_uint16(),get_int16()check the range for you. With C++23,get_float32()andget_float64()returnstd::float32_tandstd::float64_t. The binary32 value is rounded once, directly from the decimal string, not through a double. - The DOM API can parse a buffer that has no padding (
parser.parse_unpadded(...)). It is slower than the regular function, but it never reads past the end of your buffer and it does not copy your data. - With C++17,
simdjson::padded_inputadds padding only when it is needed: when your string ends near a page boundary. - C++20 ranges: you can pipe On-Demand arrays and objects into
std::views::transformand other adaptors. - DOM arrays support reverse iteration (
rbegin(),rend()) with no allocation. - On-Demand objects offer
get_current_position()andrevert_position(): if you miss an optional field, you can go back to where you were instead of rescanning the whole object. char8_t(u8) variants of the string accessors in C++20.- Better pretty printing with the FracturedJson style, including tables.
- Memory-mapped files under Windows.
- We support the memory-safe compiler Fil-C.
The simdjson 5.0 release improved performance compared to simdjson 4.0 in some key cases. Let me review some of them.
I built both versions with GCC 16.1 (-O3, CMake Release) and ran them on an Intel Xeon Gold 6548N (Emerald Rapids), pinned to one core.
Let us start with DOM parsing of our standard files (GB/s):
Files full of numbers (canada, marine_ik, mesh, numbers) are 8% to 25% faster. And a file full of escaped Unicode characters (twitterescaped) is almost twice as fast: among other changes, we now decode consecutive uXXXX sequences without going back to the string scanner between them.
We also serialize faster. Printing floating-point numbers used to be a bottleneck. We replaced the ancient Grisu2 by Dragonbox, and removed calls to memcpy and memmove from the hot path.
The simdjson library is a community project. Since version 4.6, contributions came from fior512, 吴杨帆, Alecto Irene Perez, Francisco Geiman Thiesen, Max Bachmann, MoonFlowww, Advit Arora, Jaël Champagne Gareau, Taimoor Kiani, Vasily Pelikh, jmestwa-coder, liyinlong, AlbertoFVisconti, Aylin Dmello, Cuda Chen, Ezra Li, Madhurendra Purbay, Makkar, Pastoray, Paul Dreik, Pavel Kruglov, Piotr Kubaj, Yusuf İhsan Görgel, metsw24-max, neil, pratap singh, Vladimir Saraikin, wankun, xaldarof, Riyane El Qoqui, Justin Li and others. Thank you!
Daniel Lemire, "simdjson 5.0 is out," in Daniel Lemire's blog, September 28, 2026, https://lemire.me/blog/2026/09/28/simdjson-5-0-is-out/.
[BibTeX]
You can also subscribe by email to this blog (non-commercial, no ads, weekly email).
How to post code (C, C++, Java, Python, etc.):
Wrap your code in backticks, like this:
`int main() { return 0; }`