Splitwise Design
Splitwise LLD models groups, expenses, split strategies (equal, exact, percentage), and simplified balances between members — who owes whom.
Introduction
Splitwise LLD models groups, expenses, split strategies (equal, exact, percentage), and simplified balances between members — who owes whom.
Key classes: User, Group, Expense, Split, BalanceSheet. Adding expense updates pairwise balances; settlement records payment between users.
Interview depth: split algorithms, debt simplification, and idempotent expense creation.
Understanding the topic
Key concepts
- Group contains members sharing expenses.
- Expense: payer, amount, split type, participants.
- Split strategies: EQUAL, EXACT, PERCENTAGE.
- BalanceSheet tracks net owed between pairs.
- Settlement reduces balances between two users.
- Optional debt simplification (min cash flow) advanced topic.
Step-by-step explanation
- Create group; add members.
- Member adds expense with split rule.
- System computes each participant share.
- Update balances: participants owe payer.
- Member views net balance per friend.
- Record settlement when cash exchanged.
Informative example
Expense with equal split and balance ledger:
public enum SplitType { EQUAL, EXACT }public record Expense(String id, String payerId, Money total, SplitType type, Map<String, Money> shares) {}public final class BalanceLedger {private final Map<String, Money> netByUser = new HashMap<>();public void applyExpense(Expense e) {e.shares().forEach((user, share) -> {if (!user.equals(e.payerId())) {netByUser.merge(user, share, Money::add);netByUser.merge(e.payerId(), share, Money::subtract);}});}public Money balanceFor(String userId) {return netByUser.getOrDefault(userId, Money.ZERO);}}public final class ExpenseService {public Expense createEqual(String payerId, Money total, List<String> participants) {Money each = total.divide(participants.size());Map<String, Money> shares = participants.stream().collect(Collectors.toMap(u -> u, u -> each));return new Expense(UUID.randomUUID().toString(), payerId, total, SplitType.EQUAL, shares);}}public final class Group {private final String id;private final Set<String> members = new HashSet<>();private final BalanceLedger ledger = new BalanceLedger();private final ExpenseService expenses = new ExpenseService();public Group(String id) { this.id = id; }public void addMember(String userId) { members.add(userId); }public void addEqualExpense(String payerId, Money total) {Expense e = expenses.createEqual(payerId, total, List.copyOf(members));ledger.applyExpense(e);}}
Money value object with add/subtract/divide; SettlementService records pairwise payments.
Real-world use
Real-world applications
- Split algorithm interview question.
- Ledger and balance aggregation modeling.
- Group expense apps and fintech LLD.
Best practices
- Immutable Expense records after creation.
- Split strategy pattern for EQUAL/EXACT/PERCENT.
- Validate shares sum to total.
- Idempotent expense ids for retry safety.
- Separate balance query from expense command.
Common mistakes
- Shares not summing to total amount.
- Mutating past expenses instead of adjustment entries.
- O(n²) balance display without simplification plan.
- No payer distinction in ledger updates.
Advanced interview questions
Q1BeginnerSplitwise core entities?
Q2BeginnerEqual split of 100 among 3?
Q3IntermediateExact vs equal split?
Q4IntermediateSimplify who owes whom?
Q5AdvancedMulti-currency expense?
Summary
Group aggregates members and expenses. Split strategies compute participant shares. Ledger tracks net balances from expenses. Settlements record real payments. Validate splits sum to expense total.