Skip to content
Home › SQL Comparisons › MongoDB Time Series vs TimescaleDB
Comparison · Time-Series & IoT

MongoDB Time Series vs TimescaleDB

MongoDB time series collections store measurements as documents that MongoDB groups into compressed, columnar buckets by metaField and time; TimescaleDB turns a PostgreSQL table into a hypertable partitioned by time, with a columnstore, continuous aggregates and retention policies. Choose MongoDB when the application already runs on MongoDB and the telemetry is document-shaped; choose TimescaleDB when readings must be joined, constrained and rolled up in SQL next to relational data.

Last verified October 2026. Versions checked: MongoDB 9.0 (9.0.4, 13 October 2026), TimescaleDB 2.31.0. Licensing and features change; check the official sources for the latest details.

Quick verdict

Short answer

Our editorial view: choose MongoDB time series collections when your application and team already use MongoDB, when each reading arrives as a JSON document with nested metadata, and when you want sensor data in the same cluster and driver as the rest of the application. Choose TimescaleDB when telemetry must be joined to assets, spaces and work orders with SQL, when you need transactions and constraints on the same tables, or when you want incrementally maintained roll-ups (continuous aggregates) rather than pipelines you schedule yourself. Neither vendor publishes a like-for-like benchmark against the other, so test with your own point list and queries.

How we know: This comparison is research-based: data models, write and update rules, indexing, retention, downsampling, licences and pricing models were checked against the MongoDB manual (time series collections, bucketing, granularity, automatic removal, best practices and limitations pages, the $out, $dateTrunc, $densify and $lookup references, the 9.0 release notes, and the 7.0 and 8.0 limitations pages for the update rules), the MongoDB SSPL FAQ and the SSPL text, Community Edition and Atlas pricing pages, the TimescaleDB repository LICENSE file, and the Tiger Data documentation, licence (including the Timescale License agreement) and pricing pages on 27 October 2026. Licence terms are summarised and quoted from those texts; they are not interpreted as legal conclusions. The plain PostgreSQL join and the foreign key check on this page were run on PostgreSQL 18.6 (PGlite 0.5.11). The MongoDB shell commands and the TimescaleDB statements are taken from the vendors' documentation, adapted to building sensors, labelled illustrative and were not run here; in particular $lookup against a time series collection and delete-and-re-insert of a measurement were not run. Atlas prices are described qualitatively, because the Atlas plan cards checked on 27 October 2026 do not state the cloud provider or region their starting prices apply to. We have not run benchmarks and quote no performance figures.

This page is for developers and data engineers who must store building and equipment telemetry and are choosing between MongoDB, often because the application already runs on it, and TimescaleDB on PostgreSQL. Typical data: BMS points such as AHU supply-air temperature, chiller kW and zone CO2 every 1 to 60 seconds, utility meter readings, and the asset and work-order records that a CAFM or CMMS keeps. For background on how data flows from devices through brokers into storage, see the time-series and IoT data hub.

MongoDB time series collections arrived in MongoDB 5.0 and are a special collection type: you name a timeField and an optional metaField, and MongoDB groups measurements from the same source and similar time into compressed buckets with a columnar format. MongoDB 9.0 is the current stable series (9.0.4 was released on 13 October 2026). The 9.0 release notes state: "Starting in 9.0, MongoDB stores time series collections as a single namespace that contains time series data compressed into buckets. Time series collections are no longer writable non-materialized views." Earlier releases behave differently, so check the release notes for the version you run. The MongoDB time series collections guide covers schema design in more depth.

TimescaleDB is a PostgreSQL extension maintained by Tiger Data. Its hypertables are PostgreSQL tables partitioned automatically into time chunks; recent chunks are row-oriented and older ones can be converted to the hypercore columnstore. The latest release when checked was 2.31.0. See the TimescaleDB guide for setup detail.

Side by side

AspectMongoDB time series collectionsTimescaleDB
What it is A collection type inside MongoDB (Community, Enterprise Advanced or Atlas) An extension loaded into PostgreSQL; hypertables are ordinary SQL tables
Data model BSON documents with a timeField, a metaField (source identity) and measurement fields Relational rows with typed columns, keys and foreign keys
Physical layout Buckets of up to 1000 measurements or 125KB per metaField value and time span, compressed and columnar Time chunks; rowstore for recent data, hypercore columnstore for older chunks
Query language MongoDB Query API and aggregation pipeline ($dateTrunc, $densify, $setWindowFields) PostgreSQL SQL plus time_bucket and other hyperfunctions
Updates and deletes Updates may only match on and modify the metaField; no upserts UPDATE, DELETE and upserts, including on the columnstore
Transactions Writes to time series collections cannot run in transactions (reads can) Full PostgreSQL transactions
Roll-ups Aggregation pipelines you schedule, writing with $out or $merge Continuous aggregates refreshed incrementally by policy
Retention expireAfterSeconds; whole buckets removed by a background task add_retention_policy; whole chunks dropped on a schedule
Licence Community Server under SSPL (source-available, not OSI-approved) Apache 2.0 core plus Timescale License (TSL) for Community Edition features
Managed service MongoDB Atlas Tiger Cloud

Key differences

Data model: documents in buckets versus rows in chunks

In MongoDB each reading is a document. The metaField should hold what identifies a series and rarely changes, such as site, AHU and point; MongoDB buckets documents that share an identical metaField value and fall in the same time span, so a metaField that changes often produces many sparse buckets. The manual puts it plainly: your choice of metaField has the biggest impact on query performance. Both the timeField and the metaField are fixed at creation, and an existing collection cannot be converted into a time series collection, so the shape needs to be right before data arrives.

// Illustrative configuration, not run here: adapted from the MongoDB manual;
// check every option against the documentation for your version before use.
db.createCollection("ahu_readings", {
  timeseries: { timeField: "ts", metaField: "meta", granularity: "seconds" },
  expireAfterSeconds: 7776000   // 90 days
})

db.ahu_readings.insertMany([
  { ts: ISODate("2026-10-27T08:00:00Z"), meta: { site: "hq", ahuId: "ahu-02" },
    supplyAirTemp: 16.8, fanSpeedPct: 62 },
  { ts: ISODate("2026-10-27T08:00:30Z"), meta: { site: "hq", ahuId: "ahu-02" },
    supplyAirTemp: 17.0, fanSpeedPct: 63 }
], { ordered: false })

In TimescaleDB a reading is a row in a hypertable, and the asset register, the sensor-to-asset mapping and work orders are ordinary tables in the same database. Keys and foreign keys work as in any PostgreSQL schema, which is useful when commissioning data is messy: a reading for an asset that does not exist is rejected rather than stored silently. The TimescaleDB DDL is the same CREATE TABLE ... WITH (tsdb.hypertable ...) shown in TimescaleDB vs InfluxDB; the relational part below is plain PostgreSQL and was run on PostgreSQL 18.6.

-- Plain PostgreSQL (run on PostgreSQL 18.6, PGlite)
CREATE TABLE asset (
    asset_id   text PRIMARY KEY,
    site       text NOT NULL,
    asset_type text NOT NULL
);

CREATE TABLE work_order (
    wo_id     integer PRIMARY KEY,
    asset_id  text NOT NULL REFERENCES asset (asset_id),
    status    text NOT NULL,
    opened_at timestamptz NOT NULL
);

CREATE TABLE reading (
    asset_id text NOT NULL REFERENCES asset (asset_id),
    point    text NOT NULL,
    ts       timestamptz NOT NULL,
    value    double precision NOT NULL,
    PRIMARY KEY (asset_id, point, ts)
);

INSERT INTO asset VALUES ('ahu-01', 'hq', 'AHU'), ('ahu-02', 'hq', 'AHU');
INSERT INTO work_order VALUES (5012, 'ahu-02', 'open', '2026-10-27 07:40+00');
INSERT INTO reading VALUES
    ('ahu-01', 'supply_air_temp', '2026-10-27 08:00+00', 13.1),
    ('ahu-01', 'supply_air_temp', '2026-10-27 08:30+00', 13.4),
    ('ahu-02', 'supply_air_temp', '2026-10-27 08:00+00', 16.8),
    ('ahu-02', 'supply_air_temp', '2026-10-27 08:30+00', 17.6),
    ('ahu-02', 'supply_air_temp', '2026-10-27 09:00+00', 18.1);

INSERT INTO reading VALUES ('ahu-99', 'supply_air_temp', '2026-10-27 09:00+00', 14.0);
-- ERROR:  insert or update on table "reading" violates foreign key constraint "reading_asset_id_fkey"
-- DETAIL:  Key (asset_id)=(ahu-99) is not present in table "asset".

Querying: aggregation pipeline versus SQL with joins

MongoDB queries time series collections with the same Query API and aggregation pipeline as other collections. $dateTrunc buckets timestamps (for example 15-minute bins), $densify fills gaps in time series data, and $setWindowFields computes moving averages. A 15-minute summary for one AHU looks like this:

// Illustrative, not run here: aggregation operators from the MongoDB manual;
// check them against the documentation for your version before use.
db.ahu_readings.aggregate([
  { $match: { "meta.ahuId": "ahu-02", ts: { $gte: ISODate("2026-10-27T00:00:00Z") } } },
  { $group: {
      _id: { $dateTrunc: { date: "$ts", unit: "minute", binSize: 15 } },
      avgSat: { $avg: "$supplyAirTemp" },
      maxSat: { $max: "$supplyAirTemp" } } },
  { $sort: { _id: 1 } }
])

The manual advises querying the metaField on scalar sub-fields ("meta.ahuId") rather than the whole object, and using $group instead of distinct on time series collections. The $lookup reference describes a left outer join to a collection in the same database; neither it nor the time series pages we checked say anything specific about using a time series collection in a $lookup, so test such joins (and their performance) on your version before designing around them. Either way, there are no foreign keys to keep readings and asset documents consistent.

In TimescaleDB the same question, extended to "only AHUs with an open work order", is one SQL statement. The query below is plain PostgreSQL (date_trunc rather than TimescaleDB's time_bucket) and ran on PostgreSQL 18.6 against the tables above:

-- Plain PostgreSQL (run on PostgreSQL 18.6, PGlite)
SELECT r.asset_id, a.site, w.wo_id,
       date_trunc('hour', r.ts) AS hour,
       round(avg(r.value)::numeric, 1) AS avg_supply_air_c,
       max(r.value) AS max_supply_air_c
FROM reading AS r
JOIN asset AS a ON a.asset_id = r.asset_id
JOIN work_order AS w ON w.asset_id = r.asset_id AND w.status = 'open'
WHERE r.point = 'supply_air_temp'
  AND r.ts >= w.opened_at
GROUP BY r.asset_id, a.site, w.wo_id, date_trunc('hour', r.ts)
ORDER BY r.asset_id, hour;

 asset_id | site | wo_id |          hour          | avg_supply_air_c | max_supply_air_c
----------+------+-------+------------------------+------------------+------------------
 ahu-02   | hq   |  5012 | 2026-10-27 08:00:00+00 |             17.2 |             17.6
 ahu-02   | hq   |  5012 | 2026-10-27 09:00:00+00 |             18.1 |             18.1

Writes, corrections and late data

MongoDB time series collections are built for appends. The current (9.0) limitations page says of update commands: "You can only match on the metaField field value." "You can only modify the metaField field value." They must also be multi-document and "must not set upsert: true"; the 7.0 and 8.0 manuals list the same requirements. The page lists no separate restriction on deletes, but we did not verify deleting and re-inserting a single measurement. Writes cannot take part in multi-document transactions, the maximum document size is 4 MB, and change streams, schema validation rules and unique indexes are not supported. For insert performance the manual recommends batching with insertMany(), grouping documents with the same metaField in a batch, and setting ordered: false. Out-of-order timestamps that arrive close together are handled by rounding bucket start times, but a reading far outside the open bucket's span opens a new bucket.

TimescaleDB accepts ordinary INSERT, UPDATE, DELETE and upserts, and its documentation states these work directly on the columnstore. For BMS data that matters when a gateway replays a buffer after an outage or a meter reading is corrected: a primary key plus INSERT ... ON CONFLICT makes replays idempotent (see duplicate key errors for what happens without it). More on this in late-arriving and out-of-order data.

Retention and downsampling

MongoDB uses expireAfterSeconds on the collection. Deletion works on whole buckets: a bucket is removed only when all its documents have expired, by a background task that runs every 60 seconds, so data can outlive its expiry by up to the bucket span (one hour for granularity: "seconds", 24 hours for minutes, 30 days for hours). There is no built-in incremental roll-up; you write an aggregation pipeline that groups raw readings and writes the result with $out (which can create a time series collection since MongoDB 7.0.3) or $merge into a regular collection, and you schedule it yourself. Note that $merge cannot write into a time series collection.

TimescaleDB drops whole chunks with a retention policy and maintains continuous aggregates that refresh in the background as new data is added or old data is modified. For example, a BMS might keep raw readings for 90 days and hourly aggregates for years, with the aggregate surviving after its raw chunks are dropped; the 90-day figure here and in the code samples is an illustrative assumption, to be set from how long operators need raw data, reporting needs and storage cost. The retention and downsampling guide covers both patterns.

-- Illustrative configuration, not run here: adapted from the Tiger Data documentation;
-- check every setting against the documentation for your version before use.
SELECT add_retention_policy('reading', drop_after => INTERVAL '90 days');

Scaling, sharding and operations

MongoDB scales out with replica sets and sharding. For time series collections the shard key may only use the metaField, its sub-fields and the timeField; from MongoDB 8.0 shard keys containing the timeField are deprecated, and the manual recommends sharding on the metaField. Zone sharding is not supported for time series collections. Bucket granularity can be made coarser after creation but never finer.

In the self-hosted replication setup that Tiger Data documents, TimescaleDB writes to one PostgreSQL primary and can serve reads from replicas; the pages we checked do not describe sharding writes for one hypertable across several primaries. You operate PostgreSQL as well as the extension (vacuum, upgrades, connection pooling). Chunk interval and columnstore settings are the main tuning levers; see choosing partition intervals. For both systems, size storage from points per second times retention and measure compression on a sample, as described in how to store IoT sensor data.

Security follows each platform: MongoDB roles and TLS (client-side field level encryption is not supported on time series collections), and PostgreSQL roles, row-level security and TLS for TimescaleDB. In both cases the database is the storage and query layer; devices usually publish to an MQTT broker or Kafka first, and long-range cross-site analytics often move to a warehouse or lakehouse.

Licensing

MongoDB. MongoDB Community Server releases since 16 October 2018 are under the Server Side Public License (SSPL). MongoDB describes Community Edition as "the free, source-available version of MongoDB", and its SSPL FAQ states: "The SSPL has not been approved by the OSI." Section 13 of the SSPL text, headed "Offering the Program as a Service", says: "If you make the functionality of the Program or a modified version available to third parties as a service, you must make the Service Source Code available via network download to everyone at no charge, under the terms of this License." The same section defines what counts as a service and as Service Source Code. MongoDB Enterprise Advanced is a commercial subscription.

TimescaleDB. The repository's LICENSE file states that outside the tsl directory "source code in a given file is licensed under the Apache License Version 2.0, unless otherwise noted", and that within it "source code in a given file is licensed under the Timescale License, unless otherwise noted". Tiger Data's edition comparison places the columnstore, continuous aggregates and retention policies in Community Edition, which is under the Timescale License (TSL). Tiger Data's licence page summarises the TSL as: "Roughly speaking, as long as you are not offering TimescaleDB as a hosted Database-as-a-Service, you can use all Community features for free." The TSL agreement is reproduced on that page (effective date 17 June 2025) and in the repository (posted 24 September 2020); the clauses quoted here appear in both, and the agreement is more detailed than the summary. Its Internal Use grant covers use "solely for Your own internal business purposes in a manner that does not expose or give access to, directly or indirectly (e.g., via a wrapper), the Timescale Data Definition Interfaces or the Timescale Data Manipulation Interfaces to any person or entity other than You or Your employees and Contractors working on Your behalf"; a separate grant covers Value Added Products or Services, with its own conditions; and section 2.2 prohibits, among other things, "using any TSL Licensed Software to provide time-sharing services or database-as-a-service services".

Which terms apply to a particular CAFM, CMMS or BMS platform (for example one where tenants, contractors or customers reach the data through your application) depends on how it is built and offered and on the full licence texts, and we do not interpret that here. Not legal advice: this section summarises and quotes the licence texts as published on 27 October 2026; read the licences for the versions you use and take legal advice for your situation.

Pricing and licensing

MongoDB describes Community Edition as "the free, source-available version of MongoDB"; the licence conditions are summarised in the licensing section above. MongoDB Atlas clusters are billed hourly with monthly invoices. On 27 October 2026 the Atlas pricing page offered a Free tier, a Flex tier and Dedicated clusters, with a starting price on each paid plan card, but the plan cards did not state which cloud provider or region those prices apply to, so we do not quote them; price your own provider, region and cluster tier in the Atlas pricing calculator or console. Actual cost depends on provider, region, cluster tier, storage, backup and data transfer. Enterprise Advanced is priced through sales.

TimescaleDB: Tiger Data's edition page states that "TimescaleDB Community Edition is completely free if you manage your own service", subject to the TSL terms summarised above. Tiger Cloud charges based on consumption, billing compute hourly and storage by GB used, with add-ons such as HA replicas and tiered storage; see TimescaleDB vs InfluxDB for the storage prices checked the same day.

The two are not priced on the same unit in practice: Atlas cluster tiers bundle compute and storage ranges, while Tiger Cloud separates compute from storage. Estimate both from your series count, sample rate, retention and expected compression.

Pricing checked on the vendors' official pages on 27 October 2026. Prices change; confirm before buying.

Where each one leads

MongoDB time series collections strengths

  • One database and driver for application documents and telemetry when the stack is already MongoDB
  • Flexible, nested document schema; new measurement fields need no migration
  • Automatic bucketing with columnar compression and an automatic metaField plus timeField index
  • Horizontal scaling with sharding on the metaField, and a managed service in Atlas
  • Aggregation pipeline with <code>$dateTrunc</code>, <code>$densify</code> and window functions for time-based analysis

TimescaleDB strengths

  • Full SQL with joins, constraints and foreign keys to assets, spaces and work orders
  • Continuous aggregates maintain roll-ups incrementally instead of scheduled pipelines
  • Updates, deletes and upserts on time-series rows, including in the columnstore
  • Transactions across telemetry and business tables
  • Works with the PostgreSQL ecosystem of drivers, BI tools and backup tools

Limitations

MongoDB time series collections limitations

  • Writes to time series collections cannot run in transactions
  • Updates may only match on and change the metaField; no upserts
  • No unique indexes, change streams or schema validation rules on time series collections
  • timeField, metaField and collection type are fixed at creation; granularity can only grow
  • Expired data is removed per bucket, so deletion can lag the TTL by up to the bucket span
  • No built-in incremental roll-ups; downsampling is a pipeline you schedule

TimescaleDB limitations

  • Columnstore, continuous aggregates and retention policies need the TSL-licensed Community Edition
  • The documented self-hosted replication writes to one PostgreSQL primary; the pages we checked do not describe sharding writes across nodes
  • You operate PostgreSQL as well as the extension
  • A rigid relational schema means migrations when new point types arrive

When to choose each

Choose MongoDB time series collections if

  • The application, team and operations are already built on MongoDB or Atlas
  • Readings arrive as varied JSON documents and the schema changes often
  • Telemetry is mostly appended and read back per device, with few corrections
  • You expect to scale writes horizontally with sharding

Choose TimescaleDB if

  • Readings must be joined to assets, spaces and work orders in SQL
  • Late or wrong readings need updates, upserts or transactional fixes
  • You want roll-ups maintained automatically for dashboards and energy reports
  • Your team knows PostgreSQL and its tooling

When neither is right

Final recommendation

Bottom line

Our editorial view (a judgement, not a vendor statement): MongoDB time series collections are a sound choice when MongoDB is already the application database and telemetry is append-mostly and document-shaped: you avoid a second database and get compressed, bucketed storage and sharding. Their limits (no transactional writes, metaField-only updates, no unique indexes, scheduled rather than incremental roll-ups) matter most for maintenance and energy systems that correct data and join it to business records. TimescaleDB fits those systems better, provided operating PostgreSQL suits your team and the TSL terms that cover its key features fit how you will deploy it (see the licensing section). For a new CAFM, CMMS or BMS platform with relational reference data, TimescaleDB is usually the more natural fit; for an existing MongoDB application adding device data, time series collections are the lower-friction option.

Frequently asked questions

Is MongoDB good for time series data?

It can be. Time series collections (since MongoDB 5.0) group measurements into compressed, columnar buckets by source and time and create an index on the metaField and timeField automatically. They suit append-mostly device data in a MongoDB application. They are less suited when you need transactional writes, frequent corrections or SQL joins with relational data.

Can I update readings in a MongoDB time series collection?

Only partly. Update commands may only match on and modify the metaField, must update all matching documents, and cannot upsert. Measurement fields cannot be updated in place (the 9.0 manual: "You can only modify the metaField field value."), so corrections need another design. One option, which is our design suggestion rather than a MongoDB recommendation, is to write corrected values to a separate collection that reports read in preference to the raw data; deleting and re-inserting the measurement is another, which you should test on your version.

Does MongoDB have continuous aggregates like TimescaleDB?

No built-in equivalent. You build roll-ups with an aggregation pipeline that writes results with $out or $merge, and run it on a schedule. TimescaleDB continuous aggregates are refreshed incrementally by a policy.

Is TimescaleDB faster than MongoDB for time series?

There is no neutral, like-for-like benchmark that settles it, and results depend on data shape, metaField or key design, batch size and query mix. Test both with your own point list, write rate and dashboard queries.

Is MongoDB open source?

MongoDB Community Server is source-available under the Server Side Public License (SSPL), which MongoDB states has not been approved by the OSI, and MongoDB describes Community Edition as free and source-available. Section 13 of the SSPL sets conditions for making the program available to third parties as a service; read the licence text and take legal advice for your situation, as this answer is not legal advice.

Sources

Checked October 2026.

How we research comparisons: our editorial method.

More comparisons

Browse all SQL comparisons or the tools directory.