The Challenge: Racing Against Time in Healthcare Vital Sign Monitoring
In clinical settings like hospitals, home health services, or remote patient monitoring, every second counts. Medical devices continuously stream vital sign data, including heart rate, blood oxygen, and blood glucose, at high frequency. The challenge isn't just capturing this constant flow of information. It is analyzing it in the moment. How do you process real-time vital signs to detect abnormalities and trigger alerts instantly without introducing high latency or massive infrastructure complexity? Traditional data systems often rely on batch processing. This leads to delayed alerts that can compromise patient safety. Conversely, custom stream processing solutions often require heavy coding and maintenance, putting them out of reach for many agile teams. This is the gap our demo bridges: turning raw, high-volume vital sign data into actionable alerts that healthcare providers can act on instantly.
The Solution: Real-Time Clinical Insights with RisingWave
We have built a demo that combines the high-throughput ingestion of Kafka with the stream processing power of RisingWave.
This solution transforms raw vital sign streams into instant alerts and trend analysis using standard SQL. By leveraging RisingWave, we eliminate the complexity of traditional stream processing frameworks like Flink or Spark Streaming. This allows you to focus on defining critical logic, such as patient-specific thresholds, rather than managing complicated data pipelines.
A Look Inside the Dashboard: Clinical-Grade Real-Time Monitoring
Our demo delivers a clinician-friendly interface that puts critical data front and center.
1. Live Alert Monitoring & Triage
The dashboard’s summary section provides a bird’s-eye view of system performance and clinical workload:
Total alerts, broken down by severity (Level 1/Level 2)
Pending alerts (with 10-minute trend to identify surge patterns)
Confirmation and resolution rates (to measure team responsiveness)
The Alert Details section displays real-time alerts for abnormal vital signs, sorted by severity. Clinicians can immediately see which patient is in critical condition without sifting through raw logs.

2. Detailed Alert Drill-Down
Clicking an alert reveals the context. This includes timestamped readings before and after the event alongside the specific rule that was breached, such as "Heart rate exceeded 140 bpm for 2 minutes.”

How It Works: The Technical Architecture
The demo’s power lies in its simplicity. It is powered by RisingWave, which turns complex stream processing into simple SQL. Here represents the end-to-end data flow:

1. Data Capture (Medical Devices → Kafka)
Medical devices (wearables, bedside monitors) stream real-time vital sign data in JSON format to Kafka topics. Each message includes patient ID, device ID, timestamp, and vital sign values.
A lightweight Python producer, included in the demo, simulates device data for testing. It generates normal and abnormal readings to trigger alerts.
2. Streaming Processing (RisingWave)
This is where the core processing happens. RisingWave acts as the engine of the system, processing data incrementally and maintaining fresh results without redundant computations.
Step 1: Ingest Data from Kafka
With a single CREATE SOURCE command, RisingWave ingests the Kafka stream and makes it queryable as a Source Table:
CREATE SOURCE patient_vital_signs_stream (
patient_id STRING, -- Unique identifier for patient (inpatient number)
device_id STRING, -- Monitoring device ID (serial number)
measure_time TIMESTAMP, -- Measurement time (accurate to milliseconds)
heart_rate INT, -- Heart rate (beats per minute)
blood_oxygen DECIMAL, -- Blood oxygen saturation (%)
blood_glucose DECIMAL -- Blood glucose level (mmol/L)
) WITH (
connector = 'kafka',
topic = 'vital_signs',
properties.bootstrap.server = 'localhost:9092'
) FORMAT PLAIN ENCODE JSON;
Step 2: Detect Anomalies with SQL
We can customize alert rules and create a materialized view to track alerts in real time:
CREATE MATERIALIZED VIEW vital_signs_single_alerts AS
SELECT
v.patient_id AS patient_id,
v.measure_time AS measure_time,
CASE
WHEN v.heart_rate < t.heart_rate_min OR v.heart_rate > t.heart_rate_max THEN 'heart_rate'
WHEN v.blood_oxygen < t.blood_oxygen_min THEN 'blood_oxygen'
WHEN v.blood_glucose < t.blood_glucose_min OR v.blood_glucose > t.blood_glucose_max THEN 'blood_glucose'
END AS "alert_type",
CASE
WHEN v.heart_rate < t.heart_rate_min THEN CONCAT('Heart rate too low: ', v.heart_rate, ' bpm')
WHEN v.heart_rate > t.heart_rate_max THEN CONCAT('Heart rate too high: ', v.heart_rate, ' bpm')
WHEN v.blood_oxygen < t.blood_oxygen_min THEN CONCAT('Blood oxygen too low: ', v.blood_oxygen, '%')
WHEN v.blood_glucose < t.blood_glucose_min THEN CONCAT('Blood glucose too low: ', v.blood_glucose, ' mmol/L')
WHEN v.blood_glucose > t.blood_glucose_max THEN CONCAT('Blood glucose too high: ', v.blood_glucose, ' mmol/L')
END AS "alert_detail"
FROM patient_vital_signs_stream v
LEFT JOIN vital_signs_thresholds t ON v.patient_id = t.patient_id
WHERE
(v.heart_rate < t.heart_rate_min OR v.heart_rate > t.heart_rate_max)
OR (v.blood_oxygen < t.blood_oxygen_min)
OR (v.blood_glucose < t.blood_glucose_min OR v.blood_glucose > t.blood_glucose_max);
Step 3: Sink Processed Data to The Hospital Databases
To connect stream-processed alerts to the hospital databases (e.g., MySQL), we use RisingWave’s CREATE SINK command to real-time sync the materialized view data to it.
CREATE SINK alerts_sink FROM unified_alerts
WITH (
connector='jdbc',
jdbc.url='jdbc:mysql://localhost:3306/medical_alerts',
user='root',
password='root',
table.name='alerts',
type = 'append-only',
force_append_only='true',
primary_key = 'alert_id'
);
Alternative: Simplify Your Stack with Subscriptions
If you want to further simplify your architecture, you can skip the MySQL database entirely. RisingWave supports Subscriptions, which allow your backend application to listen for updates directly.
Instead of sinking to MySQL and polling for changes, your application can declare a subscription:
CREATE SUBSCRIPTION alerts_sub FROM vital_signs_single_alerts;
Your Python backend can then consume this subscription using a cursor, receiving alerts as they are generated. This removes the need for an intermediate database, reducing latency and operational overhead. Read more about Subscriptions here.
3. Real-Time Visualization (Frontend Dashboard)
The frontend dashboard is built with HTML5 + Tailwind CSS + JavaScript—aligning with the demo’s lightweight, production-ready design principles. It interacts with the backend via a FastAPI service that reads synced alert data from MySQL.
Build It Yourself in Minutes
Ready to see it in action? This entire demo is open-source, with step-by-step instructions to get you up and running in under an hour.
Python Kafka producer for simulating medical device data
RisingWave SQL scripts (source, materialized view, sink)
MySQL table schema for alert storage
FastAPI backend code (API endpoints for data query and status updates)
Frontend HTML/JS dashboard (no build tools required)
Get Started with RisingWave
Try RisingWave Today:
Download the open-sourced version of RisingWave to deploy on your own infrastructure.
Get started quickly with RisingWave Cloud for a fully managed experience.
Talk to Our Experts: Have a complex use case or want to see a personalized demo? Contact us to discuss how RisingWave can address your specific challenges.
Join Our Community: Connect with fellow developers, ask questions, and share your experiences in our vibrant Slack community.
If you’d like to see a personalized demo or discuss how this could work for your use case, please contact our sales team.

