Courses › System Design › Key Technologies

Time-Series Databases

Prometheus, InfluxDB and TimescaleDB: series, compression, downsampling and cardinality.

A time-series database (TSDB) stores measurements indexed by time — CPU usage every 10 seconds, a stock price on every trade, a sensor reading every minute — and is built to ingest them at very high rates and query them by time range. The common ones are Prometheus (metrics monitoring), InfluxDB, TimescaleDB (a PostgreSQL extension) and M3/VictoriaMetrics for large scale. In interviews they come up in metrics and monitoring, IoT, and financial market data.

Data model

http_requests_total{service="checkout", region="us-east", status="500"}  1734  @ 2026-10-12T10:00:00Z
└──── metric name ────┘└──────────────── labels (tags) ────────────────┘  value  timestamp
  • A series is one metric name plus one unique combination of labels. Each series is a stream of (timestamp, value) points.
  • Writes are almost always appends of recent data; updates and deletes are rare.
  • Queries filter by labels and a time range, then aggregate: rate, sum, average, percentiles, grouped by a label.

Why they're efficient

  • Time-partitioned storage — data is written into blocks per time window (e.g. 2 hours), so a range query touches only a few blocks and expiring old data means deleting whole blocks.
  • Compression — delta-of-delta encoding for timestamps and XOR encoding for values (the Gorilla technique) shrink a point to about 1–2 bytes.
  • Inverted index on labels — finds every series matching service="checkout" quickly.
  • Downsampling and retention — keep raw 10-second data for 15 days, 5-minute rollups for a year, hourly rollups forever.

[!WARNING] Cardinality is the classic failure Each unique label combination is a new series. A label like user_id or request_id creates millions of series and can take the database down. Keep labels low-cardinality (service, region, status code), and put per-request detail in logs or traces instead.

Push vs pull

  • Pull (Prometheus) — the server scrapes each target's /metrics endpoint every N seconds. Missing scrapes reveal dead targets, and targets are found through service discovery.
  • Push (InfluxDB, StatsD, OpenTelemetry) — agents send data to collectors. Better for short-lived jobs and devices behind firewalls; usually buffered through Kafka at scale.

Choosing one

When to use one

  • Infrastructure and application metrics, dashboards and alerting
  • IoT and sensor telemetry
  • Market data and other high-rate numeric streams queried by time window

When not to

  • Business events with many dimensions and high-cardinality filters — an OLAP store fits better
  • Logs and traces — use a log store (Elasticsearch, Loki, ClickHouse) and a tracing backend

[!INTERVIEW] Metrics and monitoring system "Agents push metrics to a collector tier that writes to Kafka, partitioned by series hash. Ingesters consume them into a sharded TSDB that stores 2-hour compressed blocks, uploads completed blocks to S3, and downsamples older data. An alerting service evaluates rules every 30 seconds against recent data. I'll enforce a per-tenant series limit to guard against cardinality explosions." See Design Metrics Monitoring & Alerting and Time-Series Ingestion.