Written by
Halkwinds Editorial Team
Halkwinds Research & Editorial

Time-Series Databases: When and Why to Use Them
How time-series databases differ from relational and document databases, and when they are the right tool for metrics, IoT, and financial data.
If you have ever tried to store 50,000 sensor readings per second in PostgreSQL, watched your write throughput collapse, and then discovered that a simple "average CPU over the last 24 hours grouped by 5-minute buckets" query takes 40 seconds, you already understand the problem that time-series databases exist to solve. Metrics, IoT telemetry, financial ticks, and application observability data all share a common shape — timestamped, append-heavy, and queried by ranges — that general-purpose databases handle poorly at scale. This article breaks down what makes time-series databases (TSDBs) different, when they are the right tool, and how to implement one without inheriting a new class of operational headaches.
- Background / Why This Matters
- Core Concepts and Architecture
- Implementation Strategy
- Scaling and Operational Considerations
- Common Mistakes / What to Avoid
- Frequently Asked Questions
- Conclusion
Background / Why This Matters
Time-series data is one of the fastest-growing data categories in modern systems, and the reason is structural rather than hype-driven. Cloud-native architectures emit metrics from every container, service mesh, and load balancer. IoT deployments push telemetry from thousands of edge devices. Financial systems record every quote and trade. All of these produce high-cardinality, high-velocity, timestamp-indexed data that is written far more often than it is updated.
The pain data engineers feel usually shows up in three places:
- Write amplification. Relational databases maintain B-tree indexes that must be rebalanced on every insert. Ingesting millions of rows per minute causes index bloat, lock contention, and vacuum pressure in PostgreSQL or fragmentation in MySQL.
- Storage cost. Raw time-series data is enormous, but it is also highly compressible because consecutive values change slowly. General-purpose engines rarely exploit this.
- Query patterns. Nearly all analytical queries are range scans with time-based aggregation (downsampling, rollups, moving averages). Row-oriented storage forces you to read far more than you need.
Time-series databases are purpose-built around these realities. Rather than treating the timestamp as just another column, they treat it as the primary organizing axis of the entire storage engine.
Actionable takeaway: If more than 70% of your workload is time-ordered inserts and range-based reads, you are likely paying a hidden tax by forcing that workload into a general-purpose database.
Core Concepts and Architecture
To evaluate TSDBs sensibly, you need to understand the handful of concepts that define them.
Data model: measurements, tags, and fields
Most TSDBs organize data around a measurement (e.g., cpu_usage), a set of indexed tags (e.g., host, region, datacenter), and one or more fields (the actual numeric values). Tags define cardinality; fields hold the payload. In InfluxDB this is explicit in the line protocol. In Prometheus, labels play the tag role. In TimescaleDB, you keep the familiar SQL table model but add a time dimension.
Time-partitioned storage
The defining architectural trick is partitioning data by time into chunks (TimescaleDB calls them "hypertable chunks," InfluxDB uses "shards," Prometheus uses TSDB "blocks"). This gives you three advantages: recent data stays hot in memory, old chunks can be compressed or dropped cheaply, and range queries only touch relevant partitions.
Columnar compression
Because time-series values are sequential and slowly changing, TSDBs apply specialized encodings: delta-of-delta for timestamps, Gorilla/XOR compression for floating-point values, and run-length encoding for repeated tags. Real-world compression ratios of 10x or more are commonly reported for observability workloads, though your mileage depends heavily on cardinality and value volatility.
Downsampling and retention
TSDBs bake in the idea that data loses granularity value over time. You keep raw 1-second data for a week, 1-minute rollups for a month, and 1-hour rollups for a year. Continuous aggregates (TimescaleDB), tasks (InfluxDB), and recording rules (Prometheus) automate this.
How the major options compare
| Dimension | InfluxDB | TimescaleDB | Prometheus |
|---|---|---|---|
| Query language | Flux / InfluxQL | Full SQL (Postgres) | PromQL |
| Underlying model | Purpose-built TSM engine | PostgreSQL extension | Purpose-built pull-based |
| Primary use case | IoT, metrics, events | Metrics + relational joins | Infra/app monitoring |
| Data ingestion | Push (line protocol) | Push (SQL inserts/COPY) | Pull (scrape) |
| Long-term storage | Built-in retention | Compression + tiering | Needs remote write (Thanos/Cortex/Mimir) |
| SQL/JOIN support | Limited | Full | None |
| Best fit team | Teams wanting a dedicated TSDB | Teams already on Postgres | Kubernetes/DevOps monitoring |
Actionable takeaway: Choose based on your existing stack and query needs. If your team lives in SQL and needs to join time-series data with relational metadata, TimescaleDB avoids a new query language. If you are monitoring Kubernetes, Prometheus is the default for a reason. If you have diverse IoT ingestion, InfluxDB's line protocol and ecosystem are hard to beat.
Implementation Strategy
A successful TSDB rollout is less about picking the "best" database and more about modeling your data correctly and integrating it cleanly. Here is a pragmatic sequence.
- Profile your workload first. Measure ingest rate (points/sec), cardinality (unique tag combinations), query patterns, and retention requirements. Cardinality is the single biggest predictor of TSDB pain — a metric tagged with
user_idorrequest_idcan explode into millions of series and cripple performance. - Design your schema around queries. Put low-cardinality, frequently-filtered dimensions in tags/labels. Keep high-cardinality identifiers as fields, or better, avoid storing them as series dimensions at all. A common rule of thumb: if a value is nearly unique per data point, it is a field, not a tag.
- Set up ingestion. For push-based systems (InfluxDB, TimescaleDB), use Telegraf, a message queue like Kafka, or batched writes rather than single-row inserts. TimescaleDB benefits enormously from
COPYor batch inserts over row-by-row writes. For Prometheus, configure scrape intervals and targets carefully. - Define retention and downsampling on day one. Do not defer this. Configure continuous aggregates or downsampling tasks before ingesting production volume, or you will scramble later when storage costs spike.
- Wire up querying and dashboards. Grafana is the near-universal front end and supports all three databases natively. Standardize dashboards early so teams query rollups instead of raw data by default.
For teams standing up a metrics or IoT platform for the first time, the modeling and cardinality decisions made in week one have outsized long-term consequences. This is one area where Halkwinds' Data & Analytics practice often helps clients — running a workload profiling exercise and designing the schema before a single production record is written, which is far cheaper than re-architecting after a cardinality explosion.
Actionable takeaway: Never store high-cardinality identifiers as tags/labels. Test your schema with realistic cardinality synthetically before production, because the failure mode is silent until it isn't.
Scaling and Operational Considerations
TSDBs scale differently from OLTP databases, and the operational model matters as much as raw performance.
Cardinality management
Cardinality is the recurring theme. Every unique combination of tag values creates a new time series that must be indexed in memory. Prometheus, for example, keeps an in-memory index of all active series, so a cardinality explosion translates directly into out-of-memory crashes. Monitor your series count as a first-class operational metric and alert on unexpected growth.
Retention and tiering
Storage grows relentlessly. Plan for hot, warm, and cold tiers:
- Hot: recent raw data on fast SSD.
- Warm: compressed rollups on cheaper storage.
- Cold: object storage (S3) via TimescaleDB tiering, Thanos/Mimir for Prometheus, or InfluxDB's tiered storage options.
High availability and horizontal scale
This is where architectures diverge sharply. Prometheus is intentionally single-node and durable-by-simplicity; horizontal scale comes from federation or remote-write systems like Thanos, Cortex, or Grafana Mimir. TimescaleDB scales vertically well and offers multi-node and read replicas. InfluxDB's clustering capabilities depend on the version and edition. Understand these boundaries before you promise "infinite scale" to stakeholders.
Backup and recovery
Because these systems are write-heavy, backups must be incremental and continuous. TimescaleDB inherits Postgres backup tooling (pg_dump, pgBackRest, WAL archiving). Prometheus snapshots blocks. Test restores regularly — a backup you have never restored is a hypothesis, not a safeguard.
Actionable takeaway: Treat active series count and storage growth rate as SLO-level operational metrics. Provision remote-write or tiering before you hit capacity, not during an incident.
Common Mistakes / What to Avoid
Most TSDB failures are self-inflicted and predictable. The following list covers the ones we see most often.
- Using a TSD
Explore Further