Benchmark
Capacity, in hard numbers
Measured, not projected: 10,000 sensors, each reporting once a minute, on a single
server. The benchmark ships with the product, so every figure below can be
re-produced on your own hardware.
The machine behind every number on this page: an Intel Core i9-14900KF (24 cores),
64 GB RAM and NVMe SSDs, running Windows 11 with PostgreSQL in Docker —
the database, the backend services and the benchmark client all on this one
server. No cluster, no separate database host, nothing tuned beyond the
stock container configuration.
Taking it in
Before anything is written down it has to arrive. Measured on the same server with the
live-ingestion benchmark that ships with the product: 10,000 sensors reporting
ten times a second — 12 million readings per run — through the real
MQTT, Kafka and HTTP services, into the shared buffer and on into storage, every run
checked reading by reading against what was sent. Every transport accepts readings in
batches (a JSON array of readings per message, or the ingest-batch route
over HTTP), and that shape decides the number: a fleet of 10,000 sensors at 10 Hz is
100,000 readings a second, and one ingestion instance takes it with room to spare.
| Gateways sending batches |
~430,000 readings/s |
One ingestion instance, one buffer node. A gateway flushing a second of its sensors’ samples per message — 12 million readings taken in under 30 seconds, none lost |
| Many sensors per message, one reading each |
~120,000 readings/s |
A polling gateway’s natural shape — still one instance, one buffer node |
| One reading per message |
~80,000 readings/s |
Devices that publish as they sample, over Kafka — the ceiling of a single buffer node; the buffer is built to spread over more |
| Readings lost across every run |
0 |
Counts, sums and sampled minutes matched the generator exactly — in the buffer, and in the database afterwards |
Writing it down
| Readings per month |
432,000,000 |
10,000 sensors × one reading per minute, full density |
| Sustained write throughput |
~134,000 readings/s |
The production storage path, flat for hours — no degradation as history accumulates |
| Long-term storage per month |
≈5.3 GiB |
Full-resolution history, compressed at month close |
| One year of history |
≈64 GiB |
Growth is linear — sizing a year ahead is multiplication |
| Working area, current month |
≈12 GiB |
Finished days are compacted in the background, so the working area stays a couple of days deep instead of growing all month |
Reading it back
The other half of the story: how fast readings come back out. Same fleet, same single
server, measured against the product’s real query API with every response fully
downloaded — 3.4 million requests, not one error.
| Live values on screen |
~57,000 requests/s |
Each request fetches ten sensors’ newest values — over half a million live values per second, typical answer in 8 ms |
| One sensor, one day, charted |
~1,390 charts/s |
A day of minute-level history answers in ~47 ms — even in the month still being written |
| A month across five sensors |
~350 charts/s |
A point per sensor per day, precomputed as each day is compacted — the month still being written answers in ~46 ms |
| A month summarised per sensor |
~4,200 summaries/s |
Minimum, maximum, average and count over a closed month, typically back in ~15 ms |
| Errors across the whole sweep |
0 |
3,406,032 requests at up to 512 parallel clients — every response complete |
Keeping it up
Speed for a minute is one thing; the question a sceptic asks is how long it keeps going and whether anything goes missing. So the same server was run for three hours straight: 10,000 sensors reporting ten times a second, plus 2,000 more over MQTT and HTTP — about 102,000 readings a second, steadily — while a busy console kept asking it questions the whole time. Afterwards, every sensor was read back minute by minute and compared with what had been sent.
| Readings sent in three hours |
1,101,600,000 |
None failed to send; the producers never fell behind |
| Readings read back, exact |
1,101,600,000 |
Every one of 12,000 sensors, every minute, count and sum identical to what was sent |
| Console requests meanwhile |
1,241,199 · 0 errors |
Live values, charts and Insights questions, ~115 a second; typical answer 3 ms for live values, 13 ms for a chart — the same in the last hour as in the first |
| Memory after three hours |
the same as after five minutes |
Nothing grew in any of the three services |
During those three hours the day being written was compacted into its long-term form ten times, underneath the live stream, without a single reading going missing across any of it.
Head-to-head: TimescaleDB — same machine, same data, same questions
A second benchmark, run for this page: 2,000 sensors × 30 days of per-minute aggregates
— 86.4 million rows with identical values — ingested into LandauOne's engine and
into TimescaleDB (latest, PostgreSQL 17, compression on, segmented by sensor), each
through its own production path: LandauOne's deduplicating upsert against TimescaleDB's
binary COPY. Same machine as above, both databases in Docker at stock configuration,
the client in-process on the same host, HTTP excluded on both sides. Before anything
was timed, both systems were asked the same questions and had to return
identical answers — they did, to the digit. The harness ships in the
repository (CompareBench), so every row below is reproducible.
| Ingest, 86.4M rows |
127,000 rows/s |
TimescaleDB: 1,290,000 rows/s — TimescaleDB 915% faster (10×). Raw COPY against an upsert that deduplicates as it lands. |
| Sealing the month (fold vs compress) |
2 min 57 s |
TimescaleDB: 41 s — TimescaleDB 331% faster. LandauOne's seal also precomputes every summary and percentile below. |
| Storage, sealed month |
1.11 GiB |
TimescaleDB: 1.43 GiB — LandauOne 22% smaller, summaries included. |
| Whole-month average, one sensor |
0.8 ms |
TimescaleDB: 2.9 ms — LandauOne 276% faster |
| Hour buckets over a month (720 points), one sensor |
21.2 ms |
TimescaleDB: 5.0 ms — TimescaleDB 325% faster. LandauOne pays a flat cost to open the whole month cube; Timescale scans one sensor's segment. |
| Day buckets over a month (30 points), one sensor |
21.0 ms |
TimescaleDB: 4.1 ms — TimescaleDB 418% faster, same reason as above. |
| Whole-month P95 (count-weighted), one sensor |
0.8 ms |
TimescaleDB: 30.0 ms — LandauOne 3,706% faster (37×). Precomputed at the seal against ranked at read time. |
| Per-day P95 over a month (30 points), one sensor |
35.0 ms |
TimescaleDB: 49.1 ms — LandauOne 40% faster |
| Whole-month average, 100 sensors |
64.8 ms |
TimescaleDB: 65.5 ms — even (100 sequential summary reads against one grouped scan) |
| Whole-month P95, 100 sensors |
53.1 ms |
TimescaleDB: 5.53 s — LandauOne 10,330% faster (104×). The gap that grows with the fleet. |
What the numbers mean — and what they cost
Where LandauOne is ahead
Historical statistics are precomputed as each day and month is compacted, so a
month's average, median or P95 is a row read instead of a scan — 276% faster for an
average, 37× for a single P95, 104× for a hundred sensors' P95s, and the gap widens
with history because a summarised answer does not get more expensive as the data
behind it grows. The same month takes 22% less disk, summaries included, and the
percentiles, spike envelopes, coverage and meter deltas arrive as product features
— charted, alerted on, reported and emailed — not as SQL you write and maintain.
Where TimescaleDB is ahead
TimescaleDB is a general-purpose database, and that generality is real: any SQL
over your raw rows, joins against your own tables, sub-minute timestamps, and a
large ecosystem that speaks to it. Its bulk ingest is roughly 10× faster (a raw
COPY against LandauOne's deduplicating upsert), its compression pass is 4× quicker
than LandauOne's richer seal, and single-sensor bucket charts over a sealed month
come back 4–5× sooner. LandauOne trades that generality away deliberately: its
query surface is its API — the aggregations on this page, at minute resolution and
above — and its statistics set is fixed at what the seal precomputes. If your
questions are open-ended SQL, Timescale is the right tool; if they are the
questions an operations team actually asks of sensors, this engine answers them
faster, from less disk, with the console included.