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
/metricsendpoint 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.