Time-Series Database Comparison 2026: Architecture, Performance & Decision Guide
Quick recommendations
There is no single "best" time-series database. The right choice depends on your data model, query patterns, operational maturity, and budget. This article covers five leading engines — architecture, code, cost, and decision criteria — so you can make an informed call.
| Primary need | Recommended engine | Why |
|---|---|---|
| Full SQL with relational JOINs | TimescaleDB | PostgreSQL extension — all SQL capabilities natively available |
| Object-storage-first plus ad-hoc analytics | InfluxDB 3 (IOx) / VictoriaMetrics | Columnar engine + Arrow Flight — fast large-dataset scans |
| Millions of IoT devices at high frequency | TDengine | Super-table + per-device partitioning — maximum write efficiency |
| Kubernetes monitoring & cloud-native metrics | Prometheus + remote-write | Mature ecosystem, Operator auto-collection |
| High-cardinality labels, cost-sensitive | VictoriaMetrics | Single binary, industry-leading memory/disk efficiency |
If you're aiming for production, don't judge by slide-deck numbers alone. Evaluate: stability under high cardinality, operational complexity of scaling out, and whether the community or vendor provides enough support.
Why you need a purpose-built time-series database
General-purpose relational databases hit a wall on time-series workloads for four reasons:
1. Write amplification
Time-series data is append-heavy, concurrent, and immutable — sensor/metric entries are never updated, only appended. MySQL/PostgreSQL's B-Tree indexes must rebalance tree nodes, write to WAL + data files + index pages for every INSERT. At hundreds of thousands of points per second, IOPS is saturated. TSDB engines use LSM-Tree, TSM (Time-Structured Merge Tree), or columnar append — converting random I/O into sequential writes.
2. Time-based partitioning is non-negotiable
Analytical queries almost always target "the last N hours / N days". Without time partitioning, every query forces a full table scan. TSDB storage engines natively organize data by time chunks/segments/shards, allowing queries to skip irrelevant time ranges entirely.
3. Automatic downsampling and retention
You don't need to keep per-millisecond precision forever. TSDBs ship Continuous Queries (CQ) or Retention Policies (RP) that automatically downsample raw data into minute/hour aggregates and delete the originals — cutting storage costs dramatically without any cron job.
4. Purpose-built compression
Timestamps are monotonically increasing — delta-of-delta encoding exploits this. Adjacent sensor values are highly similar — XOR/Gorilla compression exploits this. A general-purpose DB cannot match the compression ratios that TSDBs achieve; terabyte-level differences are common for equivalent datasets.
Deep profiles of the five contenders
InfluxDB 3 (IOx)
InfluxData retired the self-developed TSM engine in 2023 and pivoted to IOx, built on Apache DataFusion. IOx uses columnar storage (Apache Parquet) that writes directly to S3/MinIO-compatible object storage.
Architecture:
- Ingester: buffers writes in memory (WAL), flushes as Parquet files by partition.
- Querier: uses DataFusion for vectorized queries (SIMD + columnar scanning), supports SQL and InfluxQL.
- Compactor: merges small Parquet files in the background, updates the catalog.
Strengths:
- Compute/storage separation — ingest and query nodes scale independently.
- Data lands natively on object storage at ~$0.023/GB/month (S3 Standard).
- Arrow Flight SQL delivers sub-millisecond batch query results.
Weaknesses:
- Significant ecosystem shift from v2; migration is not entirely smooth.
- Free tier features are trimmed — cluster management is commercial.
Best for: teams needing an "ingest → object store → ad-hoc analytics" pipeline with strong SQL analysis requirements.
TimescaleDB
TimescaleDB is a PostgreSQL extension. Its core abstraction, the hypertable, automatically partitions data by time (or custom dimensions). Each partition is a standard PostgreSQL table (chunk) supporting every index type (B-Tree, GIN, GiST, BRIN).
Architecture:
- Incoming writes are routed to the active chunk; old chunks are automatically compressed.
- Compression: converts row data within a chunk into columnar arrays, applying Gorilla and delta-delta algorithms — 10–20× compression ratio is typical.
- Continuous Aggregate: materialized views that auto-refresh on a time window, so queries hit pre-aggregated results directly.
Strengths:
- The entire PostgreSQL SQL surface: CTEs, window functions, LATERAL JOIN, JSONB/GIS — all available.
- Native compatibility with BI tools (Metabase, Grafana, Tableau, Superset) via standard PostgreSQL wire protocol.
- Community edition (Apache-2) is feature-rich: compression and continuous aggregates are free.
Weaknesses:
- Write path depends on PostgreSQL's WAL mechanism; single-node write throughput lags pure columnar engines.
- Horizontal scaling requires multi-node, which is a commercial feature in TimescaleDB.
Best for: teams already operating PostgreSQL, needing hybrid "relational + time-series" queries, and not wanting to learn a new query language.
VictoriaMetrics
Built by ex-ClickHouse engineers, VictoriaMetrics' design philosophy is simple, performant, low-cost. It is a single binary — download, start, and serve:
Architecture:
- Writes: buffered in-memory first, flushed per-second to an LSM (Log-Structured Merge) structure on disk.
- Storage: a MergeTree variant similar to ClickHouse, partitioned by date, with rows sorted by metric name + labels within each partition.
- Queries: MetricsQL (a PromQL superset) supports rollup, transform, join; also provides a Graphite API compatibility layer.
Strengths:
- Exceptional single-node efficiency: official benchmarks show 7× write throughput over InfluxDB, 20× compression over Prometheus at equal resources.
- Extremely low memory footprint — even millions of active series rarely exceed a few GB of RAM.
- vmagent can replace Prometheus as a scraper at 1/10th the memory footprint.
Weaknesses:
- SQL is not a first-class citizen (experimental SQL support exists but is incomplete).
- Cluster mode (vmcluster) adds operational overhead; documentation is predominantly English/Russian.
Best for: high-cardinality monitoring (Kubernetes, microservices), teams on a budget with high throughput needs.
TDengine
TDengine is developed by TAOS Data. Its core design philosophy is one table per data point combined with a super table (STable).
Architecture:
- Super table: a schema template for a class of devices. Each physical device gets a child table inheriting the STable schema.
- Writes: each vnode (virtual compute node) handles a subset of child tables. Because data is sharded by device, writes are naturally lock-free.
- Queries: SQL-like syntax. Aggregation queries execute locally on each vnode, then the mnode merges results — significant push-down optimization.
Strengths:
- Device-level write performance is extremely high: 30M+ points/second on a single node, as officially claimed.
- Window functions, interpolation, and downsampling are first-class features.
- Built-in caching, stream processing, and data subscription — suitable for end-to-end IoT pipelines.
Weaknesses:
- SQL syntax is not standard PostgreSQL (
INTERVALsemantics differ), creating friction with BI tools. - Community edition is AGPL-licensed; pay attention to compliance in commercial settings.
Best for: massive IoT device fleets (tens of thousands to millions of devices), manufacturing / energy industries.
Prometheus
Prometheus is a CNCF graduated project and the de-facto standard for cloud-native monitoring. Its core is a local TSDB plus service discovery and alerting.
Architecture:
- TSDB: every 2 hours a new block is created. Each block contains chunks (sample data), an index (label index), and meta (metadata).
- WAL: writes land in a write-ahead log first to prevent data loss on crash.
- Remote Write: streams data to another TSDB (VictoriaMetrics, Cortex, Thanos) for long-term storage.
Strengths:
- PromQL is concise and powerful —
rate(),histogram_quantile(), and friends work out of the box. - Deep Kubernetes integration: Prometheus Operator, ServiceMonitor, AlertManager.
- Federation plus Thanos/Cortex enables global aggregation.
Weaknesses:
- Local TSDB isn't designed for long retention (default 15 days).
- Local storage is not highly available without remote-write or Thanos.
- High cardinality stresses memory and disk (each new label combination produces a new series).
Best for: core metrics monitoring in Kubernetes / cloud-native environments. Long-term storage and cross-cluster queries should be offloaded downstream.
Write performance benchmarks
| Engine | Single-node write rate (pts/s) | Write amplification | Protocols supported |
|---|---|---|---|
| InfluxDB 3 | ~1.2M (batch 10k) | Medium (Parquet compression) | Line Protocol, OTLP |
| TimescaleDB | ~300k (batch 5k) | Higher (WAL+B-Tree) | PostgreSQL Wire |
| VictoriaMetrics | ~1.8M (batch 5k) | Very low (LSM sequential append) | Prometheus RW, InfluxDB Line, Graphite, OTLP |
| TDengine | ~3M+ (per-device sharding) | Low (device-level isolation) | SQL-like, RESTful, OTLP |
| Prometheus | ~100k (single scrape) | Medium (block compression) | Prometheus RW, OTLP |
Test conditions: 8-core, 32 GB RAM, SSD. Write mode: batch, 8 fields per point. Actual results vary with label cardinality and batch size.
Query pattern comparison
| Engine | Query language | Downsampling | Cross-table JOIN | Visualization |
|---|---|---|---|---|
| InfluxDB 3 | SQL + InfluxQL | ✅ (SQL) | ❌ | Grafana, Tableau |
| TimescaleDB | PostgreSQL SQL | ✅ (Continuous Agg) | ✅ (native JOIN) | Grafana, Metabase, BI |
| VictoriaMetrics | MetricsQL / PromQL | ✅ (rollup) | Limited (join()) |
Grafana |
| TDengine | SQL-like + windows | ✅ (INTERVAL) | Limited (STable JOIN) | Grafana, built-in dashboard |
| Prometheus | PromQL | ✅ (rate()/avg_over_time()) |
❌ | Grafana |
If your query joins sensor readings with device metadata — e.g., "list compressors whose temperature exceeded 80°C in the last hour AND firmware version is below 3.2" — TimescaleDB is the only contender that can do this in one SQL statement.
High cardinality: the real test
High cardinality separates "works in a demo" from "survives in production".
Why it hurts
Each unique label combination (e.g., {app="checkout", region="us-east", pod="xxx-1234"}) creates an independent time series inside the TSDB. A Kubernetes cluster with 10,000 pods × 30 metrics per pod = potentially millions of series.
- Index bloat: each series requires an inverted-index lookup — enormous memory cost.
- Write contention: new series index entries need locks or atomic updates.
- Query fan-out:
sum(rate(metric{}[5m]))without label filters scans all series.
How each engine handles it
| Engine | High-cardinality strategy | Stability at 1M series |
|---|---|---|
| VictoriaMetrics | Label-value compression + LSM merge | ✅ Best-in-class |
| InfluxDB 3 | Columnar + partition pruning | ✅ Good |
| TDengine | Device-level sharding (series count = device count) | ✅ Good (bounded by device dimension) |
| TimescaleDB | PostgreSQL indexing + compression overlay | ⚠️ Requires careful index design |
| Prometheus | TSDB inverted index | ⚠️ Single-node ceiling ~10M series |
Annual cost estimates
Rough estimates based on a single 8c32g node with 10 TB storage (2026 cloud pricing reference):
| Engine | Compute (monthly) | Storage (monthly) | Ops burden | Annual total |
|---|---|---|---|---|
| InfluxDB 3 | ~$210 | ~$35 (S3 object storage) | Medium | ~$2,940 |
| TimescaleDB | ~$170 | ~$110 (block storage) | Medium-low | ~$3,360 |
| VictoriaMetrics | ~$140 | ~$55 | Low (single binary) | ~$2,340 |
| TDengine | ~$170 | ~$70 | Low | ~$2,880 |
| Prometheus (local only) | ~$110 | ~$85 | Medium | ~$2,340 |
Migration cost notes
- InfluxDB v1/v2 → v3: partial InfluxQL syntax deprecation; migrate queries to SQL. Line Protocol writes unchanged — data pipelines need minimal adjustment.
- Prometheus → VictoriaMetrics: add a single
remote_writeURL line to the Prometheus configuration. Scraping configuration untouched. PromQL/MetricsQL query migration is almost 1:1. - Any → TimescaleDB: the biggest challenge is rewriting non-SQL query logic into standard SQL + TimescaleDB hyperfunctions. Data import via CSV, pg_dump, or Kafka Connect.
Weighted decision framework
Fill in the weights based on your team's priorities:
| Dimension | Weight (1–5) | InfluxDB 3 | TimescaleDB | VictoriaMetrics | TDengine | Prometheus |
|---|---|---|---|---|---|---|
| SQL requirement | 4 | 5 | 2 | 3 | 1 | |
| Write throughput | 4 | 3 | 5 | 5 | 2 | |
| Query flexibility | 4 | 5 | 3 | 3 | 3 | |
| High cardinality | 4 | 3 | 5 | 3 | 2 | |
| Operational simplicity | 3 | 3 | 5 | 4 | 3 | |
| Cost | 4 | 3 | 5 | 4 | 4 | |
| Ecosystem integration | 4 | 5 | 4 | 2 | 5 |
Scores 1–5, relative only; validate with your own benchmarks.
Practical deployment patterns
- IoT vendor: TDengine as primary storage, Grafana connected via RESTful interface.
- SaaS / monitoring platform: Prometheus (scraping) → VictoriaMetrics (long-term), optimal cost-performance balance.
- Data analytics team: TimescaleDB handles sensor time-series + business table joins directly, BI tools connect via PostgreSQL.
- Data lake architecture: InfluxDB 3 + object storage, raw time-series data lands as Parquet for Spark/Trino analytics.
FAQ
Q1: Can I just use MySQL/PostgreSQL with a time index?
Feasible at low volume (tens of thousands per day). Once you exceed ~10k writes/second, B-Tree write amplification and autovacuum cause significant latency jitter. Lack of automatic downsampling means historical queries keep getting slower.
Q2: VictoriaMetrics vs. ClickHouse?
ClickHouse is a general-purpose OLAP engine — you need to design table schemas (ORDER BY + TTL) for time-series yourself. VictoriaMetrics is purpose-built: compression, downsampling, PromQL out of the box. If you need frequent JOINs with dimension tables or arbitrary free-form analysis, ClickHouse is more flexible; if your focus is metrics monitoring and alerting, VictoriaMetrics is less work.
Q3: Is object storage mandatory for TSDBs?
No. Prometheus on local SSD works well. But if you need retention beyond ~30 days, object storage's cost advantage is definitive — S3 Glacier Deep Archive runs ~$0.00099/GB/month.
Q4: Recommended alerting stack?
- Prometheus + AlertManager (native integration, flexible routing).
- VictoriaMetrics + vmalert (PromQL-compatible alerting rules).
- Grafana Alerting (visual configuration, multi-channel notifications).
Q5: How does time-series compression actually work?
Three core techniques:
- Timestamp delta + delta-of-delta: record the difference from the previous timestamp. For periodic collection, delta is constant and ddelta is zero — near-zero storage cost.
- Value XOR (Gorilla algorithm): XOR adjacent floating-point values; leading zeros, trailing zeros, sign bit, and exponent are all stripped.
- Columnar layout: adjacent values in the same column are far more similar than in the same row — columnar compression dramatically outperforms row-based.
Conclusion
Test every TSDB with your own data volume. A benchmark at 100k active series is a completely different world from one at 10 million. The stack that works for a 10-node cluster may crumble at 1,000 nodes.
A practical evaluation flow:
- Use
tsbs(Time Series Benchmark Suite) to generate workloads resembling your real data. - Ingest into each candidate, recording p99 write latency, CPU, and memory.
- Run your 10 most frequent queries, recording p50/p99 latency.
- Simulate failures (kill process, disconnect network), verify recovery speed and data integrity.