DEV Community

Dhruv Jain
Dhruv Jain

Posted on

Designing DynamoDB for an emergency department (access patterns first)

I built Solace, an AI-native patient intake and triage app for emergency departments, on Amazon DynamoDB and Vercel. This post is about the part that's easy to get wrong: the data model.

Why DynamoDB for an ED

An emergency department is the textbook DynamoDB workload. Traffic is bursty and unpredictable (a quiet floor, then six ambulances, then quiet again). Reads have to be single-digit-millisecond because the live patient queue refreshes on every arrival and a clinician is staring at it. And the access patterns are known in advance: look a patient up by id, a queue up by hospital, an encounter up by patient. That is exactly the shape DynamoDB is built for, and exactly the shape a relational database punishes you for under load.

Access patterns first, schema second

I did not drop a normalized relational schema into DynamoDB. I listed every read the product actually performs, then built a deliberate multi-table design around them. About 30 tables, all on demand (PAY_PER_REQUEST) so I never plan capacity, all encrypted with one customer-managed KMS key.

The most important one:

  • solace-patients: partition key patient_id, plus a GSI on hospital_id (hash) and created_at (range).

That single GSI is the live queue. Query by hospital, sorted by arrival time, in milliseconds. The clinician cockpit reads it on every refresh.

Three decisions that mattered

  1. Exactly-once intake without transactions. A patient on a flaky waiting-room connection will double-submit. Instead of a distributed transaction, the client sends a stable idempotency key and I store it in a TTL'd solace-idempotency table. The same key lands once and returns the cached response on a retry. The TTL evicts the record after 24 hours, so there is no cleanup job.

  2. Self-expiring sessions. solace-intake-nonces uses DynamoDB TTL as the session lifetime. The database is the garbage collector.

  3. Append-only audit, hot and cold. solace-audit-log is write-only with a 90-day TTL for hot access, and every record is also archived to S3 as CMK-encrypted JSONL with a lifecycle transition to Glacier, which is how I meet the HIPAA six-year retention requirement.

The Vercel half

The patient intake SPA and the clinician terminal deploy on Vercel as static, edge-cached shells that talk to the AWS backend (FastAPI on Lambda in front of DynamoDB). Fast to load on bad hospital Wi-Fi, atomic branch-based deploys.

The payoff: the live queue and the EHR match return in single-digit milliseconds with zero capacity planning, and the design scales from one ED to many hospitals by adding partitions, not by re-architecting.


I created this content for the purposes of entering the H0: Hack the Zero Stack hackathon. #H0Hackathon

Top comments (0)