Benchmark
Capacidad, en cifras concretas
Medido, no proyectado: 10 000 sensores, cada uno informando una vez por minuto, en un
solo servidor. El benchmark se entrega con el producto, así que cada cifra de abajo
puede reproducirse en su propio hardware.
La máquina detrás de cada número de esta página: un Intel Core i9-14900KF
(24 núcleos), 64 GB de RAM y SSD NVMe con Windows 11, PostgreSQL en
Docker — la base de datos, los servicios backend y el cliente del benchmark,
todos en este único servidor. Sin clúster, sin host de base de datos
separado, nada ajustado más allá de la configuración estándar de los contenedores.
Recibir
Antes de escribirse, una lectura tiene que llegar. Medido en el mismo servidor con el
benchmark de ingesta en vivo que se entrega con el producto: 10 000 sensores
reportando diez veces por segundo — 12 millones de lecturas por
ejecución — a través de los servicios reales de MQTT, Kafka y HTTP, hacia el búfer
compartido y de ahí al almacenamiento, cada ejecución comprobada lectura a lectura
contra lo enviado. Todos los transportes aceptan lecturas por lotes (un array JSON de
lecturas por mensaje, o la ruta ingest-batch por HTTP), y esa forma es la
que decide la cifra: una flota de 10 000 sensores a 10 Hz son 100 000 lecturas por
segundo, y una sola instancia de ingesta las absorbe con margen.
| Pasarelas que envían lotes |
~430 000 lecturas/s |
Una instancia de ingesta, un nodo de búfer. Una pasarela que vacía cada segundo las muestras de sus sensores en un mensaje — 12 millones de lecturas recibidas en menos de 30 segundos, ninguna perdida |
| Muchos sensores por mensaje, una lectura cada uno |
~120 000 lecturas/s |
La forma natural de una pasarela que consulta sus sensores — sigue siendo una instancia, un nodo de búfer |
| Una lectura por mensaje |
~80 000 lecturas/s |
Dispositivos que publican según muestrean, por Kafka — el techo de un solo nodo de búfer; el búfer está construido para repartirse entre varios |
| Lecturas perdidas en todas las ejecuciones |
0 |
Recuentos, sumas y minutos muestreados idénticos al generador, hasta el último dígito — en el búfer y después en la base de datos |
Escribir
| Lecturas al mes |
432 000 000 |
10 000 sensores × una lectura por minuto, densidad completa |
| Caudal de escritura sostenido |
~134 000 lecturas/s |
La ruta de almacenamiento de producción, plana durante horas — sin degradación a medida que se acumula el historial |
| Almacenamiento de largo plazo al mes |
≈5,3 GiB |
Historial a resolución completa, comprimido al cierre de mes |
| Un año de historial |
≈64 GiB |
El crecimiento es lineal — dimensionar un año por adelantado es una multiplicación |
| Área de trabajo, mes en curso |
≈12 GiB |
Los días terminados se compactan en segundo plano — el área de trabajo se mantiene a un par de días de profundidad en vez de crecer todo el mes |
Releer
La otra mitad de la historia: la velocidad a la que las lecturas vuelven a salir. La
misma flota, el mismo servidor único, medido contra la API de consulta real del
producto, con cada respuesta descargada por completo — 3,4 millones de peticiones, ni
un solo error.
| Valores en vivo en pantalla |
~57 000 peticiones/s |
Cada petición trae los valores más recientes de diez sensores — más de medio millón de valores en vivo por segundo, respuesta típica en 8 ms |
| Un sensor, un día, en gráfico |
~1 390 gráficos/s |
Un día de historial a resolución de minuto responde en ~47 ms — incluso en el mes que aún se está escribiendo |
| Un mes sobre cinco sensores |
~350 gráficos/s |
Un punto por sensor y día, precalculado al compactar cada jornada — el mes en curso responde en ~46 ms |
| Un mes resumido por sensor |
~4 200 resúmenes/s |
Mínimo, máximo, promedio y recuento de un mes cerrado, típicamente en ~15 ms |
| Errores en todo el barrido |
0 |
3 406 032 peticiones con hasta 512 clientes en paralelo — cada respuesta completa |
Aguantar
La velocidad durante un minuto es una cosa; la pregunta de un escéptico es cuánto tiempo aguanta y si se pierde algo por el camino. Así que el mismo servidor funcionó tres horas seguidas: 10.000 sensores reportando diez veces por segundo, más otros 2.000 por MQTT y HTTP — unas 102.000 lecturas por segundo, de forma constante — mientras una consola ocupada le hacía preguntas todo el tiempo. Después, cada sensor se releyó minuto a minuto y se comparó con lo enviado.
| Lecturas enviadas en tres horas |
1.101.600.000 |
Ninguna falló al enviarse; los productores nunca se quedaron atrás |
| Lecturas releídas, exactas |
1.101.600.000 |
Cada uno de los 12.000 sensores, cada minuto, recuento y suma idénticos a lo enviado |
| Peticiones de la consola mientras tanto |
1.241.199 · 0 errores |
Valores en vivo, gráficos y preguntas de Análisis, ~115 por segundo; respuesta típica 3 ms para valores en vivo, 13 ms para un gráfico — iguales en la última hora y en la primera |
| Memoria tras tres horas |
la misma que tras cinco minutos |
Nada creció en ninguno de los tres servicios |
Durante esas tres horas, el día que se estaba escribiendo se compactó diez veces en su forma de largo plazo, por debajo del flujo en vivo, sin que se perdiera una sola lectura.
Cara a cara: TimescaleDB — la misma máquina, los mismos datos, las mismas preguntas
Un segundo benchmark, ejecutado para esta página: 2 000 sensores × 30 días de agregados
por minuto — 86,4 millones de filas con valores idénticos — ingeridos en el motor
de LandauOne y en TimescaleDB (última versión, PostgreSQL 17, compresión activada,
segmentado por sensor), cada uno por su propia ruta de producción: el upsert
deduplicador de LandauOne frente al COPY binario de TimescaleDB. La misma máquina de
arriba, ambas bases de datos en Docker con configuración estándar, el cliente en el
mismo host y dentro del mismo proceso, HTTP excluido en ambos lados. Antes de
cronometrar nada, a los dos sistemas se les hicieron las mismas preguntas y tenían que
devolver respuestas idénticas — lo hicieron, dígito a dígito. El
arnés se entrega en el repositorio (CompareBench), así que cada fila de
abajo es reproducible.
| Ingesta, 86,4 millones de filas |
127 000 filas/s |
TimescaleDB: 1 290 000 filas/s — TimescaleDB 915 % más rápido (10×). Un COPY en bruto frente a un upsert que deduplica según llegan los datos. |
| Sellar el mes (compactación frente a compresión) |
2 min 57 s |
TimescaleDB: 41 s — TimescaleDB 331 % más rápido. El sellado de LandauOne además precalcula todos los resúmenes y percentiles de abajo. |
| Almacenamiento, mes sellado |
1,11 GiB |
TimescaleDB: 1,43 GiB — LandauOne un 22 % más compacto, resúmenes incluidos. |
| Promedio del mes completo, un sensor |
0,8 ms |
TimescaleDB: 2,9 ms — LandauOne 276 % más rápido |
| Cubos por hora sobre un mes (720 puntos), un sensor |
21,2 ms |
TimescaleDB: 5,0 ms — TimescaleDB 325 % más rápido. LandauOne paga un coste fijo por abrir el cubo del mes entero; Timescale recorre solo el segmento de ese sensor. |
| Cubos por día sobre un mes (30 puntos), un sensor |
21,0 ms |
TimescaleDB: 4,1 ms — TimescaleDB 418 % más rápido, por la misma razón de arriba. |
| P95 del mes completo (ponderado por recuento), un sensor |
0,8 ms |
TimescaleDB: 30,0 ms — LandauOne 3 706 % más rápido (37×). Precalculado en el sellado frente a ordenado en el momento de la lectura. |
| P95 por día sobre un mes (30 puntos), un sensor |
35,0 ms |
TimescaleDB: 49,1 ms — LandauOne 40 % más rápido |
| Promedio del mes completo, 100 sensores |
64,8 ms |
TimescaleDB: 65,5 ms — empate (100 lecturas secuenciales de resúmenes frente a un único barrido agrupado) |
| P95 del mes completo, 100 sensores |
53,1 ms |
TimescaleDB: 5,53 s — LandauOne 10 330 % más rápido (104×). La brecha que crece con la flota. |
Qué significan las cifras — y qué cuestan
Dónde LandauOne va por delante
Las estadísticas históricas se precalculan al compactar cada día y cada mes, de
modo que el promedio, la mediana o el P95 de un mes son una lectura de fila en vez
de un barrido — 276 % más rápido para un promedio, 37× para un único P95, 104×
para los P95 de cien sensores, y la brecha se amplía con el historial porque una
respuesta resumida no se encarece a medida que crecen los datos que hay detrás. El
mismo mes ocupa un 22 % menos de disco, resúmenes incluidos, y los percentiles,
las envolventes de picos, la cobertura y los deltas de contadores llegan como
funciones del producto — graficados, con alertas, en informes y por correo — no
como SQL que usted escribe y mantiene.
Dónde TimescaleDB va por delante
TimescaleDB es una base de datos de propósito general, y esa generalidad es real:
cualquier SQL sobre sus filas en bruto, joins contra sus propias tablas, marcas de
tiempo por debajo del minuto y un gran ecosistema que sabe hablar con ella. Su
ingesta masiva es unas 10× más rápida (un COPY en bruto frente al upsert
deduplicador de LandauOne), su pasada de compresión es 4× más veloz que el sellado
más rico de LandauOne, y los gráficos por cubos de un solo sensor sobre un mes
sellado vuelven 4–5× antes. LandauOne renuncia a esa generalidad de forma
deliberada: su superficie de consulta es su API — las agregaciones de esta página,
a resolución de minuto y superior — y su conjunto de estadísticas queda fijado en
lo que el sellado precalcula. Si sus preguntas son SQL abierto, Timescale es la
herramienta correcta; si son las preguntas que un equipo de operaciones realmente
hace a sus sensores, este motor las responde más rápido, con menos disco y con la
consola incluida.