Shared expense tracker inspired by Splitwise: a ledger where expenses and net balances commit in one transaction, cached balances, debt simplification into the fewest payments, notifications, receipts and search. A teaching design.
See why recomputing balances from all history doesn't last.
What was missing: Nothing yet.
Why that's risky: Balance views (the most common request) get slower as history grows, and one server and database carry everything.
What gets added: One server that stores expenses and computes each balance by summing every expense the user ever shared.
Trade-offs: No stored balances means they can't drift, but every read does the full computation.
Keep a running balance per member that can never disagree with the expenses.
What was missing: Balances were recomputed from all history on every view.
Why that's risky: Every balance view still reads the ledger, and a group's debts can form long chains (A owes B owes C) that take many payments to settle.
What gets added: An expense service that records each expense with its split lines and updates every member's net balance (per group and currency) in the same transaction, a sharded ledger database, a balance service reading net balances, and a groups service.
Trade-offs: Each write updates several balance rows, so a busy group has some write contention; sharding by group keeps it local.
Serve balance views from memory and settle groups with the fewest payments.
What was missing: Balance views hit the ledger, and settling a group took many payments.
Why that's risky: Nobody is told when a friend adds an expense, and there's no history of who changed what.
What gets added: A balance cache invalidated by every change in a group, and debt simplification in the balance service: net balances are matched largest creditor to largest debtor until everyone is settled, giving at most n−1 payments for n people.
Trade-offs: Simplified payments may send money between people who never shared an expense directly; users can turn simplification off.
Tell group members about changes and keep a history of who did what.
What was missing: No notifications and no record of changes.
Why that's risky: Receipt photos have nowhere to go, finding an old entry means scrolling, and nothing limits abuse.
What gets added: An activity event queue fed by every change, and a notification worker that sends push and email notifications and writes each member's activity feed.
Trade-offs: Notifications arrive seconds after the change.
Attach receipts, find old entries, and protect and watch the service.
What was missing: No receipts, no search, no rate limits and no monitoring.
Why that's risky: Remaining risk is low at this scale; backups and a second region cover disasters.
What gets added: Receipt uploads to object storage served through a CDN, a search index of descriptions, amounts, dates and people kept current from the activity events, a rate limiter, and monitoring of latency, transaction conflicts and notification delivery.
Trade-offs: Search lags new entries by a few seconds.
You're in the middle of an interview session. Leaving now will end your current attempt.
Explore concept overviews, real-system examples, key tradeoffs, and interview talking points for each roadmap section.
You've conquered this phase. These are the skills you now own: