Mastering Your Heartbeat: Architecting a High-Frequency Health Monitoring System with InfluxDB and Grafana
Source: Dev.to
Introduction
High‑frequency health monitoring generates thousands of data points per minute from sensors such as heart‑rate, blood‑oxygen (SpO₂), and electrocardiogram (ECG). Storing this data in a traditional relational database quickly becomes impractical. A time‑series database (TSDB) like InfluxDB provides the write throughput and storage efficiency needed for such workloads.
Architecture Overview
The data flow consists of:
graph TD
A[Wearable Sensors / IoT Node] -->|MQTT/HTTP| B(Telegraf Collector)
B -->|Line Protocol| C{InfluxDB 2.x}
C -->|Flux Query| D[Grafana Dashboard]
C -->|Retention Policy| E[Downsampled Long‑term Storage]
subgraph "Data Engineering Layer"
B
C
E
end
style C fill:#f96,stroke:#333,stroke-width:2px
- Wearable Sensors / IoT Node – emit data via MQTT or HTTP.
- Telegraf – universal data collector that receives the data and writes it to InfluxDB using the line protocol.
- InfluxDB 2.x – stores raw measurements and runs background tasks for down‑sampling.
- Grafana – visualizes the data with Flux queries.
Prerequisites
- Docker & Docker Compose
- Basic knowledge of IoT protocols (MQTT/HTTP)
- InfluxDB 2.x, Telegraf, Grafana
Docker Compose Setup
Create a docker-compose.yml file to orchestrate the services:
version: '3.8'
services:
influxdb:
image: influxdb:2.7
ports:
- "8086:8086"
volumes:
- influxdb-data:/var/lib/influxdb2
environment:
- DOCKER_INFLUXDB_INIT_MODE=setup
- DOCKER_INFLUXDB_INIT_USERNAME=admin
- DOCKER_INFLUXDB_INIT_PASSWORD=password123
- DOCKER_INFLUXDB_INIT_ORG=my-health
- DOCKER_INFLUXDB_INIT_BUCKET=raw_vitals
telegraf:
image: telegraf:latest
volumes:
- ./telegraf.conf:/etc/telegraf/telegraf.conf:ro
depends_on:
- influxdb
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
depends_on:
- influxdb
volumes:
influxdb-data:
Running docker compose up -d will start a reproducible, isolated environment.
InfluxDB Schema Design
For health vitals, organize data into tags (metadata) and fields (measurements).
Measurement: vitals
Tags: patient_id="user_01", device_type="watch_v2"
Fields: bpm (float), spo2 (float), ecg_mv (float)
Tags are indexed and enable efficient queries; fields store the actual numeric values.
Telegraf Configuration
Save the following as telegraf.conf (TOML format). It configures an HTTP listener to receive JSON payloads and forwards them to InfluxDB.
[[inputs.http_listener_v2]]
service_address = ":8080"
path = "/telegraf"
methods = ["POST"]
data_format = "json"
tag_keys = ["patient_id", "device_type"]
[[outputs.influxdb_v2]]
urls = ["http://influxdb:8086"]
token = "${INFLUX_TOKEN}"
organization = "my-health"
bucket = "raw_vitals"
Downsampling with InfluxDB Tasks
Storing every ECG sample for years is costly. Keep raw data for 24 hours and downsampled data for long‑term analysis. The following Flux task creates 1‑minute averages and writes them to a separate bucket.
option task = {name: "Downsample_Vitals", every: 1m}
from(bucket: "raw_vitals")
|> range(start: -task.every)
|> filter(fn: (r) => r._measurement == "vitals")
|> mean()
|> set(key: "_measurement", value: "vitals_1m_avg")
|> to(bucket: "long_term_vitals")
Grafana Setup
- Add InfluxDB as a data source (choose Flux as the query language).
- Create a dashboard panel with the following Flux query to visualize heart‑rate (
bpm):
from(bucket: "raw_vitals")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "vitals")
|> filter(fn: (r) => r["_field"] == "bpm")
|> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)
|> yield(name: "mean")
Alerting
Set up an alert rule in Grafana (or via InfluxDB Tasks) to trigger when the heart‑rate exceeds a threshold, e.g., bpm > 150 for more than 5 minutes. The alert can send notifications to Slack, Discord, or other channels.
Conclusion
By combining InfluxDB, Telegraf, and Grafana, raw sensor signals are transformed into actionable health insights. This stack provides high write throughput, efficient storage, and flexible visualization—making it well‑suited for personal or research‑grade health monitoring.
What’s Next?
- Add an AI layer (e.g., Python) to detect arrhythmias in real time.
- Explore multi‑tenant architectures and encryption‑at‑rest for HIPAA‑compliant deployments.