Home
/
Blog
/
ESP32 Telemetry
IoT Backend Engineering
ESP32 Telemetry Pipeline: MQTT, Cloudflare Workers, Supabase, SQL, and Dashboards
ESP32 projects get interesting when they stop being isolated devices and become observable systems. A temperature sensor, vibration sensor, relay, camera, or battery-powered node is only the edge of the system. The real engineering starts when every reading becomes reliable data: validated, stored, charted, alerted, and replayable.
Published Jun 1, 2026
12 min read
IoT Backend
Why ESP32 belongs in backend conversations
The ESP32 is usually introduced as maker hardware, but the architecture around it is a backend problem. Devices lose Wi-Fi, sensors produce noisy data, clocks drift, messages duplicate, batteries die, and dashboards lie when the pipeline has no freshness model. A professional ESP32 project needs the same thinking as API integrations: idempotency, retries, schema validation, observability, and storage design.
Newer Espressif boards also make the edge more capable. For example, Espressif describes the ESP32-C6 as supporting Wi-Fi 6, Bluetooth 5 LE, and IEEE 802.15.4, which opens the door to Matter, Thread, Zigbee-style networks, and low-power IoT designs. The chip is small; the system around it is not.
Telemetry pipeline
ESP32 node
Reads sensor values and attaches device metadata.
MQTT broker
Receives compact events and handles flaky connectivity.
Worker API
Validates payloads, signs ingestion, and normalizes data.
Postgres
Stores raw readings, device state, and derived aggregates.
SQL views
Shapes data into dashboard-ready time windows.
Alerts
Detects thresholds, missing devices, and anomaly patterns.
The device payload should be boring
The best telemetry payloads are boring: device ID, timestamp, firmware version, sensor type, value, unit, battery level, signal strength, sequence number, and a unique event ID. That is enough to debug duplicates, late arrivals, bad clocks, firmware rollouts, and device health.
A common mistake is treating the ESP32 as the only source of truth. In practice, the backend should add its own server timestamp, ingestion ID, validation result, and source topic. The device reports what it saw. The backend records when and how the system received it.
24 devices
Active nodes seen in the last 10 minutes.
2.1s p95
Sensor-to-database ingestion latency.
98.7%
Valid payload rate after schema checks.
3 alerts
Devices missing data or crossing thresholds.
Example chart: hourly sensor average
MQTT is the ingestion layer, not the database
MQTT is a great transport for constrained devices because it is lightweight, topic-oriented, and resilient to intermittent networks. But the broker should not be the long-term analytics store. Its job is to move messages. The backend's job is to preserve history, validate data, calculate aggregates, and expose dashboards.
A clean pattern is: ESP32 publishes to MQTT, an ingestion worker subscribes or receives forwarded messages, validates the payload, writes raw data to Postgres/Supabase, then derives views for dashboard windows. That keeps the system replayable. If a chart looks wrong, you can inspect the raw events instead of guessing what the device did.
What I would build
I would start with a small but production-shaped version: ESP32 devices publishing JSON over MQTT, a Cloudflare Worker ingestion endpoint, Supabase/Postgres tables for raw readings and device registry, SQL views for hourly aggregates, and a simple dashboard showing freshness, charts, and alerts.
For a portfolio implementation, the dashboard should be visual from day one: metric cards, live device status, sparkline charts, alert history, firmware version distribution, and an event log. That makes the project feel less like a sensor demo and more like an operational telemetry platform.
| Table |
Purpose |
Important fields |
iot_devices |
Registry of known ESP32 nodes. |
device_id, location, firmware_version, last_seen_at, status |
sensor_readings_raw |
Append-only raw event storage. |
event_id, device_id, sensor_type, value, unit, device_timestamp, received_at |
sensor_readings_hourly |
Dashboard-ready aggregate view. |
device_id, sensor_type, hour_bucket, avg_value, min_value, max_value |
iot_alerts |
Threshold, freshness, and anomaly events. |
alert_id, device_id, severity, reason, opened_at, resolved_at |
Failure modes worth showing
Good IoT articles should show failure modes visually. The useful alerts are not only "temperature is high." They are also "device stopped reporting," "battery dropped faster than usual," "firmware version is old," "sequence numbers skipped," and "payload schema changed." These are the signals that separate a working demo from a maintainable system.
The same thinking applies to industrial vibration monitoring, smart greenhouses, energy meters, water tanks, rental equipment tracking, and vehicle telemetry labs. Once sensor data becomes a backend pipeline, ESP32 stops being only hardware and becomes an edge node in a distributed system.