Ch. 12 · MongoDB

MongoDB Time-Series Collections

Store metrics and events in time-series collections, set the meta field and granularity, and query with time bounds.

~2 min readadvancedupdated Oct 5, 2026

A time-series collection organizes data by measurement time and metadata, storing related points in compressed buckets. It reduces storage and speeds up range queries compared with a normal collection, provided the schema and queries match how time-series data is used.

Before you start

You should be comfortable with collections and indexes. This article uses the MongoDB shell.

Step-by-step walkthrough

Step 1: Choose the time field and meta field

timeField is the timestamp, and metaField identifies the source, such as a sensor id. Points with the same meta value are bucketed together, so the meta field should have moderate cardinality. A high-cardinality meta field creates many tiny buckets and loses the benefit.

Step 2: Set granularity and expiration

granularity tells the engine how close together points arrive, so it can size buckets well: seconds, minutes or hours. expireAfterSeconds sets a TTL so old points disappear automatically, which bounds storage without a cleanup job.

Step 3: Query with time bounds

Filter on the time field so the engine can prune buckets, and aggregate per bucket for rollups. A query without a time bound scans every bucket and loses the advantage, so always include a range.

Worked scenario

The collection buckets sensor readings and expires after a day.

db.createCollection('sensor', {
  timeseries: { timeField: 'ts', metaField: 'sensor', granularity: 'minutes' },
  expireAfterSeconds: 86400,
});
db.sensor.insertOne({ ts: new Date(), sensor: 'a', value: 21 });
JavaScript

Walk through the example

Readings from sensor a share a meta value and land in the same buckets, which compress well. The TTL removes points after one day, so storage is bounded. A query such as { sensor: 'a', ts: { $gte: since } } prunes to recent buckets and stays fast.

Common mistake

Using a high-cardinality meta field such as a unique request id, which produces one point per bucket and no compression. Another is querying without a time range, which scans everything and erases the benefit.

Verify the behavior

Insert many points across a few meta values and compare storage with a normal collection. Query with and without a time bound and compare explain stats. Confirm old points expire after the configured TTL.

Interview exercise

What makes a good meta field for a time-series collection?

Answer and reasoning

A field with moderate cardinality that groups measurements of the same series, such as a sensor id, device id or metric name. Points with the same meta value are bucketed and compressed together, so a small number of large buckets is ideal. A unique-per-point field fragments the data into tiny buckets and defeats the optimization.

Continue learning

Compare retention in TTL expiration and sharding in Shard key design. Read the MongoDB time-series documentation and try the MongoDB interview questions.

More in MongoDB

read ✓MongoDB · mid

MongoDB Bulk Writes

Batch inserts and updates with bulkWrite, choose ordered or unordered, and handle partial failures correctly.

~2 min readread →
read ✓MongoDB · mid

MongoDB Capped Collections

Use capped collections for fixed-size, insertion-ordered logs, and know why documents cannot grow.

~2 min readread →
read ✓MongoDB · hard

MongoDB Change Streams and Resume Tokens

React to inserts and updates with change streams, persist resume tokens, and handle invalidate and failover correctly.

~2 min readread →
esc