MongoDB's native time-series collections (Post 17 Ch 9) cover small-to-medium telemetry workloads beautifully — IoT fleets in the thousands of devices, observability for a single product, financial ticks for a few symbols. Past that, dedicated columnar / time-series engines pull ahead by an order of magnitude on price-performance. This post is the comparative guide: how Mongo time-series collections actually work internally, where their limits are, and how they compare to ClickHouse, TimescaleDB, InfluxDB, QuestDB, Druid. The goal — give you the decision matrix so you know when to stay on Mongo and when to add (or move to) something else.

Series map: 26 OpenTelemetry → 27 Geo → 28 Time-series extreme (this post) → 29 K8s + mongosync + cost.


Learning Outcome

  • Explain how MongoDB time-series collections store + query data.
  • Recognise the workload ceiling — when Mongo time-series stops scaling.
  • Compare with ClickHouse, TimescaleDB, InfluxDB, QuestDB, Druid on the dimensions that matter.
  • Pick a stack — pure Mongo / Mongo + hot analytics engine / replace Mongo for this workload.
  • Design hybrid architectures (Mongo OLTP + external OLAP).

Chapter 1 — How Mongo time-series collections work

You create a TS collection with a timeField, optional metaField, and granularity:

1
2
3
4
db.createCollection("metrics", {
timeseries: { timeField: "ts", metaField: "host", granularity: "seconds" }
})

Under the hood:

  • Documents you insert are invisibly bucketed by metaField + time window. The visible API is one-doc-per-event, but on disk it's many events per bucket document.
  • Buckets use columnar compression — much smaller than 1-doc-per-event.
  • Queries by time range + metaField are fast because they touch only matching buckets.

Time-series events grouped by host and time window into compressed bucket documents, and a query that reads only one bucket

Trade-offs vs hand-rolled bucket pattern (Post 07 Ch 5):

  • No manual schema to maintain.
  • Better compression than naive.
  • TTL works out of the box.

Limits to be aware of:

  • No update / delete of individual events (you can re-create the doc or delete the bucket; old events were immutable).
  • Indexing limited (mostly timeField + metaField; partial multi-key support).
  • Aggregations work but cardinality-heavy $group is still RAM-bound.

For most telemetry use cases this is fine. Workloads where Mongo TS starts to crack: 100k+ writes/sec sustained on a single node, deep aggregations over years of data, sub-100 ms query latency on billions of rows.


Chapter 2 — Where Mongo TS shines

Workload Why Mongo TS fits
Mid-volume IoT (thousands of devices, 1-10 Hz each) one collection; no extra infra
Observability for one product metrics + tags fit Mongo doc model; index by host + time
Financial ticks for handful of symbols bucket per symbol + minute
Audit / event log with TTL TS + expireAfterSeconds purges automatically
Workloads that mix transactional + analytics one DB; no ETL

If you're already on Mongo + the workload is in this band, don't add a new DB. The operational simplicity wins.


Chapter 3 — Where Mongo TS struggles

  • Very high write throughput — single primary saturates around 50-100k writes/sec on a strong shard. Beyond that, sharding helps but costs grow.
  • Very deep aggregations — averaging across billions of rows with cardinality-heavy $group is slower than columnar engines built for it.
  • Sub-50ms p99 on huge ranges — columnar formats with vectorised execution win.
  • Compression at extreme scale — ClickHouse / Parquet typically achieves 5-20× the compression ratio of Mongo TS for time-series-shape data.
  • Cost per TB of cold data — Atlas hot storage isn't cheap; archive helps but specialist engines compress more aggressively.

When the workload hits any of these, look at alternatives below.


Chapter 4 — Alternatives — quick reference

System Storage model Strengths Weaknesses
MongoDB TS document buckets w/ columnar compression flexible schema, mixed workload, one DB scale ceiling, slower deep analytics
ClickHouse columnar, MergeTree variants extreme analytics speed; great compression; SQL append-mostly; weaker on point updates; ops complexity
TimescaleDB Postgres extension; chunked time-partitioned tables full SQL + Postgres tooling; PostGIS friends not columnar core; scaling beyond 1 node harder
InfluxDB v3 Apache Arrow + Parquet purpose-built for metrics; PromQL-like Flux/SQL rewrite history; ecosystem smaller
QuestDB columnar, SIMD-vectorised very fast ingest + queries; small footprint newer ecosystem; less feature coverage
Apache Druid columnar, segment-based sub-second on huge datasets + dashboards heavy ops; complex schema
Apache Pinot columnar, segment-based sub-second; ad-tech / event use cases heavy ops
Prometheus + Mimir/Thanos TSDB metrics monitoring not for arbitrary analytical queries

For pure analytics over time-series, ClickHouse is the dominant 2026 choice for new builds. Operational complexity dropped with managed offerings (Altinity Cloud, ClickHouse Cloud).


Chapter 5 — ClickHouse — when + how

ClickHouse is a columnar OLAP database. Strengths for time-series:

  • Sub-second aggregation over billions of rows.
  • 10-50× compression vs row-store.
  • Materialized views update incrementally.
  • Native S3 + Parquet integration for cold storage.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE TABLE metrics (
ts DateTime CODEC(Delta, ZSTD),
host LowCardinality(String),
metric LowCardinality(String),
value Float64
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(ts)
ORDER BY (host, metric, ts);

SELECT host, avg(value)
FROM metrics
WHERE metric = 'cpu' AND ts >= now() - INTERVAL 1 HOUR
GROUP BY host
ORDER BY 2 DESC LIMIT 20;

Inserts: millions of rows / second per node.
Queries: tens of milliseconds over millions of rows.

Trade-offs:

  • Append-mostly; updates + deletes are expensive (mutations queue).
  • Schema is rigid (vs Mongo's flexibility).
  • Operational complexity higher than managed Mongo.

Use ClickHouse when: pure analytical queries dominate; workload exceeds Mongo TS ceiling; you can devote eng time to running it or pay for managed.


Chapter 6 — Hybrid — Mongo for OLTP, ClickHouse for OLAP

The common 2026 pattern for serious scale:

1
2
3
4
5
6
7
8
Application
│ writes (transactional)
▼
MongoDB (OLTP: orders, users, sessions, recent telemetry)
│ change stream / outbox / Kafka
▼
ClickHouse (OLAP: years of history, dashboards, BI)

Mongo handles user-facing reads + writes with rich queries on recent data. Events flow to ClickHouse via Kafka (Post 24) or a periodic batch ($merge + S3 → ClickHouse). Dashboards / BI hit ClickHouse for big analytics.

Each tool does what it's best at; you pay the cost of running two systems but neither is asked to do the other's job poorly.


Chapter 7 — When TimescaleDB fits better

If your team is already deep on Postgres + your analytical queries are still SQL-shape (joins, complex predicates, transactions over recent slices), TimescaleDB keeps you on one engine.

1
2
3
4
5
6
7
CREATE TABLE metrics (
ts TIMESTAMPTZ NOT NULL,
host TEXT,
value DOUBLE PRECISION
);
SELECT create_hypertable('metrics', 'ts');

Strengths:

  • Full Postgres feature set + PostGIS + extensions.
  • Multi-tier storage (recent on SSD, old compressed to columnar).
  • Familiar to SQL teams.

Weaknesses:

  • Not as fast as pure columnar for huge analytics.
  • Scaling horizontally still harder than Atlas + Mongo or ClickHouse.

Pick when: SQL-first team, mixed transactional + analytical SQL workload, < ~1 TB per dataset.


Chapter 8 — InfluxDB v3 — metrics-focused

InfluxDB v3 (formerly IOx) is rebuilt on Apache Arrow + Parquet. Strengths for metrics:

  • Native to monitoring workflows (Prometheus-compat ingest, Grafana plugin).
  • Fast on time-series math (rates, moving averages, derivatives).
  • Self-managed or cloud.

Weaknesses:

  • Less general-purpose than ClickHouse.
  • Schema evolution gotchas inherited from earlier versions.

Pick when: pure monitoring workload + you want a metrics-first DB rather than a general analytical engine.


Chapter 9 — QuestDB — fast + small

QuestDB is a young, fast columnar TS database. Strengths:

  • Tiny footprint; runs on a laptop and on a server.
  • Very fast ingest + SQL queries.
  • Compatible with Postgres wire protocol.

Weaknesses:

  • Smaller community + ecosystem than ClickHouse.
  • Fewer enterprise features.

Pick when: greenfield project, dev-friendliness > ecosystem.


Chapter 10 — Druid / Pinot — sub-second dashboards over huge data

For ad-tech, real-time analytics, leaderboard-style dashboards over billions of rows with millisecond response:

  • Apache Druid — operational complexity high; sub-second analytical queries shine.
  • Apache Pinot — similar story; LinkedIn / Uber heritage.

Not the first choice for general workloads; reserve for when you genuinely need that latency at that scale.


Chapter 11 — Decision matrix

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Mongo TS already in use + workload < 50k writes/sec sustained?
→ stay on Mongo TS.

Mongo TS but slow analytics over years of data?
→ keep Mongo for OLTP, add ClickHouse for OLAP (Chapter 6 hybrid).

Greenfield project, SQL team, mixed workload, < 1 TB / dataset?
→ TimescaleDB.

Greenfield project, NoSQL friendly, time-series only, very high throughput?
→ ClickHouse or QuestDB.

Pure metrics monitoring?
→ InfluxDB v3 or Prometheus + Mimir/Thanos.

Sub-second dashboards over billions of rows?
→ Druid or Pinot.

Already on Postgres + small scale?
→ TimescaleDB.

The right answer is rarely "one engine for everything" past a certain scale.


Chapter 12 — Migration paths

Mongo TS → ClickHouse

  1. Continue ingesting into Mongo.
  2. Stream from Mongo to ClickHouse via Kafka (Post 24) or $merge to S3 → ClickHouse S3-table.
  3. Switch dashboards + BI to ClickHouse.
  4. Optionally cut writes to Mongo if it no longer serves a transactional purpose.

Atlas Online Archive as a half-step

For "old data costs too much in Mongo", Atlas Online Archive (Post 16) moves cold data to cheap S3-like storage, still queryable via federation. Cheaper than ClickHouse for archive-then-occasionally-query patterns. Faster path than a full migration.


Chapter 13 — Common pitfalls

Pitfall Cause Fix
Started with Mongo TS, blew the ceiling optimistic capacity planning hybrid with ClickHouse for analytics
Adopted ClickHouse for OLTP wrong tool use it only for OLAP; keep Mongo for OLTP
Schema rigid in ClickHouse, painful to add columns underestimated evolution cost always design ALTER-friendly schemas
Big bills running both Mongo + ClickHouse parallel storage of same data smarter retention (raw in CH, summaries in Mongo)
TS collection updates rejected by design — TS is append-only re-architect to event-shape
Cross-engine joins required one shouldn't be the source of truth for the other sync via Kafka; or materialise into one
New DB before proving the need premature optimisation scale-test Mongo TS first

Practice Exercises

Exercise 1 — Benchmark Mongo TS

Insert 10M rows into a Mongo TS collection (single device). Time random-time-range aggregations.

Exercise 2 — ClickHouse PoC

Stand up ClickHouse local. Insert the same 10M rows. Run the same aggregations. Compare.

Exercise 3 — Hybrid sync

Build the Mongo→Kafka→ClickHouse path for one collection. Verify rows land in both.

Exercise 4 — Compression compare

Disk size: Mongo TS 10M rows vs ClickHouse 10M rows vs raw JSONL. Note the ratios.

Exercise 5 — Atlas Online Archive

For an existing TS collection, set up Online Archive moving data older than 90 days. Query via federation; confirm transparency.

Exercise 6 — Decision exercise

Pick a real or imagined product. Walk Chapter 11's matrix. Justify the stack you'd pick.


Cheat-sheet

What How
Mongo TS one DB; mixed workload; up to mid-volume
Mongo TS ceiling ~50-100k writes/s per primary; sharding helps
ClickHouse extreme analytics; OLAP only
TimescaleDB Postgres-native; SQL team friendly
InfluxDB v3 metrics-focused; Arrow/Parquet
QuestDB fast, small, greenfield
Druid / Pinot sub-second over billions; ops-heavy
Hybrid Mongo OLTP + ClickHouse OLAP via Kafka
Atlas Online Archive cheap cold storage; still queryable
Never use ClickHouse as OLTP
Always benchmark before adopting a second engine
Migration path dual-write or stream into the new engine first

What's next

Post 29 — the final post in the advanced series — covers Kubernetes (MongoDB Controllers + Operator), mongosync for cluster-to-cluster sync + multi-region active-active, cost optimisation on Atlas, and compliance patterns (HIPAA, PCI-DSS, GDPR, SOC 2).


References

Note: this post is in progress. Planned additions: live benchmark on representative dataset; cost-comparison tables across cloud regions; dedicated migration scripts.