Design a service that ingests donations and serves rolling 3-day donation totals.
Requirements
Core features
-
Ingest donation
events:
-
Each donation has:
donation_id
(unique),
user_id
,
campaign_id
,
amount
,
currency
,
created_at
(event time).
-
Query APIs:
-
GET /campaigns/{id}/total?window=72h
→ total donated to that campaign in the last 72 hours (rolling window).
-
GET /leaderboard?window=72h&k=100
→ top-K campaigns by donated amount in the last 72 hours.
Correctness and scale expectations
-
Must handle
duplicate submissions
(retries) safely (idempotency).
-
Donations may arrive
late/out of order
(e.g., mobile offline, retries).
-
Support high write throughput (assume 5k–50k donations/sec) and high read QPS for totals/leaderboard.
-
Windowing is based on
event time
(
created_at
), not ingestion time.
Non-functional
-
Low latency reads (p95 < 200ms for totals and leaderboard).
-
Strong auditability (ability to reconcile totals from raw events).
Deliverables
-
High-level architecture
-
Data model and storage choices
-
Windowed aggregation approach
-
Handling idempotency, late events, and consistency
-
Scaling, caching, and failure modes