Nothing is stored or transmitted as JSON. The driver serializes to BSON — "Binary JSON", specified at bsonspec.org (https://bsonspec.org/spec.html 674,861 ) — and the server stores BSON in its files. The grammar is short: a document is a 32-bit length, a list of elements, and a terminating zero byte; each element is a one-byte type code, a null-terminated field name, then the value.
Three differences do real work. BSON is typed, so an integer stays an integer where JSON knows only numbers, strings, booleans, arrays, objects and null. BSON is length-prefixed, so the server jumps over a 4 MB field instead of scanning for a closing brace. And BSON is ordered: {a:1, b:2} and {b:2, a:1} differ to an exact match on the whole object.
import { serialize, deserialize, EJSON, ObjectId } from 'bson';
const doc = { _id: new ObjectId('68c9a1f2b4c3d2e1f0a9b8c7'), title: 'Dune', pages: 412 };
const bytes = serialize(doc);
console.log('BSON bytes :', bytes.length, '| JSON chars :', JSON.stringify(doc).length);
console.log('hex :', bytes.toString('hex'));
console.log('EJSON :', EJSON.stringify(deserialize(bytes)));BSON bytes : 49 | JSON chars : 61
hex : 31000000075f69640068c9a1f2b4c3d2e1f0a9b8c7027469746c65000500000044756e650010706167
6573009c01000000
EJSON : {"_id":{"$oid":"68c9a1f2b4c3d2e1f0a9b8c7"},"title":"Dune","pages":412}BSON is not always smaller — a long integer costs 8 bytes where JSON might spend 3; compactness was never the point. The last line is Extended JSON, the text form used by mongoexport, Compass 1,815 and the Atlas 1,815 UI: canonical mode wraps every value ({"$oid":...}, {"$numberInt":"7"}), while relaxed mode prints plain JSON numbers and cannot round-trip an Int32 from a Double.
