Metrics, application events, sensor readings, and audit logs all have the same shape: timestamped records that arrive continuously, are almost never updated, are queried over time ranges, and become less interesting as they age.
That shape is specific enough to optimise for, which is why purpose-built time-series stores exist and why they can be dramatically more efficient than a general-purpose table for the same data.
What changed in 2026
- Relational extensions closed much of the gap. Time-series capabilities added to general databases made adopting a separate system less necessary.
- Compression improved further. Specialised encodings for ordered numeric data pushed storage efficiency higher.
- Retention automation became standard. Automatic downsampling and expiry moved from configuration to built-in behaviour.
- Cardinality limits stayed the main constraint. High-cardinality label sets remained the failure mode across implementations.
What makes the workload distinctive
| Property |
Time-series |
General OLTP |
| Writes |
Append-only, high rate |
Mixed insert and update |
| Updates |
Rare or never |
Common |
| Queries |
Time ranges, aggregates |
Point lookups, joins |
| Recency bias |
Strong — recent data queried most |
Weak |
| Retention |
Old data dropped or downsampled |
Retained |
| Cardinality |
Can be enormous |
Moderate |
Each row enables an optimisation. Append-only writes mean no in-place update machinery. Time-range queries mean data can be physically ordered by time so a range is a contiguous read. Recency bias means recent data can live on fast storage and old data on cheap storage. Predictable retention means dropping old data can be a metadata operation.
Compression is the headline
Time-series data compresses extraordinarily well, and this is usually the largest practical difference.
Consecutive readings from the same source are similar. Timestamps increase at regular intervals. Values change slowly. Stored as columns rather than rows, those properties enable specialised encodings — storing differences rather than values, run-length encoding for repeated values, and delta encoding for regular timestamps.
Compression ratios well beyond what general-purpose storage achieves are normal, which changes what is affordable to retain. See columnar storage for the underlying mechanism.
Retention and downsampling
Old time-series data is rarely needed at full resolution. Per-second metrics from two years ago are useful as hourly averages and not as individual points.
Downsampling aggregates old data to a coarser resolution and discards the detail, which is frequently a hundredfold reduction. Purpose-built stores automate this: keep full resolution for a week, hourly for a year, daily beyond that.
Dropping old data must also be cheap. Deleting a month of rows with a DELETE is expensive and produces bloat; dropping a partition is a metadata operation — see table partitioning.
That is the single most valuable capability for this workload, and it is available in a general database with partitioning.
Try partitioning first
Before adopting another database, consider what a partitioned relational table gives you:
Time-based partitioning, so range queries prune irrelevant partitions and dropping old data is instant. An index on the time column and any dimension you filter by. Compression where your engine supports it per-column or per-partition.
That covers a substantial fraction of time-series workloads, and it keeps everything in one system you already operate — which is worth more than most people account for. Another database means another thing to back up, monitor, upgrade, and be paged about.
Purpose-built stores earn their place at genuinely high ingest rates, where compression ratios materially change storage cost, where automatic downsampling is needed, and where query patterns are overwhelmingly time-range aggregations.
The constraint to check either way is cardinality. Time-series systems index by the combination of dimensions, and a dimension with unbounded values — a user identifier, a request identifier — produces enormous cardinality that degrades every implementation. Keeping high-cardinality identifiers out of the dimension set is the single most important schema decision.
Common mistakes
- Adopting a specialist store for modest volume. Operating another database is a real cost.
- High-cardinality dimensions. The dominant failure mode.
- Deleting old rows instead of dropping partitions. Expensive and produces bloat.
- No downsampling policy. Storage grows without bound at full resolution.
- Treating it as a general database. Joins and updates are not what it is for.
- Not partitioning a relational table used this way. Gives up the cheapest win.
FAQ
Can I use my existing database?
Frequently yes, with time-based partitioning and appropriate indexing. That covers a lot of ground before a specialist system is warranted.
What ingest rate justifies a specialist store?
There is no clean threshold — it depends on your hardware and schema. The practical trigger is when partitioning and compression in your existing database stop keeping up.
What about high-cardinality data?
Store high-cardinality identifiers as values rather than as indexed dimensions, or use a different store for that data. This is the constraint that most often forces a rethink.
Is this the same as an event store?
Related and different. Event sourcing stores events as the source of truth for reconstructing state; time-series storage optimises for aggregating measurements over time.
Where to go next
For the partitioning approach in a general database, read table partitioning and hypertables. For the compression mechanism, columnar storage.