
AkumuliArchived
A single-node C++ time-series database that keeps one compressed B+tree per series, with its own codecs for timestamps and floating-point values.
- What it is
- Time-series databases
- Used for
- Metrics
- Type
- Open source
- Made by
- Eugene Lazin (independent project)
- License
- Apache 2.0
- Status
- Archived since 21 May 2020
- Facts checked
- 23 October 2026
What it is
Akumuli is a server, akumulid, built on a storage engine library. A series is a metric name plus tags, such as cpu.user host=pg-balancer region=NE, and each point is a nanosecond timestamp and a double, or a string for event series whose names start with !. Writes arrive over TCP (port 8282) or UDP (8383) in a format borrowed from Redis’s RESP, or as OpenTSDB telnet put lines, so collectors such as Netdata, collectd and tcollector can feed it. Queries are JSON objects posted to /api/query on the HTTP port (8181): select, aggregate, group-aggregate over a time step, and join, with tag filters and functions such as rate and ewma. Results stream back as RESP.
Storage is one Numeric B+tree (NB+tree) per series. Leaves hold about 1,000 compressed points; when a level fills, it is written to disk and linked into the level above, so data is never rewritten, unlike compaction in an LSM tree. Inner nodes carry aggregates, which lets downsampling queries skip reading leaves, without rollups set up in advance. Timestamps are delta-encoded, then each chunk subtracts its smallest delta and stores the rest in a byte-aligned variable-length code with 4-bit length flags. Values are XORed with a guess from a DFCM predictor, which learns from past differences between values, and only the non-zero bytes are kept. The disk is split into fixed-size volumes (4 GB by default), so it can use a fixed amount of space, like RRDtool; with nvolumes = 0 it grows on demand instead.
Why teams pick it
- High single-node ingest: the README reports 16.1 million writes a second on a 32-core EC2 c3.8xlarge
- Compact storage without tuning: a point takes 0.1 to 9 bytes depending on how random the data is, and 1 to 2 bytes for many integer monitoring series
- Fast downsampling and aggregation from aggregates kept in tree nodes, without materialized views
- Takes OpenTSDB
putlines, so existing collectors work, and has a Grafana data source and a Prometheus remote-storage adapter
Watch out for
- Unmaintained since 2020, with the repository archived and packages only for old Linux releases
- One node only: no clustering or replication, and the roadmap’s out-of-order inserts, updates and deletes never shipped
- Memory grows with the number of series, because each series keeps a resident part of its tree; about 10 GB of RAM for a million series of up to 4 GB each
- Its own JSON query format instead of SQL or PromQL, and no Windows support
- Data model
- Series named by a metric and tags; points are a timestamp and a double
- How it scales
- One node; no clustering
- Replication
- None
- Storage engine
- One compressed NB+tree per series, never rewritten
- Retention
- Fixed-size volumes overwritten like RRDtool, or growing on demand
- Written in
- C++
- Ways to run it
- Self-hosted Linux packages; the project is archived
Alternatives, recommended first
What all time-series databases have in common →Compare side by side →
QuestDBOpen sourceA columnar time-series database in Java, C++ and Rust that ingests millions of rows a second and answers time-series SQL, with old partitions kept as Parquet.
TDengineOpen sourceA clustered time-series database for IoT and industrial data that gives every device its own table, grouped under “supertables” with tags.Apache IoTDBOpen sourceAn Apache time-series database for industrial IoT that stores everything in its own open file format, TsFile, and lets you model devices as a tree of paths or as SQL tables.+1 TimechoDB
Apache HoraeDBArchivedOpen sourceA distributed time-series database in Rust, started at Ant Group as CeresDB, that keeps recent writes in a WAL and memtable and flushes them as Parquet files to object storage.How it fits with other technologies
Write two points over RESP, then ask for one-minute minimums and maximums · bash
# a series name, a timestamp and a value per point, each line ending in CRLF
printf '+cpu.user host=machine1 region=NW\r\n+20180530T123000\r\n+22.5\r\n+cpu.user host=machine1 region=NW\r\n+20180530T123010\r\n+23.0\r\n' \
| nc localhost 8282
curl -s localhost:8181/api/query -d '{
"group-aggregate": { "metric": "cpu.user", "step": "1m", "func": ["min", "max"] },
"range": { "from": "20180530T123000", "to": "20180530T130000" },
"where": { "region": "NW" }
}'See it in a real stack
No architecture uses Akumuli yet. Drop it into the playground and wire it up yourself.Open playground →Where it came from2014–2020
Eugene Lazin began Akumuli around 2013; the name is Esperanto for “accumulate”. In a January 2015 post he listed what he found missing in open-source time-series databases: compression that can’t be turned off, sustained writes above a million points a second, a fixed disk footprint like RRDtool’s, simple retrieval by series and time range, and one executable with one configuration file. He argued that a single modern machine is enough for most monitoring workloads, so the project stayed standalone rather than distributed.
The first engine was a log-structured store over memory-mapped files. By September 2016 Lazin was rewriting it: the old design couldn’t backfill data, had to read a whole time range to draw one series, ran only on 64-bit Linux and had a single writer thread. The replacement, the NB+tree described in 2017, gave every series its own tree, along with new codecs for timestamps and floats; the README claims they beat Facebook’s Gorilla compression.
Work in 2018 and 2019 added support for high-cardinality data, scalable downsampling and a write-ahead log, and the 0.8 releases added joins and expression evaluation. The last blog post, in March 2020, analyzed 500 billion rows, and 0.8.80 in May 2020 was the final release.
Why it’s built this way
- One B+tree per series instead of time-partitioned chunks
- Queries usually read a few series, so keeping each series in its own page-aligned tree avoids reading unrelated data, and appends need no reads at all.
- Link full levels instead of merging files
- LSM trees rewrite data during compaction and keep many files open, which made one tree per series impractical; promoting a full extent only adds a pointer to the level above.
- A specialized codec instead of a general compressor
- Libraries like LZ4 need about 12 KB of state per stream, roughly 1 GB for 100,000 series. Delta coding for timestamps and predictive XOR coding for values need far less: the predictor’s table holds 128 entries.
- A DFCM predictor rather than the previous value
- Gorilla’s XOR against the previous value works for slowly changing series. A predictor that learns repeating differences also handles steady growth and repeating patterns.
Timeline
- 2014
GitHub repository created in January; v0.2.0 tagged in December
- 2015
Lazin publishes the project’s goals and RESP-based write protocol
- 2016
Rewrite around a new Numeric B+tree storage engine begins
- 2017
NB+tree design and the float codec published
- 2018
Posts on scalable downsampling and high-cardinality support
- 2020
Final release, 0.8.80, in May
- Akumuli blog: Motivation (January 2015)
- Akumuli blog: Standalone (October 2015)
- Akumuli blog: What’s next (September 2016)
- Akumuli blog: NB+tree (April 2017)
- Akumuli blog: Compression, part 1, timestamps (December 2016)
- Akumuli blog: Compression, part 2, floating-point values (February 2017)
- Akumuli blog: index of posts (2015 to March 2020)
- GitHub: Akumuli releases (0.8.80, May 2020)
- GitHub: Akumuli CHANGELOG
Sources11 · facts checked 23 October 2026
- GitHub: Akumuli README (features, ingest benchmarks, roadmap, collectors, Grafana and Prometheus integrations)
- Akumuli: home page (Apache 2.0, standalone, fixed disk space)
- Akumuli docs: Getting started (packages, volumes, nvolumes, ports)
- Akumuli docs: Data model (metrics, tags, events)
- Akumuli docs: Writing data (RESP, OpenTSDB put, timestamps)
- Akumuli docs: Query language (select, aggregate, group-aggregate, join)
- Akumuli docs: API endpoints (/api/query, /api/search, functions)
- Akumuli docs: Hardware requirements (memory per series, bytes per point)
- Akumuli blog: NB+tree (extents, leaf size, aggregates in inner nodes)
- Akumuli blog: Storage engine design, part 2 (no reads on write, memory per series)
- Akumuli source: compression.h (DeltaDelta, VByte, DFCM float encoder)