Inicio / Blog / Almacenamiento temporal
Arquitectura de datos para IoT

Bases de datos de series temporales para IoT: ¿Supabase/Postgres, InfluxDB o SQLite?

Que un ESP32 envíe la temperatura cada minuto no constituye un benchmark de base de datos. La decisión depende de dónde llegan las lecturas, quién las consulta, durante cuánto tiempo son útiles y con qué deben relacionarse: inventario, mantenimiento, clientes o eventos de control. PostgreSQL, InfluxDB y SQLite almacenan observaciones con marca de tiempo, pero responden a escenarios operativos distintos.

Empieza por el recorrido de los datos, no por la marca

Separa el búfer de borde, la ingesta, el almacenamiento duradero y las consultas del panel
1 / MedirEl dispositivo envía valor, unidad, hora del evento y secuencia.
2 / AlmacenarLa pasarela conserva lotes limitados durante una interrupción.
3 / IngerirValida identidad, esquema y clave contra duplicados.
4 / ConsultarAgrupa por equipo, sitio e intervalo temporal.

Documenta tasa de ingesta, picos, eventos tardíos, ventanas de consulta, niveles de retención, límites entre clientes, tiempo offline y objetivo de recuperación. Calcula bytes por fila incluyendo índices y metadatos, no solo el payload. Mil equipos muestreando una vez por minuto generan unos 1,44 millones de puntos diarios antes de reintentos e índices. Sirve para planificar, pero no demuestra que haga falta una base especializada.

Tres herramientas, tres formas de operar

OpciónBuen encajeCompromisosPrimera opción cuando...
PostgreSQL, también gestionado en SupabaseTelemetría relacionada con clientes y equipos; SQL, transacciones, políticas de acceso y una base para la aplicación.Índices y consultas, crecimiento del almacenamiento, vacuum, retención y mantenimiento de particiones si el volumen lo exige.Contexto relacional y flexibilidad SQL importan más que un flujo especializado.
InfluxDBIngesta temporal, consultas por intervalos y retención mediante buckets.Diseño de esquema y cardinalidad, modelo de consulta y migración según versión.La telemetría es la carga principal y el modelo encaja con equipo y despliegue.
SQLite en una pasarelaBúfer local duradero, equipo offline, colector de un host o instalación pequeña.Un escritor a la vez en WAL, acceso en el mismo host, checkpoints, copias y sincronización posterior.Los datos deben persistir localmente durante una caída de red y un proceso puede controlar las escrituras.

Supabase es una plataforma gestionada de Postgres, no otro motor de series temporales. La disponibilidad de extensiones depende de la versión: Supabase indica que TimescaleDB está obsoleto en proyectos con Postgres 17 y dirige a quienes usan hypertables hacia particionamiento nativo con pg_partman. Verifica la versión principal y la ruta de migración admitida antes de seguir tutoriales antiguos.

Postgres: el contexto relacional sí aporta valor

Una tabla normal suele bastar para empezar. Un esquema básico puede usar device_id, observed_at (timestamptz), received_at, sequence_no, metric, value, unit y schema_version; la clave debe hacer idempotente cada punto. Indexa equipo y hora descendente solo si coincide con filtros reales del panel.

Separa la hora del evento de la recepción en el servidor y usa timestamps con zona horaria. En producción, valida pares métrica/unidad, limita payloads y aplica autorización por cliente en la API o la base. Cada índice adicional consume espacio y trabajo de escritura. Particiona por tiempo solo cuando las mediciones demuestren que la poda, el borrado por retención o la operación compensan el mantenimiento. PostgreSQL sitúa el particionamiento sobre todo en tablas grandes y patrones compatibles, no como acelerador automático.

La ventaja relacional es concreta: un gráfico puede unir la lectura con el sitio, cliente, calibración o mantenimiento sin repetir esos datos en cada punto. Agrega a la resolución del panel; no envíes millones de lecturas al navegador esperando que la librería resuelva el almacenamiento.

InfluxDB: diseña las series con intención

InfluxDB distingue timestamp, measurement, tags y fields. En el modelo documentado de 2.x, los tags están indexados y los fields no. Usa tags para dimensiones estables que filtras; no conviertas valores únicos o cambiantes en tags sin analizar la cardinalidad. Un ID de equipo puede servir en una flota acotada, pero valida el crecimiento y la guía de la versión desplegada.

Los buckets de InfluxDB 2.x combinan organización y reglas de retención. InfluxDB 3 es la generación actual y difiere en arquitectura y consultas. No copies una receta de bucket/Flux de v2 a v3 sin comprobar compatibilidad, edición, alojamiento, autenticación, backups, bibliotecas y actualización.

SQLite: búfer fiable en el borde, no base compartida por red

En una pasarela sin conexión, SQLite guarda lotes y los envía al volver la red. Write-Ahead Logging permite lectores y un escritor a la vez, pero solo admite un escritor simultáneo. WAL requiere memoria compartida en el mismo host y no está pensado para sistemas de archivos de red. Asigna la ingesta a un proceso, agrupa transacciones, vigila el disco, planifica checkpoints y copias, y prueba recuperación tras cortes en el hardware real. Usa una versión con las correcciones relevantes.

Al reconectar, el endpoint remoto debe ser idempotente para aceptar reenvíos sin duplicados. Conserva un cursor o acuse local duradero para que un reinicio no descarte lotes en silencio. Define qué ocurre al llenarse el disco: pausar, descartar solo datos secundarios explícitos o mantener resúmenes y alertar. Sobrescribir sin aviso no es una política de retención.

Retención y reducción de resolución son decisiones de producto

Conserva datos brutos de alta resolución solo el tiempo que exija un caso real, una norma o una investigación. Vibración bruta durante días, resúmenes horarios durante meses y mantenimiento por más tiempo son ejemplos, no plazos universales. Guarda método de agregación, cantidad de muestras, mínimo/máximo y unidades para que una media no borre una alarma breve. Define el tratamiento de eventos tardíos y correcciones auditables.

Prueba una carga representativa

Reproduce la misma carga sintética o autorizada en cada candidato. Mantén comparables hardware, red, esquema, retención, índices, lotes y consultas. Mide retraso de ingesta, p95 del panel, crecimiento, CPU/memoria, recuperación, restauración de copias y esfuerzo operativo. Incluye ventanas recientes y antiguas, agregados de flota, eventos desordenados y aislamiento entre clientes. Publica carga y esquema junto con resultados: una tasa de escritura aislada no es un benchmark reutilizable.

Mantén reversible la migración

Define un contrato por evento: ID lógico, métrica, unidad, versión del esquema, hora del evento y de recepción y clave idempotente. Así se puede escribir temporalmente en ambos sistemas, comparar conteos y agregados, validar acceso/retención y cambiar lectores con una feature flag. Fija fecha de fin para la escritura doble y condiciones de rollback. Evita que ambas bases compitan como fuente de verdad.

En resumen

Elige por recorrido y consultas: Postgres cuando dominan relaciones y SQL; InfluxDB cuando encaja su modelo y operación; SQLite cuando un host de borde debe guardar con fiabilidad durante una caída. Empieza con el sistema más sencillo que cumpla requisitos medidos, explicita retención y reenvío, y reevalúa con datos reales, no con mitos de marcas.

Referencias