Advanced Topics
Time-Series Databases
Storing data that only moves forward in time — metrics, events, sensor readings — and why append-heavy, time-ordered workloads get their own kind of database.
A time-series database (TSDB) is built for data where time is the primary axis: server metrics, IoT sensor readings, stock ticks, application events, ad clicks. These workloads look nothing like a typical app's — they're overwhelmingly append-only, arrive in huge volume, are almost always queried by time range, and get less valuable as they age. That distinct shape is why specialised stores (InfluxDB, TimescaleDB, Prometheus) exist.
What makes the workload special
- Writes dominate, and they're append-only. New points stream in constantly; old points are rarely updated. A million sensors reporting every second is a firehose of inserts.
- Queries are time-ranged and aggregated. You almost never fetch one point — you ask "average CPU over the last hour, per minute," "p99 latency today," "clicks per 5-minute bucket." Raw points get rolled up.
- Recent data is hot; old data is cold. You query the last hour constantly and last year rarely. The data has a natural lifecycle.
A general relational table can store this, but it struggles: indexes bloat under relentless inserts, time-bucket aggregations get expensive, and you end up manually deleting old rows.
How TSDBs optimise for it
- Time-based partitioning. Data is automatically chunked by time window, so a range query reads only the relevant chunks and old chunks are cheap to drop. (TimescaleDB does this on top of Postgres via "hypertables.")
- Heavy compression. Time-series data compresses extremely well (values change slowly, timestamps are regular), cutting storage by an order of magnitude.
- Built-in downsampling & retention. Automatically roll raw points into coarser aggregates as they age (per-second → per-minute → per-hour) and expire the raw data. You keep cheap summaries forever and raw detail only recently.
- First-class time functions. Bucketing, gap-filling, moving averages, rate — the operations these queries always need, built in.
The lifecycle pattern
The defining idea is downsampling + retention: full-resolution data for recent time, progressively coarser aggregates for older time, and automatic deletion past a horizon. A monitoring system might keep per-second data for a day, per-minute for a month, per-hour for a year. This keeps storage bounded and dashboards fast without you writing cleanup jobs.
Where it fits in a design
A TSDB is usually the serving layer at the end of a metrics pipeline: events stream through Kafka, a stream processor (Flink) aggregates, and rollups land in the TSDB that dashboards and alerts read. Your transactional database stays out of the firehose entirely.
What to watch
- It's for metrics/events, not relational data. Don't put your users and orders in a TSDB.
- Cardinality. Too many distinct label combinations (high-cardinality tags) can blow up some TSDBs — design labels carefully.
- Often you don't need a separate one. At modest scale, TimescaleDB (Postgres extension) or even a well-partitioned table does the job without a new system.
What to say in an interview
Recognise the time-axis, append-heavy workload and reach for the right lifecycle:
"Metrics are append-only, high-volume and always queried by time range, so I'd store them in a time-series database rather than Postgres. It partitions by time so range queries are fast and old chunks drop cheaply, and I'd set a downsampling policy — per-second for a day, per-minute for a month, per-hour for a year — so storage stays bounded. The raw firehose goes through Kafka and gets aggregated before landing there."
Next up: Data Structures for Big Data — probabilistic structures that trade a little accuracy for enormous savings.
