VitalSense: Real-Time Patient Triage on Redis (Streams • Search • JSON • TimeSeries)



This content originally appeared on DEV Community and was authored by devin nicholson

This is a submission for the Redis AI Challenge: Beyond the Cache.

What I Built

A real-time patient triage dashboard that uses Redis 8 as the primary data platform. It ingests vitals (HR/SpO₂/BP) via Redis Streams, persists the latest state per patient in Hashes, indexes snapshots with RediSearch for instant querying, publishes alerts with Pub/Sub, stores adjustable alert thresholds in RedisJSON, and renders 24-hour trends from RedisTimeSeries. The React/Next.js UI is real-time (WebSocket), offline-first (IndexedDB hydration), supports threshold configuration (persisted in Redis), and provides a drill-down panel with a per-patient sparkline (via TS.RANGE).

Key properties:

  • Primary DB: No external database; Redis is the system of record for runtime state + settings.
  • Search & Rules: RediSearch powers numeric queries for “critical” patients (low SpO₂ / high HR), pulled by a watcher that publishes alerts.
  • Streams + Pub/Sub: Streams for ingestion/fan-out; Pub/Sub for real-time alert fan-out to the browser.
  • Time series: Per-patient SpO₂ time series with 24h retention for drill-down trends.
  • UX: Progressive skeletons, dark mode, drill-down, offline cache, threshold modal (live-reconfigures the watcher).

Demo

Github: https://github.com/devinnicholson/vitalsense/tree/main
Demo: wip

How I Used Redis 8

Data ingestion (Streams)

  • XADD patients:stream * id P01 heart_rate 82 spo2 95 bp_systolic 120 bp_diastolic 80
  • Consumer group (XGROUP CREATE / XREADGROUP) provides reliable processing and back-pressure.

Primary state (Hashes)

  • Latest snapshot per patient in Hash:
  • HSET patient:P01:snapshot hr 82 spo2 95 sys 120 dia 80 timestamp

No external DB; Redis holds the live source of truth.

Indexed queries (RediSearch)

  • FT.CREATE idx:snapshots ON HASH PREFIX 1 “patient:” SCHEMA hr NUMERIC SORTABLE spo2 NUMERIC SORTABLE sys NUMERIC dia NUMERIC timestamp TAG
  • Query examples used by the watcher/UI:
  • Low oxygen: @spo2:[-inf 92]
  • High HR: @hr:[120 +inf]
  • Combined: (@spo2:[-inf 92]) | (@hr:[120 +inf])
  • Event fan-out (Pub/Sub)
  • Watcher runs a periodic RediSearch query, publishes critical hits to alerts:critical.
  • A Node WS proxy subscribes and forwards JSON to browser WebSockets.

Time series analytics (RedisTimeSeries)

Per-patient SpO₂:

  • TS.CREATE ts:patient:Pxx:spo2 RETENTION 86400000 LABELS patient Pxx
  • TS.ADD ts:patient:Pxx:spo2
  • Drill-down: TS.RANGE ts:patient:Pxx:spo2
  • Dynamic configuration (RedisJSON)

Alert thresholds live in JSON:

  • JSON.SET settings:thresholds . ‘{“spo2″:92,”hr”:100}’
  • Next API GET/PATCH /api/settings/thresholds reads/writes this key.
  • Watcher reloads thresholds each loop → instant effect.

Team Submissions:
Devin Nicholson


This content originally appeared on DEV Community and was authored by devin nicholson