LandauOne

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.

Against the usual alternative

LandauOne versus TimescaleDB + Grafana

The head-to-head above compares engines. The comparison people actually make is with the stack they would otherwise assemble — a time-series database plus a dashboard tool — so here is that one, plainly.

What Timescale + Grafana gives you

A very good database and a very good chart tool. Everything between a broker and a chart is yours to build and run: the MQTT, Kafka, Service Bus and Event Hubs consumers, field mapping per producer, timestamp validation, duplicate suppression, loss accounting, retention, the alert rules, user sign-in and per-user ownership, sharing, the registry of what should be reporting, reports and their mailing, an audit trail — and the SQL behind every statistic, written, reviewed and maintained by your team.

What LandauOne gives you

The whole product: the ingestion front door for those brokers with validation, deduplication and counted losses; the store with its precomputed statistics; and the console — sixteen modules from dashboards, maps, floor plans and live cameras to alerts, sensor health, reports, audit, storage and the two ingestion monitors. The statistics that took 37× and 104× longer to rank on the other side are a row read here, and they arrive as features: charted, alerted on, reported, mailed, and asked about in Insights.

Where the other side is ahead

Open-ended SQL over raw rows, joins against your own tables, sub-minute timestamps kept verbatim, a 10× faster bulk load, and a large ecosystem of plug-ins. If your questions are ad-hoc SQL, build the stack. If they are the questions an operations team asks of sensors every day, LandauOne answers them faster, from less disk, with nothing to assemble.

What you are not assembling

Ingestion, validation, deduplication, retention, alerting, sign-in, sharing, reporting, audit, maps that work offline, camera access behind sign-in, and the monitors that tell you what arrived — each a project of its own on the other side, each already here and measured.