The Rise of Open Source Time Series Databases
victoriametrics.com
victoriametrics.com
Everybody thinks TSDB are something new-ish, but they've been around since the days of APL. All you youngins disappointment me every time you write about time series, vector languages, or data-oriented programming and entirely neglect all the work that comes under the APL/Vector umbrella. SOA and DOD have been around for 50+ years, and they didn't start with c++ or Pandas.
Now the creator, Arthur Whitney, has a new one out called Shakti that is even faster (but has also ditched from the "niceties" of Q.
EDIT: yeah that sentence is new. I think some of the sentences around Influx being the "first" have been adjusted too now saying it is the first "mainstream" and called other db's niche. it's also a little off. KDB+ is more popular in large banks and trading firms than HFT places.
It might take a bit more context or setup, but this article is an opportunity to educate folks who aren't deep in the same trench.
Edit: in fairness, this article doesn't describe itself as "a Postgres developer's guide to getting started with time series databases" and maybe that's what I was unfairly hoping I would find.
propertyid, timestamp, value
Then add a covering index so your reads only ever hit the index. This works completely fine for low billions of rows. After that suggest using clickhouse. It is less general but at large enough scale you need to make some tradeoffs. Completely fine to start with a relational DB in many cases though.
The article mentioned stock prices, so let's use your schema:
LLY.NYSE, 1726377148, 924.38
SHOP.NYSE, 1726377216, 72.45
SHOP.NYSE, 1726377245, 72.41
LLY.NYSE, 1726377284, 924.39
LLY.NYSE, 1726377310, 924.36
Okay, so you're appending values that capture a moment in time for a given index, with the understanding that you're almost never going to revise a tuple. So far as we're concerned, time only flows in one direction. Periodicity is determined by the client application but could be throttled due to a bottleneck, resulting in fewer writes.
I can imagine how storing in blocks based on time ranges and the fact that time number goes up makes this very easy to index.
With even this simple example, it's clear what this type of datastore could be useful for, even though I'm not convinced you couldn't do pretty exciting things in Redis or sqlite3.
That said, I'm still significantly confused why the hell you can only store numeric values. It just seems like a very arbitrary constraint.
The key is the covering index, you don't want to hit the actual table at all. You should re-organize the index periodically as well in order to ensure optimal query times.
This is suboptimal in many ways as the records are tiny yet there is per row overhead. However, it works fine to low billions of rows in general. I think it would work fine in SQLite as well. Redis is a very different animal however so a different strategy would be needed.
Migrating the same schema to ClickHouse when you need it (I have no affiliation with them), will give you 50X lower data footprint, increase your ingest rates by 10X and your query times by about 2X. However, if you don't really need that, don't bother adding another component in your infrastructure (imo). Also, ClickHouse is much more of a purpose built Ferrari. I.e. you can't expect it to do all kinds of "off schema" type queries (i.e. give me all the stock values on Jan 10, @ 10:32:02.232am). In a relational DB you can add indexes and get results reasonably well. In ClickHouse schema == query pattern essentially. Naturally, you should know what you are doing with both models but in ClickHouse, don't treat it like a "magic data box" that will can handle anything you throw at it (beyond a certain scale at least).
My guess is that constraining to numbers greatly simplifies the implementation, especially so for the query language and aggregation functions.
For enormous amounts of data, you want your data to be sequential (a few batch reads are generally faster than lots of random ones) and sorted. Databases like Postgres don't store rows in index order, and their indexes are geared towards small fetches as opposed to big ranges of sequential data. (Postgres does have BRIN indexes, but they're not that great for this.) Other databases do support clustered tables, but they're still page-based underneath and still not suboptimal for other reasons. It's a good learning exercise to compare traditional databases with something like ClickHouse, which was s designed from the ground up to store data in this optimized way. (It's a general-purpose OLAP database, so columns can be any kind of data, not just numbers, and data doesn't need to be time-based; so it's useful for much more than "pure" TSDBs.)
As for numbers: For metric data you're storing numeric measurements. The whole point is applying aggregations to the data, like calculating an average or a percentile over a certain time period. Storing numbers also has the advantage of allowing downsampling. For many purposes you don't need 1s granularity for all your data. So as you "roll" data over into old time periods, you can downsample by storing the data points aggregated as mean/min/max/etc. New data can be exact down to the second, while old data can be exact down to the hour, for example.
"In mathematics, a time series is a series of data points indexed (or listed or graphed) in time order."
A a numeric datapoint is by far the largest use case, timeseries databases optimize for that. Most allow you to have several labels ofcourse, i.e. you could store country border crossings as
{from: US,to:Canada} 1726377148, 2123 {from: US,to:Mexico} 1726377148, 34567
However, strings aren't as common as usually you are a value of some sort.
Maybe Influx took off in a way these prior projects didn't, but people have been storing time series data for decades.
Oddly InfluxDB has raised amounts of VC money approaching KDB parent companies current market cap. I know VC raised and market cap are not directly comparable, but what is the hoped-for enterprise value at exit of NewCo if the IncumbentCo is worth Z?
My take is that orgs with real revenue-generating time series data challenges, budget and dev staff to cook up solutions have long ago bought KDB licenses or rolled their own in-house column store.
Orgs using time series DBs for telemetry/observability/etc type of "back office" problems (where you are willing to downsample/conflate/offload history) either don't want to pay a dime, or want a fully formed SaaS solution with pretty GUI, alerting, etc like a DataDog they will like $10M/year to.
Not a lot of middle ground oddly.
I remember when a bunch of WSO2 contribs broke off, made their own (AGPL) ESB, and created a 'ESB Performance' website that cherry picked specific scenarios to make WSO2 look worse than their product.
This was made funnier because the 'consultant' (really a buddy of management that used us as an experiment for all sorts of things, at least the code was readable, learned lots of languages fixing things lol) wound up having us go with the AGPL product, and it wasn't until I said to the team 'hey, lets try using the WSO2 docs as a cross reference' before we got productive.
I do miss the 'dramatic readings' of UltraESB docs, learned a colleague understood Pashto [0].
[0] - After a specific 'verse', the colleague pointed out one of the odd phrases in the docs that prompted this practice, was a colloquialism in that language.
Why would that not have been rrdtool or something earlier?
[1]: https://graphiteapp.org/ [2]: https://grafana.com/ [3]: https://aosabook.org/en/v1/graphite.html
Since I would actually like to store all recorded values permanently, I could partially achieve this with VM which let me set a higher threshold, like 100 years. Still not 'forever' as I would have liked, but I guess me and my flimsy weather data setup will have other things than the retention threshold to worry about in 100 years.
Would be nice to learn the reason why an infinite threshold is not allowed.
I didn't pick thanos because I really like the horizonal scaled blob store architecture the Grafana crew put together.
To be fair many projects in Prometheus "long term store" space come and gone - Thanos, Cortex, M3
Most TSDBs aren't built for use cases like "query hourly/daily data over many years". Many use cases aren't looking further than 30 days because they're focused on things like app or device uptime and performance metrics, and if they are running on longer time frames they're recording (or keeping, or consolidating data to) far fewer data points to keep performance usable.
The only workaround I've found so far is to dump out the whole timeseries which could go back months/years, delete the timeseries, fix/delete data in the dump and re-ingest the whole thing. This really, really sucks.
I will look up the query and get back to you
Broadly speaking I can say I'd trust TSDB over Influx for a lot of cases since it's using Postgres under the hood, and while I don't know precisely what issues we had adopting Influx, I know we had some as we 'scaled up' tho and that was when stuff like tag limits were brought up a lot (Interestingly, our app was 'barely passing' because we metric'd a lot but we also kept stuff just short enough for everyone to be OK with it, mostly because the metrics we got were very useful for things)
Previously InfluxDB was Open Core, with very crippled Community version (ie High Availability was Enterprise only)
I’ve personally found TimescaleDB to be a much easier to work with platform, even if there is more overhead in defining a schema and enabling compression, etc.
But v3 is still under development so I'll explore Prometheus.
Let's talk LLMs instead.