MQTT for Real-Time Sensor Data: Earthquake Monitoring Over the Cloud
When your earthquake sensor detects ground motion, how does that data travel from a microcontroller on your shelf to a cloud dashboard, an alert system, and ultimately to people who need to take protective action? The answer is MQTT — the protocol that makes real-time IoT communication possible.
For IoT-based seismic monitoring, MQTT has emerged as the clear winner.
Why MQTT for Earthquake Sensors?
MQTT (Message Queuing Telemetry Transport) is a lightweight publish-subscribe messaging protocol designed for constrained devices and unreliable networks. It was created by IBM in 1999 for satellite-linked SCADA systems — exactly the kind of environment where every byte matters.
For earthquake monitoring, MQTT offers three critical advantages:
1. Low Latency
MQTT maintains a persistent TCP connection between the sensor and the broker. When data is ready, it's sent immediately — no connection setup overhead. Typical message delivery: 50–200ms from sensor to cloud.
2. Small Payload
MQTT's protocol overhead is just 2 bytes for the fixed header. A typical sensor reading (timestamp + 3 acceleration values) fits in under 100 bytes. This means:
- Less bandwidth consumption
- Faster transmission
- Lower power consumption on the ESP32
3. Reliability Options
MQTT offers three Quality of Service (QoS) levels:
- QoS 0 — "fire and forget" (fastest, no guarantee)
- QoS 1 — "at least once" delivery (guaranteed, may duplicate)
- QoS 2 — "exactly once" delivery (guaranteed, no duplicates, slowest)
For seismic data, QoS 1 provides the best balance: fast delivery with guaranteed arrival.
MQTT Architecture for Earthquake Monitoring
┌──────────┐ MQTT/TLS ┌──────────┐ Subscribe ┌──────────┐
│ GeoShake │ ──────────────► │ MQTT │ ──────────────► │ Cloud │
│ Sensor │ Publish │ Broker │ │ Backend │
│ (ESP32) │ │(HiveMQ) │ ──────────────► │(Supabase)│
└──────────┘ └──────────┘ Forward └──────────┘
│ │
│ Subscribe │
└──────────────────────────► │
┌──────────┐
│ Mobile │
│ App │
└──────────┘
Topic Structure
GeoShake uses a hierarchical topic structure:
seismic/stations/{STATION_ID}/data ← Sensor readings
seismic/stations/{STATION_ID}/status ← Device health (RSSI, heap, uptime)
seismic/stations/{STATION_ID}/commands ← Remote commands (calibrate, restart)
seismic/stations/{STATION_ID}/events ← Detected seismic events
This structure enables:
- Per-station subscriptions — monitor a specific sensor
- Wildcard subscriptions —
seismic/stations/+/datato receive all station data - Command isolation — each station receives only its own commands
MQTT vs. Alternatives
| Protocol | Latency | Overhead | Power | Bidirectional | Best For |
|---|---|---|---|---|---|
| MQTT | 50–200ms | 2 bytes | Low | ✅ | Real-time sensor streams |
| HTTP REST | 200–500ms | ~500 bytes | High | ❌ | Occasional data uploads |
| WebSocket | 50–200ms | 2 bytes | Medium | ✅ | Browser real-time displays |
| CoAP | 50–200ms | 4 bytes | Very Low | ❌ | Ultra-constrained devices |
| LoRaWAN | 1–10s | ~20 bytes | Very Low | Limited | Remote, no-WiFi locations |
MQTT wins for earthquake sensors because:
- Sensors need persistent, low-latency connections (MQTT excels here)
- Bidirectional communication enables remote calibration and firmware updates
- The protocol efficiently handles bursty data (normal idle → sudden high-frequency during an earthquake)
- TLS support secures data in transit
Implementing MQTT on ESP32
Setting Up the Connection
The GeoShake firmware uses the PubSubClient library for MQTT on ESP32:
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
WiFiClientSecure espClient;
PubSubClient mqtt(espClient);
void setupMQTT() {
espClient.setCACert(root_ca); // TLS certificate
mqtt.setServer(MQTT_BROKER, MQTT_PORT);
mqtt.setCallback(onMessage);
}
void connectMQTT() {
while (!mqtt.connected()) {
String clientId = "GeoShake-" + String(STATION_ID);
if (mqtt.connect(clientId.c_str(), MQTT_USER, MQTT_PASS)) {
// Subscribe to commands for this station
mqtt.subscribe(("seismic/stations/" + STATION_ID + "/commands").c_str());
} else {
delay(5000); // Retry after 5 seconds
}
}
}
Publishing Sensor Data
void publishReading(float ax, float ay, float az, unsigned long timestamp) {
char payload[128];
snprintf(payload, sizeof(payload),
"{\"t\":%lu,\"x\":%.4f,\"y\":%.4f,\"z\":%.4f}",
timestamp, ax, ay, az
);
String topic = "seismic/stations/" + STATION_ID + "/data";
mqtt.publish(topic.c_str(), payload, false); // QoS 0 for streaming
}
Receiving Commands
void onMessage(char* topic, byte* payload, unsigned int length) {
String message = String((char*)payload).substring(0, length);
if (message == "CALIBRATE") {
runCalibration();
} else if (message == "RESTART") {
ESP.restart();
} else if (message.startsWith("CONFIG:")) {
updateConfig(message.substring(7));
}
}
MQTT in GeoShake's Architecture
GeoShake uses MQTT with TLS encryption to transport seismic data from community sensors to the cloud backend:
Security: MQTT over TLS
Seismic data should be encrypted in transit to prevent tampering and privacy violations. GeoShake uses MQTT over TLS (port 8883):
- Certificate pinning — the sensor validates the broker's TLS certificate
- Username/password authentication — each sensor has unique credentials
- HiveMQ Cloud — enterprise-grade MQTT broker with automatic TLS
Why Security Matters for Earthquake Data
- Tamper prevention — falsified seismic data could trigger false alarms, causing panic
- Privacy — sensor location and connectivity data should be protected
- Network integrity — unauthorized devices shouldn't be able to inject data into the network
Scaling Considerations
As a community sensor network grows, MQTT infrastructure must scale:
Broker Selection
| Broker | License | Max Connections | Cloud Hosted |
|---|---|---|---|
| HiveMQ Cloud | Managed | 10K+ | ✅ (GeoShake uses this) |
| Mosquitto | Open Source | ~10K | Self-hosted |
| EMQX | Open Source | 100K+ | ✅ or self-hosted |
| AWS IoT Core | Managed | Millions | ✅ |
Data Flow at Scale
For a network of 1,000 sensors each publishing at 100 Hz:
- Messages per second: ~208,000
- Bandwidth: ~20 MB/s (at 100 bytes per message)
- Processing requirement: Backend must handle real-time ingestion at this rate
In practice, GeoShake sensors don't stream raw data at 100 Hz to the cloud. Instead, they perform on-device processing:
- Sample at 100 Hz locally
- Compute PGA and spectral features on-device
- Stream summary data at ~1 Hz during normal operation
- Stream raw data at higher rate only during detected events
This reduces cloud bandwidth by 200x while preserving critical event data.
Getting Started
For Your DIY Sensor
- Install the
PubSubClientArduino library - Set up a free HiveMQ Cloud account (or any MQTT broker)
- Configure TLS with the broker's CA certificate
- Publish sensor readings to your topic structure
- Build a subscriber (Node.js, Python, or use MQTT Explorer) to visualize data
For the GeoShake Network
If you want to skip the MQTT setup and join an existing network:
- Get a GeoShake T1 sensor (€49) — MQTT is pre-configured
- Or flash GeoShake firmware to your ESP32 DIY build
- The firmware handles connection, publishing, reconnection, and security
📱 Manage your sensor and see real-time data in the GeoShake app. Free on iOS and Android.
Related Articles:
Ready to join the network?
Get the GeoShake T1 sensor and start detecting earthquakes at home.
Get earthquake insights in your inbox
One short email a month — new guides, network updates, real detection stories. No spam, unsubscribe anytime.