MessagePack, CBOR and BSON: Three Binary Answers to JSON
Three formats that all get called binary JSON and exist for completely different reasons. What each one adds to the JSON data model, and what happens to those additions on the way back out to text.
Three formats turn up again and again in places where JSON would have been the obvious choice: MessagePack, CBOR and BSON. All three encode roughly the JSON value model as bytes rather than characters, all three get described as binary JSON, and that description stops being useful the moment you have to work with one. They were built by different people for different problems, and they disagree about exactly the parts that matter.
Here is what each one actually adds, which of those additions survive a conversion back to text, and how to read a file you have been handed without installing the stack that produced it.
The idea all three share#
JSON's value model is maps, arrays, strings, numbers, booleans and null. Each of these formats keeps that model and changes the encoding. A length becomes a byte instead of a pair of brackets, an integer keeps its width instead of becoming a double, and binary data gets a type of its own instead of riding inside a string as base64. The result is smaller, faster to parse, and unreadable in a text editor. That last part is the whole trade.
The differences begin where each format decided the JSON model was not enough.
MessagePack: the compact one#
MessagePack came from wanting JSON's flexibility without JSON's size. Small values encode in a single byte: integers from -32 to 127, and short strings and arrays, carry their length inside the type byte itself. Integers keep their width, so a 64-bit identifier stays exact rather than being rounded through a double. Binary has a real type. The MessagePack format reference covers the encoding, and you can convert MessagePack to JSON to read one.
The extension mechanism is the catch. Tags from -128 to 127 are application-defined, so two producers can use tag 5 for two unrelated things, and only the timestamp extension was later standardised. An extension type you were not expecting is not a corrupt file. It is a file whose meaning lives in somebody else's source code.
CBOR: the standardised one#
CBOR is the same idea taken to the IETF and written down, first as RFC 7049 and now as RFC 8949. It adds tags that attach meaning to the item that follows: tag 0 is an RFC 3339 date string, tag 2 a big integer, tag 4 a decimal fraction. It also specifies deterministic encoding rules, which is the reason signature formats can be built on it at all. Its reach comes from where it was adopted rather than from broad popularity: WebAuthn and FIDO2 credentials, COSE signing, CoAP messaging on constrained devices and C2PA provenance manifests are all CBOR underneath. The CBOR format page lists the major types, and CBOR to JSON will open a captured payload.
BSON: a database's storage format that got out#
BSON was made with MongoDB in 2009 to fix two things JSON did badly for a database. Every number was a double, and reaching the tenth field meant parsing the first nine. Length prefixes fixed the traversal; a type byte per field fixed the numbers, so int32, int64, double and decimal128 are distinct types. Dates are 64-bit milliseconds rather than parsed strings, and ObjectId is a real 12-byte type whose leading four bytes are a timestamp, which is why Mongo ids sort roughly by creation order. Nearly every .bson file in circulation is mongodump output, and BSON to JSON reads one without restoring it to a database first. The BSON format page has the document layout.
Which one you are probably holding#
- A .msgpack file is usually a cache entry, a queue payload or persisted application state from a service that cared about bytes on the wire.
- A .cbor file is usually a credential, a signed structure or a device message, and the tags are the interesting part rather than an implementation detail.
- A .bson file is almost always a dump of a MongoDB collection, which means it is almost always production records.
- If the extension is missing, the shape helps. BSON opens with a little-endian document length and is one long run of typed, length-prefixed fields, which is fairly distinctive once you have seen it.
Reading one, and the round trip that is not one#
For inspection, JSON is the right target: it is the model all three are based on, so the mapping is about as direct as conversion gets. When the records have a regular shape, a table is easier to scan than nested JSON, and MessagePack to CSV or BSON to CSV will flatten it. Going the other way, JSON to MessagePack exists, but a round trip through JSON is not lossless in the way it appears to be. Anything the original encoded that JSON cannot express was already normalised on the way in, so re-encoding produces a valid file with different contents.
The same type-flattening problem shows up whenever structured data moves into a spreadsheet, and the CSV, JSON and Excel guide covers that half of it.
None of the three is better than the others. MessagePack is the smallest and the least specified, CBOR is the standardised one with real semantics, and BSON is a database format that escaped into general use. Knowing which you have tells you what to expect when the values that do not fit JSON arrive at the other end.
Troubleshooting
They are normalised forms of types JSON cannot hold: an ObjectId, a Decimal128, a CBOR tag or a binary blob. The conversion summary names them. They are reported deliberately rather than dropped.
Expected where the value exceeds what JSON numbers represent exactly. Keeping it as text preserves the digits; converting it to a JSON number would not.
Likely an application-defined extension type. The tag number is portable, its meaning is not, so you need the producing application's definition.
Normal. Field names, quoting and base64 for binary all cost bytes that the binary encoding avoided. Size is the reason these formats exist.
Frequently asked questions
Is MessagePack just smaller JSON?
Mostly, but not only. It also keeps exact integer widths, allows non-string map keys and has a real binary type, none of which JSON can express. Those are the values that need normalising when you convert back to text.
Why does CBOR exist when MessagePack already did?
Because CBOR is a standard rather than a convention. It has an IETF specification, a tag mechanism for semantics such as dates and big integers, and deterministic encoding rules that let signature formats rely on it. That is why WebAuthn and COSE use it.
Can I convert JSON back into BSON here?
No. That route is not published. Rebuilding BSON would mean inventing the type information JSON discarded, including deciding which strings were meant to be an ObjectId or a date, and guessing that is worse than not offering it.
Is my file uploaded to convert it?
No. Decoding runs in your browser. These files are usually captured payloads or database dumps, so not transmitting them is the point rather than a bonus feature.
Which should I pick for a new service?
CBOR if you need a standard other people implement independently, or if anything is signed. MessagePack if the only requirement is compactness between systems you control. BSON only if MongoDB is already in the picture.
