"Shazam, but for hearts."
Heartbeat Library answers one question: given any ECG waveform, find the most similar cardiac patterns across a 99.6-million-sample clinical database β in under half a second.
It uses Cascade DTW filtering + in-database PL/pgSQL DTW on TimescaleDB hypertables to retrieve ECG matches with zero network round-trips between filtering and scoring. Built on the MIT-BIH Arrhythmia and PTB-XL datasets from PhysioNet β 2,821 real patients, 48 hours of annotated cardiac data.
| Service | URL | Status |
|---|---|---|
| π Frontend | heartbeat-library-wt5u.vercel.app | π’ Live |
| βοΈ Backend API | heartbeat-library-api.onrender.com | π’ Live |
| π Database | Timescale Cloud Β· AP-SOUTH-1 | π’ Live |
| π GitHub | github.com/sarthakNaikare/heartbeat-library | β Public |
| π§βπ» Portfolio | sarthaknaikare.github.io | π’ Live |
All benchmarks run against 99,600,000 ECG samples across 2,821 patients
| Method | Wall Time | Filter Latency | Notes |
|---|---|---|---|
| π’ Naive DTW | `53.4s` | β | Full scan baseline |
| β‘ Cascade v1 | `15.3s` | `84ms` | 99.9% candidate elimination |
| π Cascade v2 | `17.0s` | `84ms` | Batch fetch variant |
| π In-DB DTW | `0.46s` | `3.1ms` | PL/pgSQL, zero network trips |
| π Elasticsearch | `~1s` | `18β125ms` | Industry benchmark |
``` π¦ Compression: 9 GB β 839 MB (91.2% Β· 11.3Γ ratio) π― Precision@10: 100% (PVC Β· Normal Β· Atrial beats) β‘ Filter speedup: 40Γ (3.1ms vs 125ms Elasticsearch) π Total speedup: 116Γ (Naive DTW β In-DB DTW) ```
``` βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β CLIENT (React) β β Splash Β· Search Β· Dashboard Β· Benchmarks Β· Upload β β heartbeat-library-wt5u.vercel.app β ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββ β HTTPS REST ββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββ β BACKEND (FastAPI) β β /search Β· /upload-search Β· /stats Β· /generate-report β β heartbeat-library-api.onrender.com β ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββ β psycopg2 ββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββ β DATABASE (TimescaleDB 2.26) β β Timescale Cloud Β· AP-SOUTH-1 β β β β ecg_samples β 99.6M rows Β· hypertable Β· compressed β β ecg_recordings β 2,821 patients β β ecg_beats β 201,680 individual beats β β ecg_segments β 18,366 segment-level stats β β dtw_distance() β PL/pgSQL in-database DTW function β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ```
``` Stage 1 β Statistical Pre-filter (SQL) ββ Filter by mean Β± Ο, amplitude range β eliminates 99.9% of candidates
Stage 2 β Euclidean Distance (Python) ββ Fast L2 distance on surviving candidates β narrows to top-k
Stage 3 β In-Database DTW (PL/pgSQL) ββ Full DTW on final candidates, computed inside Timescale β Zero network round-trips, sub-500ms wall time ```
```sql -- Hypertable: 99.6M rows, chunked by time, 91.2% columnar compressed CREATE TABLE ecg_samples ( sample_id BIGSERIAL, recording_id INTEGER REFERENCES ecg_recordings(recording_id), sample_index INTEGER, timestamp TIMESTAMPTZ NOT NULL, signal_value FLOAT4, lead TEXT DEFAULT 'MLII' ); SELECT create_hypertable('ecg_samples', 'timestamp');
-- In-database DTW β zero network trips CREATE OR REPLACE FUNCTION dtw_distance( seq1 FLOAT4[], seq2 FLOAT4[] ) RETURNS FLOAT8 LANGUAGE plpgsql AS $$ DECLARE -- Dynamic Time Warping matrix computed in pure SQL ... $$; ```
| Layer | Technology | Why |
|---|---|---|
| ποΈ Database | TimescaleDB 2.26 Β· Timescale Cloud | Hypertables, columnar compression, time-series native |
| βοΈ Backend | FastAPI Β· Python 3.11.9 Β· Render | Async, typed, auto-docs |
| π Frontend | React Β· Vercel | Component-driven, edge CDN |
| π‘ Uptime | UptimeRobot (5-min pings) | Keeps Render free tier awake 24/7 |
| π Data | MIT-BIH + PTB-XL Β· PhysioNet | Gold-standard clinical ECG datasets |
| π Ingestion | wfdb + psycopg2 COPY protocol | Bulk-load 99.6M rows efficiently |
- Patient + beat type selector β query by specific arrhythmia class
- Demo pills β one-click preset queries for PVC, Normal, Atrial
- Live similarity results β DTW scores, waveform visualizations
- Upload your own ECG β drag & drop CSV/TXT/DAT, get instant matches
- Live stats pulled from Timescale Cloud API
- Compression ratios, row counts, chunk statistics
- Bar charts comparing all methods
- Precision@10 table across beat types
- Compression comparison vs raw storage
- Download a professional HTML report with DTW scores, similarity bars, methodology, and disclaimer
``` heartbeat-library/ βββ gui/ β βββ frontend/ β React app (Vercel) β β βββ src/ β β β βββ App.js β React.createElement (no JSX) β β β βββ Search.js β β β βββ Dashboard.js β β β βββ Benchmarks.js β β β βββ Upload.js β β βββ .env β REACT_APP_API_URL β βββ backend/ β FastAPI app (Render) β βββ main.py β /search /upload-search /stats /generate-report β βββ dtw.py β Cascade DTW pipeline β βββ requirements.txt β βββ .python-version β Pinned 3.11.9 βββ ingestion/ β wfdb β TimescaleDB pipeline βββ README.md ```
``` GET /health β Uptime check (HEAD + GET, for UptimeRobot) GET /stats β Live database statistics POST /search β Cascade DTW search by patient/beat type POST /upload-search β Upload ECG file β normalize β cascade β results POST /generate-report β Professional HTML medical report download ```
| Dataset | Patients | Source |
|---|---|---|
| MIT-BIH Arrhythmia Database | 48 | PhysioNet |
| PTB-XL ECG Dataset | 2,773 | PhysioNet |
| Total | 2,821 | β |
Sarthak Naikare
CS Graduate Β· MIT ADT University, Pune Β· 2025
- π Publish research paper β Computers in Biology and Medicine + VLDB Industrial Track
- π Migrate database to Fly.io (post Timescale Cloud trial)
- ποΈ Add voiceover to demo video
- π Build Ghost + TimescaleDB real-time network intrusion detection SIEM