Open-Source Wikis

/

MongoDB

/

Systems

/

BSON

mongodb/mongo

BSON

BSON (Binary JSON) is MongoDB's wire and on-disk document format. The implementation under src/mongo/bson/ is one of the oldest and most performance-critical parts of the codebase: every read, every write, every replicated oplog entry, and every command request and response is BSON.

Purpose

BSON is a length-prefixed, ordered collection of typed fields. Each field has a single-byte type tag, a NUL-terminated string name, and a value whose length is determined by the type tag. The format prioritizes:

  • Streaming reads — the parser advances field-by-field without backtracking.
  • In-place type information — field types are encoded inline, avoiding schema lookups.
  • Compact representation of dates, decimal128, ObjectIds, and binary blobs.

The full type list (string, int32, int64, double, decimal128, ObjectId, bool, date, regex, code, ...) is enumerated in src/mongo/bson/bsontypes.h.

Directory layout

src/mongo/bson/
├── bsonelement.h / .cpp        # The element view: type, name, value pointer.
├── bsonobj.h / .cpp            # The document view: a length-prefixed byte range.
├── bsonobjbuilder.h / .cpp     # Builders: produce a new BSONObj field-by-field.
├── bson_validate.h / .cpp      # Strict and lax validators.
├── bson_mutator/               # In-place mutation via BSONObj patches.
├── column/                     # The bsoncolumn columnar format.
├── dotted_path/                # "a.b.c" path navigation.
├── bsontypes.h                 # Type tag enum.
├── ordering.h                  # Comparison rules.
├── timestamp.h                 # The Timestamp(ts, inc) type used by replication.
└── util/                       # Builders for arrays, scoped sub-documents, etc.

Key abstractions

Type Role
BSONElement A non-owning view of one field within a BSONObj. Carries type, name, and a pointer to the value bytes.
BSONObj A non-owning, refcounted view of a complete BSON document. Cheap to copy; iteration is forward-only.
BSONObjBuilder The builder used to produce a new BSONObj. Append fields by name and primitive value.
BSONArrayBuilder Builder for arrays.
BSONColumn The columnar format for time-series buckets. See src/mongo/bson/column/.
Timestamp The replication-internal (secs, inc) type. Distinct from Date_t.
OID The 12-byte ObjectId. Generated from the wall clock + process ID + counter.
Ordering Encodes per-field sort direction for compound indexes.

Building documents

#include "mongo/bson/bsonobjbuilder.h"

BSONObjBuilder b;
b.append("name", "alice");
b.append("count", 42);
auto doc = b.obj();   // BSONObj backed by an internal buffer.

For nested documents, scoped builders own the lifetime:

BSONObjBuilder b;
{
    BSONObjBuilder sub(b.subobjStart("nested"));
    sub.append("field", 1);
}   // sub goes out of scope -> finishes the sub-document
auto doc = b.obj();

For variadic construction, the BSON() macro in src/mongo/bson/bsonobj.h accepts a stream-like syntax:

auto doc = BSON("name" << "alice" << "count" << 42);

Reading documents

BSONObj doc = ...;
for (BSONElement e : doc) {
    if (e.fieldNameStringData() == "name"_sd) {
        StringData name = e.valueStringData();
    }
}

Iteration is forward-only and zero-copy: BSONElement is a view onto doc's underlying buffer, so the caller must keep doc alive.

Validation

src/mongo/bson/bson_validate.h provides two validators:

  • Lax validation — checks only that the byte stream is structurally well-formed.
  • Strict validation — additionally checks UTF-8 strings, dotted field names, dotted-path tag invariants, etc.

The wire-protocol receive path validates every incoming document; the storage engine validates every page on read in debug builds.

BSONColumn (columnar BSON)

src/mongo/bson/column/ implements bsoncolumn, the columnar format used to compactly encode time-series buckets. It's a difference-encoded, run-length-compressed format that fits a column of timestamped measurements into far fewer bytes than concatenating individual BSON documents. See Time-series collections for usage.

Performance notes

  • BSONObj's shared buffer is owned by a SharedBuffer. Copies are refcount bumps, not full copies.
  • Field lookup is O(N) in the number of fields. Code that needs O(1) lookup builds an index (bson_field_path_test.cpp, BSONObj::getFields()) once and reuses it.
  • Sorting and comparison go through Ordering and the BSONElement::woCompare() method, which respects per-type rules (e.g. null < numbers < strings).

Integration points

BSON is consumed by every other system:

  • Transport writes/reads the wire-protocol's BSON payloads.
  • IDL generates BSON parsers and serializers from YAML schemas.
  • Storage stores BSON in WiredTiger record stores (after key compression) and in indexes (encoded as KeyString).
  • Aggregation and Query operate on BSONElement views; many pipeline stages emit BSON directly.

Entry points for modification

A new BSON type tag would touch src/mongo/bson/bsontypes.h, the validator, the comparator, the wire protocol, and the server's IDL handling — historically a months-long effort. Most work in BSON-land is more local: a new helper on BSONObjBuilder, a new method on BSONElement, or a tweak to the validator. The unit tests in src/mongo/bson/*_test.cpp are exhaustive and a good source of usage examples.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

BSON – MongoDB wiki | Factory