Inspiration
I'm a pre-med engineering student, and I kept coming back to one place where the people most likely to decline quietly get the fewest eyes at night: nursing homes.
- Overnight, state staffing rules allow one caregiver for 15 or more residents (e.g. Maine 1:15, Connecticut 1:16), on rounds every two hours.
- About half of nursing-home residents fall every year, about twice the rate of older adults at home (AHRQ PSNet).
- In the elderly, an infection heading toward sepsis often shows up as confusion and restlessness, not a fever, so fixed alarms miss it, or ring all night until staff tune them out.
People decline between rounds. I wanted a tool that tells one tired aide who to check next, and why.
What it does
Vigil monitors every resident around the clock from a wristband and an under-mattress bed sensor, learns each resident's own normal, and gives the night shift one calm, ranked list.
- Rounds Queue: a "Check next" card in plain language ("Breathing faster and heart rate higher than usual for her, and restless in bed since about 11 pm"), bedside checks, and a big "I checked on Rosa" button. A hallway floor plan shows every room.
- Two speeds:
- Fast tier (Tiger Data, seconds): falls, extreme vitals, a resident who has stopped moving, a high-fall-risk resident out of bed alone at night.
- Deep tier (Snowflake, minutes): quiet drift judged against each person's own history, forecasts, and AI that reads their care plan.
- Resident page: why now → what to check at the bedside → verbatim care-plan quotes → who to call, based on code status (full code vs. comfort care). The detailed charts, NEWS2 and the score breakdown are one tap away.
- Nurse notes by voice: "She seems more confused tonight and barely drank" → transcribed and structured → new confusion adds 3 NEWS2 points.
- Shift handoff in SBAR format, and "Ask the facility" questions in plain English for the Director of Nursing.
- Replay of last night through the full pipeline, and a live demo with real hardware: I'm resident 120, my Polar band streams my heart rate over Web Bluetooth, and my iPhone under the pillow is the bed sensor. When I get out of bed alone at night, I'm #1 and Critical within seconds.
On the scripted night, fixed thresholds fired 903 alarms; Vigil raised 22. It flagged Rosa, an 87-year-old with a silent UTI drift, 1 h 18 min before her scheduled round and 3 h 20 min before the first fixed alarm.
How we built it
Two integrations, two jobs: Tiger Data is the live layer ("what is happening now"); Snowflake is the intelligence layer ("what it means, and what to do").
Tiger Data (TimescaleDB on Tiger Cloud): the live layer
- Hypertables for every sensor reading (33.7 M rows: 120 simulated residents every 5 s, plus my live Polar band and iPhone at 1 s) and for events.
- Hierarchical continuous aggregates 1 min → 15 min → 1 h with real-time aggregation. A 7-day hourly query for all residents runs ~43× faster than raw.
- Columnstore compression: 14.8× (4.0 GB → 274 MB).
- Hyperfunctions:
time_bucket_gapfill+locffor charts,percentile_agg/approx_percentilefor each resident's personal baseline by time of day,heartbeat_aggfor device liveness,state_aggfor time in bed, and anadd_jobhourly baseline job. - The fast-tier evaluator scores all 120 residents every 2 s straight from Tiger (NEWS2, fall and bed-exit rules, hysteresis, alarm-fatigue suppression).
Snowflake: the intelligence layer (through its REST APIs: SQL API, Cortex Search REST, Cortex Analyst REST)
SNOWFLAKE.ML.ANOMALY_DETECTION: 5 multi-series models (HR, RR, SpO₂, skin temp, night restlessness), one series per resident, so each person is judged against their own normal (255k results).SNOWFLAKE.ML.FORECAST: predicts when breathing will cross a NEWS2 danger threshold, before it happens.- Cortex
COMPLETE(Claude) + Cortex Search: 120 synthetic care-plan PDFs →AI_PARSE_DOCUMENT→ 1,200 chunks → a search service. Claude writes bedside checks that quote the care plan verbatim, with a wording guard (decision support, never a diagnosis). AI_TRANSCRIBE+AI_EXTRACT: voice and typed nurse notes become structured findings.AI_AGG: the SBAR shift handoff. Cortex Analyst: plain-English questions → SQL over a semantic model.- Every Snowflake call is counted and shown on an "Under the hood" page.
App: FastAPI (Python) + Next.js/TypeScript behind Caddy. A seeded physiology simulator for 120 residents with a scripted "last night". Web Bluetooth for the Polar Verity Sense, and DeviceMotion for the iPhone bed sensor. A calm night/day UI in Atkinson Hyperlegible, designed to be read at arm's length on a tablet.
Challenges we ran into
- Making silent decline actually silent. The first version of the story escalated on a "more confused" note at 21:30, which gave everything away. I redesigned the scenario so Snowflake's anomaly models catch the drift before any human documents confusion; the confusion is discovered because Vigil sent the aide.
- Teaching the models night vs. day. Two days of history wasn't enough, and whole-day movement bands were too wide to see restlessness. The fix was 9 days of training and a night-in-bed-only movement model.
- Trial-account limits: Cortex's
inference:completeREST endpoint returned 403, so Claude runs through the SQL REST API instead. Parallel anomaly detection also saturated the warehouse; I capped concurrency and cancel queries on shutdown. - Real hardware: turning an iPhone under a pillow into a reliable bed-exit sensor (tilt detection plus calibration), without false alarms when someone rolls over.
Accomplishments that we're proud of
- On the same night: 903 fixed-threshold alarms vs. 22 Vigil alerts, and Rosa flagged hours earlier.
- A COPD resident who would trigger 18 fixed alarms gets zero, because Vigil judges her against her own normal.
- A live, real-hardware demo: out of bed → Critical in ~6 seconds, with the care plan's fall precautions already on screen.
- Every number on the proof page is a live query, not a slide.
What we learned
- In geriatrics, "abnormal" has to mean abnormal for this person. Personal baselines beat fixed thresholds on both sensitivity and alarm fatigue.
- Splitting "now" (Tiger) from "what it means" (Snowflake) made the system faster and more robust: emergencies never wait on ML, and if Snowflake is slow, the fast tier keeps working.
- Wording matters clinically: decision support, bedside checks and code status, never a diagnosis.
What's next for Vigil
- A pilot with real devices in a skilled nursing facility, and a clinical review of the thresholds with nurses.
- Learning from nurse feedback ("checked: she was fine") to tune each resident's sensitivity.
- A family view, EHR integration, and a HIPAA-ready deployment.
All data is synthetic. No cameras. Decision support, not a diagnosis.
Built With
- caddy
- claude
- cortex-analyst
- cortex-search
- docker
- echarts
- fast-api
- ffmpeg
- ios
- next.js
- playwright
- polar
- postgresql
- python
- react
- snowflake
- snowflake-cortex
- snowflake-ml
- tailwindcss
- tiger-data
- timescaledb
- typescript
- web-bluetooth
- websockets
Log in or sign up for Devpost to join the conversation.