Open-Source Wikis

/

MongoDB

/

Features

/

Time-series collections

mongodb/mongo

Time-series collections

A time-series collection is a collection optimized for telemetry-style workloads: many small documents tagged with a timestamp and a small set of dimensions. Internally each time-series collection is two things: a user-facing view and an underlying bucket collection that packs many measurements into a single bucket document. The implementation lives at src/mongo/db/timeseries/, with query rewrites in src/mongo/db/exec/timeseries/ and src/mongo/db/query/timeseries/.

Purpose

Time-series collections provide:

  • Storage savings — bucket compression dramatically reduces on-disk size for telemetry workloads (often >10x).
  • Faster scans — a single bucket holds many measurements, so a full scan touches far fewer documents.
  • Native operators$_internalUnpackBucket, $densify, $fill, $setWindowFields integrate cleanly with the columnar bucket format.
  • Familiar API — users insert ordinary documents; the server transparently routes them into buckets.

Bucketing

When a measurement arrives, the server picks (or creates) a bucket based on:

graph TD
    Insert[insert measurement] --> Catalog[BucketCatalog]
    Catalog -->|find or open| Bucket[Bucket document]
    Bucket -->|append measurement| Storage[bucket collection<br/>system.buckets.foo]

A bucket is a document in system.buckets.<coll> with three fields:

  • control — min/max metadata, version, count.
  • meta — the per-bucket metadata value (the dimensional tag the user specified).
  • data — a bsoncolumn column store of measurements, one column per field name.

bsoncolumn

The data field uses the bsoncolumn format defined in src/mongo/bson/column/. It's a difference-encoded, run-length-compressed binary format that fits a column of timestamped floats or strings into a fraction of the bytes a sequence of standalone BSON documents would take. The codec is documented in src/mongo/bson/column/.

Reading: the unpack stage

Queries against a time-series collection see the user-facing view, but the actual scan reads buckets. The pipeline rewriter inserts an $_internalUnpackBucket stage that:

  1. Reads bucket documents from system.buckets.<coll>.
  2. Decodes the columnar data.
  3. Emits one synthetic measurement document per measurement.
graph LR
    BucketColl[system.buckets.foo] --> Scan[FETCH/IXSCAN]
    Scan --> Unpack[$_internalUnpackBucket]
    Unpack --> Match[$match / user pipeline]

The unpack stage is predicate-aware — many $match filters can be evaluated against the bucket-level control.min/control.max and skip the bucket entirely without decoding it. This makes time-range queries dramatically faster than scanning every measurement.

Compression and reopen

When a bucket fills (size or count threshold), it is closed and a new bucket opens for that meta value. Closed buckets are compressed: the columnar format described above plus an additional encoding pass. The server can also reopen a closed bucket if late-arriving data needs to be inserted into it.

Sharding

Time-series collections can be sharded. The shard key may include a time field (commonly bucketed by hour or day) and the meta field. The router targets shards based on bucket boundaries; the data side translates each measurement into the bucket it belongs in. See Sharding and src/mongo/s/commands/cluster_* for the router-side support.

Updates and deletes

Time-series collections support update and delete with a feature-flagged code path that:

  • Identifies the buckets touched.
  • Either modifies measurements within the bucket in place (when the bucket is open) or rewrites the bucket (when it's closed).
  • Replicates an applyOps containing the bucket-level update.

Key source files

File Purpose
src/mongo/db/timeseries/bucket_catalog/ The in-memory cache of open buckets.
src/mongo/db/timeseries/bucket_compression.cpp Bucket compression and reopen logic.
src/mongo/db/timeseries/timeseries_options.cpp Per-collection options (timeField, metaField, granularity).
src/mongo/db/timeseries/write_ops/ Inserts, updates, deletes on time-series collections.
src/mongo/db/exec/timeseries/ Bucket-aware execution stages.
src/mongo/db/query/timeseries/ Query-planner support for unpacking buckets.
src/mongo/db/pipeline/document_source_internal_unpack_bucket.cpp The $_internalUnpackBucket stage.
src/mongo/bson/column/ The bsoncolumn columnar format.

Integration points

  • The storage engine stores the bucket collection like any other collection — buckets are just BSON documents.
  • Aggregation pipeline rewrites pipelines to insert the unpack stage and push predicates down to bucket-level metadata.
  • Query engine indexes can be built on the bucket fields (timestamp, meta, computed columns).
  • Sharding supports sharded time-series collections.
  • Change streams translate bucket-level oplog entries back into measurement-level events.

Entry points for modification

Most time-series work touches the bucket catalog or the unpack stage. New columnar codecs go in src/mongo/bson/column/. New time-series-aware optimizations are usually pipeline rewrites under src/mongo/db/pipeline/. The core and aggregation resmoke suites have time-series subdirectories that pin behavior; the FSM workloads under jstests/concurrency/ exercise the bucket catalog under contention.

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

Time-series collections – MongoDB wiki | Factory