← The Dry Stack

Facts

Embedded time-series fact store — SIMD query surfaces over billions of records.

What it is. A time-series engine that lives inside your process — no server to deploy, no network hop to query. It holds billions of timestamped facts and answers range, tag, scan and aggregate queries with SIMD in microseconds.

The problem it kills. The usual answer to “a lot of time-series data, queried fast” is a cluster of database nodes you have to run, tune and pay for. Facts does it on one box.

For example. Store every tick from thousands of sensors or market symbols, then ask “what did device 4200 look like between 09:00 and 09:05” — and get the answer back before a network round-trip would have even finished.

The data model

Every record is dead simple, which is exactly why it’s fast. A fact is a timestamp and a tag — that pair is the core. Onto it you attach two kinds of payload, depending on the shape of your data.

the core

Timestamp + Tag

The timestamp orders the fact; the tag names the series it belongs to — a device, a market symbol, a driver, a log source.

Everything is indexed and queried on this pair: “this tag, this time window.” Nothing else to declare to get a working store.

fixed size

Columns

For fixed-size fields — a price, a temperature, an RPM — declare typed columns. They’re stored columnar, so a SIMD kernel streams one column at full memory bandwidth.

That’s what makes point access and scans cheap: read just the column you asked for, never the rest of the row.

variable size

Blob

For variable-size payloads — a log line, a JSON document, a packet, a Dry.Wire record — attach a blob. Facts stores it opaque and hands it straight back.

Blobs can be compressed by a codec you plug in (e.g. LZ4): Facts stores the packed bytes and decompresses transparently on read, so the on-disk footprint shrinks while your code still sees plain payloads. Ideal for logs and journals — see the Log Viewer demo.

Engineered for scale · no weak links

The whole stack, one standard. Facts is one layer of a stack — store, network, and serialization — where every layer is tuned to the same bar. There’s no slow component quietly capping the rest, no glue code bleeding away the speed. The same engine scales from a Raspberry Pi to a server, and from one box to many.

capacity

Limits

Billions of records on a single box — the ceiling is your disk, not the engine, with optional retention caps that evict the oldest data automatically.

Up to ~16 million distinct series per shard, and a variable-size blob of up to 256 MiB per record.

scale out

Shards

Split a dataset into independent shards for parallel ingest and query. Throughput scales with cores — add shards, add speed — with no cross-shard coordination on the hot path.

on disk

Segments

Data is written in immutable, self-describing segments. Each one is independently checksummed and recoverable, so a single bad block never takes the dataset down.

stays up

Redundancy & failover

Built-in replication with veto-based failover: a stale replica can’t win an election, so two leaders can never exist — no split-brain, and a bounded, well-defined loss window. Break it yourself in the live demo.

crash-safe

Durability

A periodic checkpoint sets your maximum loss window, and every segment verifies its own integrity on open and repairs what it can — power loss doesn’t corrupt the store.

runs anywhere

Reach

One codebase, tuned down to the SIMD for Intel, AMD and ARM, on Windows and Linux — the same engine from a server rack to a $35 board.

See it live · demos running on the box

Every card is a real Facts engine serving real queries — not a screenshot.

live demo
Market Wall
A command-center wall ingesting synthetic market data, with queries running continuously against the live stream.
live demo
F1 Replay
A real Formula 1 race ingested once, then queried — point-in-time and whole-race aggregates in microseconds.
live demo
Log Viewer
Compressed blobs in action: a virtualized browser over a huge live log, reading only the visible window — including the unsealed tail.
live demo
Benchmarks
The full query suite run live — every API surface with its median and p99 latency, straight from the engine.
live demo
Replication & Failover
A two-node cluster you can break on purpose: cut the link, force a failover, watch it heal — no split-brain, bounded loss.
live demo
Raspberry Pi
The same engine on a $35 ARM board — small enough to run right where the data is born.
Head to head · Facts vs DuckDB

We put Facts against DuckDB — a fast in-process analytical engine — on real TSBS data (the standard time-series benchmark): the same 8.19-million-row dataset, on the same machine, warm. Facts ran on one core; DuckDB got all 32.

Ingesthigher is better
Facts · 1 core20 M/s
DuckDB · 32 cores2.3 M/s
8.7×faster
Latest value point query · lower is better
Facts · 1 core~0.2 µs
DuckDB · 32 cores~4.3 ms
~21,000×faster
High-CPU filter TSBS query · higher is better
Facts · 1 core107 M/s
DuckDB · 32 cores47 M/s
2.3×faster
Full-range aggregatelower is better
Facts · 1 core1.6 ms
DuckDB · 32 cores7.9 ms
4.9×faster
Columnar scan SIMD kernel · higher is better
Facts · 1 core66 GB/s
DuckDB · 32 cores7 GB/s
9.4×faster
Storage / pointlower is better · our honest loss
Facts96 B
DuckDB25 B
3.8×more

Medians from our open harness (Facts.Benchmarks) on real TSBS cpu-only data. DuckDB got every advantage: all cores, its fastest bulk-load (Parquet COPY) and a host index. Facts wins on one core everywhere except storage density — DuckDB compresses; Facts keeps data raw and memory-mapped for speed. Honest trade, stated plainly.

† Facts supports state-of-the-art compression on blob payloads but keeps column data uncompressed — a deliberate trade: the hot columnar path stays raw and memory-mapped for SIMD-speed scans, while bulky blob data still packs down.

Head to head · over the wire · Facts vs QuestDB & InfluxDB

The test above was in-process. This one is over the wire — a real client/server database, where every query travels across a network connection and the answer is serialized back. That’s how you actually run QuestDB and InfluxDB, two of the most popular purpose-built time-series databases. Same 8.19-million-row TSBS dataset, same machine (Ryzen 9 9950X), loopback, warm, durability matched.

Here’s the kicker: Facts used a single connection. We gave the rivals their fastest setup — eight parallel connections each — because Facts doesn’t get faster with more (one is already enough). It still wins every speed test, often by a wide margin.

Ingesthigher is better
Facts · 1 conn24.6 M/s
QuestDB · 81.65 M/s
InfluxDB · 80.24 M/s
15×Quest102×Influxfaster
Latest value point query · lower is better
Facts · 1 conn39 µs
QuestDB · 8260 µs
InfluxDB · 856 ms
6.7×Quest~1,400×Influxfaster
Range read one window · lower is better
Facts · 1 conn0.25 ms
QuestDB · 81.15 ms
InfluxDB · 836 ms
4.6×Quest144×Influxfaster
High-CPU filter TSBS query · lower is better
Facts · 1 conn5.2 ms
QuestDB · 8105 ms
InfluxDB · 8846 ms
20×Quest163×Influxfaster
Storage / pointat rest · lower is better · our honest loss
Facts96 B
QuestDB~23 B
InfluxDB~86 B
4.2×Quest1.1×Influxmore

What that means. On ingest, Facts is about an order of magnitude faster than QuestDB and two orders of magnitude faster than InfluxDB; the high-CPU scan widens the gap further. And the point query — “what’s the latest reading for each sensor,” the single most common dashboard query — comes back in tens of microseconds. Facts answers before a typical network round-trip would even finish. (Exact figures shown above.)

Medians + p99 from our open harness (Facts.Benchmarks, --tier b) on real TSBS cpu-only data; each engine shown at its best configuration. Why the gap? Facts speaks a compact binary wire format; QuestDB and InfluxDB use text line protocols — every number is spelled out as ASCII and re-parsed, a tax that dominates at millions of rows per second. Facts’ ingest tops out at one connection because a single server thread is already saturating the link; the rivals genuinely need the extra connections to reach the numbers shown. These speeds are with full durability: re-run with every engine writing to a real NVMe SSD instead of RAM, Facts held at 25 M rows/s — flushing to disk is essentially free for it. The honest loss is storage density: at rest on disk, QuestDB (~23 B/point) and InfluxDB (~86 B) compress their columns; Facts keeps data raw and memory-mapped at ~96 B — the same speed-for-size trade we make against DuckDB. Both rivals are also full query languages (SQL / Flux, joins, ad-hoc) with far bigger ecosystems. InfluxDB’s v2/Flux engine is additionally known to be slow on these access patterns; its newer v3 would narrow the query gap.

Live showcase · benchmark dashboard
Facts live showcase and benchmark dashboard
Verification & benchmarks · full run
loading…