Benchmark
La capacità, in numeri concreti
Misurata, non proiettata: 10.000 sensori, ognuno con una lettura al minuto, su un
singolo server. Il benchmark è incluso nel prodotto, così ogni cifra qui sotto può
essere riprodotta sul tuo hardware.
La macchina dietro ogni numero di questa pagina: un Intel Core i9-14900KF
(24 core), 64 GB di RAM e SSD NVMe con Windows 11, PostgreSQL in
Docker — il database, i servizi backend e il client del benchmark, tutti su
questo unico server. Nessun cluster, nessun host di database separato,
nulla di ottimizzato oltre la configurazione standard dei container.
Ricevere
Prima di essere scritta, una lettura deve arrivare. Misurato sullo stesso server con il
benchmark di ingestione dal vivo incluso nel prodotto: 10.000 sensori che riportano
dieci volte al secondo — 12 milioni di letture per esecuzione —
attraverso i veri servizi MQTT, Kafka e HTTP, nel buffer condiviso e poi nello storage,
ogni esecuzione verificata lettura per lettura rispetto a quanto inviato. Ogni trasporto
accetta le letture a lotti (un array JSON di letture per messaggio, o la route
ingest-batch via HTTP), ed è questa forma a decidere la cifra: una flotta di
10.000 sensori a 10 Hz sono 100.000 letture al secondo, e una sola istanza di
ingestione le assorbe con margine.
| Gateway che inviano lotti |
~430.000 letture/s |
Un’istanza di ingestione, un nodo di buffer. Un gateway che svuota ogni secondo i campioni dei suoi sensori in un messaggio — 12 milioni di letture ricevute in meno di 30 secondi, nessuna persa |
| Molti sensori per messaggio, una lettura ciascuno |
~120.000 letture/s |
La forma naturale di un gateway che interroga i suoi sensori — sempre un’istanza, un nodo di buffer |
| Una lettura per messaggio |
~80.000 letture/s |
Dispositivi che pubblicano mentre campionano, via Kafka — il limite di un singolo nodo di buffer; il buffer è costruito per distribuirsi su più nodi |
| Letture perse in tutte le esecuzioni |
0 |
Conteggi, somme e minuti campionati identici al generatore, alla cifra — nel buffer, e poi nel database |
Scrivere
| Letture al mese |
432.000.000 |
10.000 sensori × una lettura al minuto, densità piena |
| Portata di scrittura sostenuta |
~134.000 letture/s |
Il percorso di storage di produzione, piatto per ore — nessun degrado man mano che lo storico si accumula |
| Storage a lungo termine al mese |
≈5,3 GiB |
Storico a piena risoluzione, compresso a fine mese |
| Un anno di storico |
≈64 GiB |
La crescita è lineare — dimensionare con un anno di anticipo è una moltiplicazione |
| Area di lavoro, mese corrente |
≈12 GiB |
I giorni conclusi vengono compattati in background — l'area di lavoro resta profonda un paio di giorni invece di crescere per tutto il mese |
Rileggere
L'altra metà della storia: quanto in fretta le letture tornano fuori. Stessa flotta,
stesso singolo server, misurato contro la vera API di interrogazione del prodotto, ogni
risposta scaricata per intero — 3,4 milioni di richieste, nemmeno un errore.
| Valori live sullo schermo |
~57.000 richieste/s |
Ogni richiesta preleva i valori più recenti di dieci sensori — oltre mezzo milione di valori live al secondo, risposta tipica in 8 ms |
| Un sensore, un giorno, in grafico |
~1.390 grafici/s |
Un giorno di storico al minuto risponde in ~47 ms — anche nel mese ancora in scrittura |
| Un mese su cinque sensori |
~350 grafici/s |
Un punto per sensore al giorno, precalcolato quando ogni giornata viene compattata — il mese in corso risponde in ~46 ms |
| Un mese riassunto per sensore |
~4.200 riassunti/s |
Minimo, massimo, media e conteggio su un mese chiuso, tipicamente in ~15 ms |
| Errori nell'intera prova |
0 |
3.406.032 richieste con fino a 512 client in parallelo — ogni risposta completa |
Reggere nel tempo
La velocità per un minuto è una cosa; la domanda di uno scettico è per quanto tempo regge e se qualcosa va perso. Così lo stesso server ha girato per tre ore di fila: 10.000 sensori che riportano dieci volte al secondo, più altri 2.000 via MQTT e HTTP — circa 102.000 letture al secondo, costanti — mentre una console molto attiva gli faceva domande per tutto il tempo. Dopo, ogni sensore è stato riletto minuto per minuto e confrontato con ciò che era stato inviato.
| Letture inviate in tre ore |
1.101.600.000 |
Nessuna ha fallito l’invio; i produttori non sono mai rimasti indietro |
| Letture rilette, esatte |
1.101.600.000 |
Ognuno dei 12.000 sensori, ogni minuto, conteggio e somma identici a quanto inviato |
| Richieste della console nel frattempo |
1.241.199 · 0 errori |
Valori live, grafici e domande di Analisi, ~115 al secondo; risposta tipica 3 ms per i valori live, 13 ms per un grafico — uguali nell’ultima ora e nella prima |
| Memoria dopo tre ore |
la stessa di dopo cinque minuti |
Niente è cresciuto in nessuno dei tre servizi |
In quelle tre ore il giorno in scrittura è stato compattato dieci volte nella sua forma a lungo termine, sotto il flusso live, senza che una sola lettura andasse persa.
Confronto diretto: TimescaleDB — stessa macchina, stessi dati, stesse domande
Un secondo benchmark, eseguito per questa pagina: 2.000 sensori × 30 giorni di aggregati
al minuto — 86,4 milioni di righe con valori identici — ingeriti nel motore di
LandauOne e in TimescaleDB (ultima versione, PostgreSQL 17, compressione attiva,
segmentata per sensore), ciascuno attraverso il proprio percorso di produzione: l'upsert
deduplicante di LandauOne contro il COPY binario di TimescaleDB. Stessa macchina di cui
sopra, entrambi i database in Docker a configurazione standard, il client in-process
sullo stesso host, HTTP escluso da entrambe le parti. Prima di cronometrare qualsiasi
cosa, ai due sistemi sono state poste le stesse domande e dovevano restituire
risposte identiche — lo hanno fatto, alla cifra. L'harness è incluso nel
repository (CompareBench), quindi ogni riga qui sotto è riproducibile.
| Ingestione, 86,4 mln di righe |
127.000 righe/s |
TimescaleDB: 1.290.000 righe/s — TimescaleDB più veloce del 915 % (10×). Un COPY grezzo contro un upsert che deduplica mentre i dati arrivano. |
| Sigillare il mese (ripiegatura contro compressione) |
2 min 57 s |
TimescaleDB: 41 s — TimescaleDB più veloce del 331 %. La sigillatura di LandauOne precalcola anche ogni riassunto e percentile qui sotto. |
| Storage, mese sigillato |
1,11 GiB |
TimescaleDB: 1,43 GiB — LandauOne più compatto del 22 %, riassunti inclusi. |
| Media sull'intero mese, un sensore |
0,8 ms |
TimescaleDB: 2,9 ms — LandauOne più veloce del 276 % |
| Passi orari su un mese (720 punti), un sensore |
21,2 ms |
TimescaleDB: 5,0 ms — TimescaleDB più veloce del 325 %. LandauOne paga un costo fisso per aprire l'intero cubo del mese; Timescale scansiona il segmento di un solo sensore. |
| Passi giornalieri su un mese (30 punti), un sensore |
21,0 ms |
TimescaleDB: 4,1 ms — TimescaleDB più veloce del 418 %, per la stessa ragione di cui sopra. |
| P95 sull'intero mese (pesato sui conteggi), un sensore |
0,8 ms |
TimescaleDB: 30,0 ms — LandauOne più veloce del 3.706 % (37×). Precalcolato alla sigillatura contro un ordinamento al momento della lettura. |
| P95 per giorno su un mese (30 punti), un sensore |
35,0 ms |
TimescaleDB: 49,1 ms — LandauOne più veloce del 40 % |
| Media sull'intero mese, 100 sensori |
64,8 ms |
TimescaleDB: 65,5 ms — pari (100 letture sequenziali di riassunti contro una sola scansione raggruppata) |
| P95 sull'intero mese, 100 sensori |
53,1 ms |
TimescaleDB: 5,53 s — LandauOne più veloce del 10.330 % (104×). Il divario che cresce con la flotta. |
Cosa significano i numeri — e cosa costano
Dove LandauOne è avanti
Le statistiche storiche vengono precalcolate man mano che ogni giorno e ogni mese
viene compattato, così la media, la mediana o il P95 di un mese è la lettura di una
riga invece di una scansione — il 276 % più veloce per una media, 37× per un singolo
P95, 104× per i P95 di cento sensori, e il divario si allarga con lo storico, perché
una risposta riassunta non diventa più costosa man mano che i dati dietro di essa
crescono. Lo stesso mese occupa il 22 % di disco in meno, riassunti inclusi, e i
percentili, gli inviluppi dei picchi, la copertura e i delta dei contatori arrivano
come funzioni del prodotto — in grafico, sotto avviso, nei report e via email — non
come SQL che scrivi e mantieni tu.
Dove TimescaleDB è avanti
TimescaleDB è un database generalista, e quella generalità è reale: qualsiasi SQL
sulle tue righe grezze, join con le tue tabelle, timestamp sotto il minuto e un
vasto ecosistema che gli parla. Il suo ingest massivo è circa 10× più veloce (un
COPY grezzo contro l'upsert deduplicante di LandauOne), il suo passaggio di
compressione è 4× più rapido della sigillatura più ricca di LandauOne, e i grafici a
passi di un singolo sensore su un mese sigillato tornano 4–5× prima. LandauOne cede
quella generalità di proposito: la sua superficie di interrogazione è la sua API —
le aggregazioni di questa pagina, a risoluzione al minuto e superiore — e il suo
insieme di statistiche è fissato a ciò che la sigillatura precalcola. Se le tue
domande sono SQL a risposta aperta, Timescale è lo strumento giusto; se sono le
domande che un team operativo pone davvero ai sensori, questo motore risponde più in
fretta, da meno disco, con la console inclusa.