How to design an expense sharing app: data model and math
Quick answer
An expense sharing app needs eight rules: an expense belongs to one group or friendship, balances are paid minus share, shares round to exact cents, balances stay per currency, simplify debts never changes a total, deleted and pending items do not count, permissions are explicit, and edits work offline. Each rule below has a small example and the way Splitwise or EvenOut behaves.
Key points
- Balances are paid minus share, so every balance in one currency adds up to zero. Make that sum a test that runs after every write.
- Round in whole cents and hand the leftover cents out, so $25.00 three ways is $8.34, $8.33 and $8.33 and the shares still add to the bill.
- Keep balances per currency. Splitwise's help center says its Simplify Debts works within each currency separately, and EvenOut does the same.
- Deleting and pending are states, not removals: both stop counting toward balances, and both can come back.
- EvenOut queues adds, edits, deletes and payments offline and shows 'N changes couldn't sync' with a Retry button.
On this page
What records does the data model need?
Five kinds of record cover it: expenses, shares, payers, payments and the container they live in, which is a group or a friendship. Each of the eight rules in this guide is easy to state and easy to break, so each comes with a small example.
Rule 1: an expense belongs to one container. An expense holds a description, a total, a currency, a date and who paid. Its shares are separate rows, one per person, so a split is only a list. The container is a group or a friendship, never both. EvenOut’s Friends tab is the friendship case: you split one-on-one with a friend and no group is needed.
Two details save a rewrite later. Keep payers as a list as well, because imported Splitwise expenses in EvenOut can carry several payers even though hand-added ones have one. And give people who are not on the app yet a placeholder. EvenOut’s “Add a guest” tracks a share now, shows “Guest · invite to claim”, and moves the shares to the real account when the guest claims their spot.
Payments are their own records, because they are shown, deleted and restored on their own. EvenOut’s Activity tab filters them as “Payments”. The arithmetic is the same as an expense, so the balance code does not care which kind a row came from.
How do balances stay correct?
Balances stay correct when they are built from paid minus share, shares that are exact cents, and a sum-to-zero check run after every write.
Rule 2: balance is paid minus share. Say Dee pays $72.00 for groceries shared by Dee, Eli and Fay. Each share is $24.00. Dee is at +$48.00 (paid $72.00, owes $24.00), and Eli and Fay are each at -$24.00. The three numbers add up to zero. If they ever do not, a row is missing or a share was rounded on its own, so run the sum after every write and fail loudly.
Rule 3: shares are whole cents that add up to the total. $25.00 is 2,500 cents, and 2,500 divided by 3 is 833 with 1 left over. Rounding each share on its own gives $8.33 three times, which is $24.99 and a cent short. The fix is to hand the leftover cent to one person: $8.34, $8.33 and $8.33. Which person gets it is a product choice. What cannot vary is the sum. EvenOut’s splits are cent-accurate, with remainder cents shared out and not lost.
How should currencies and simplify debts behave?
Both rules protect the totals: a balance never mixes currencies, and simplifying never changes what anyone owes.
Rule 4: keep a balance per person per currency. Splitwise’s help center, as of October 2026, shows two balances side by side, “You owe $12.45 and you are owed £8.72”, and does not net them. It says changing an expense’s currency “only changes the currency label”, and that its Pro conversion button converts every expense in a group or friendship at the current rate, settled ones included, which can change other people’s balances. A design that offers conversion should treat it as a view over the stored amounts, so the expenses themselves never change. EvenOut keeps balances, settle up and simplify per currency and has no conversion, so you log each expense in the currency you paid. The guide to splitting expenses in multiple currencies shows the day-to-day side.
Rule 5: simplify debts changes who pays whom, never a total. Say Kai owes Lia $35.00 and Lia owes Moe $35.00. Kai’s net is -$35.00, Lia’s is $0.00 and Moe’s is +$35.00, so Kai can pay Moe $35.00 once and Lia pays nobody. Splitwise’s help center says the feature “never changes anyone’s total balance” and re-runs when an expense or payment is added. Compute it from net balances each time, per currency, so the stored expenses never change. EvenOut’s setting is tagged “Recommended” and is on by default, and any member who is not a viewer can switch it. The search for the fewest payments is covered in the minimum transactions guide, and how simplify debts works has a six-IOU example.
What should not count toward a balance?
Deleted and pending expenses should stop counting, and they should not disappear.
Rule 6: deleting and pending are states. A deleted expense keeps its row and gains a deleted flag. EvenOut’s delete message says it “stops counting toward balances for everyone involved”, and the expense stays on screen crossed out with a “Restore” button. Splitwise’s help center says anyone originally included on the expense can undelete it.
Pending covers money that is promised but not final. Say a hotel holds $200.00 on a card. EvenOut’s “Pending payment” marks it “Not counted in balances yet”. After the stay the final charge is $164.50. Confirming it re-splits everyone’s share to the final amount: 16,450 cents among 4 people is 4,112 each with 2 cents left, so two people pay $41.13 and two pay $41.12, which adds up to $164.50.
Who can change an expense, and what works offline?
Every write needs a permission check and a plan for when the network is gone.
Rule 7: make permissions explicit. Splitwise’s help center says, as of October 2026, that it has no group admins or special permissions: anyone involved in an expense or its group can edit or delete it. EvenOut adds roles: an owner, a member or a viewer, and a viewer “sees everything and can comment, but can’t add or change expenses”. It also has a “Who can edit” setting, “Everyone” or “Only their own”. In an “Only their own” group, Ben can edit the dinner he paid for and cannot touch the groceries Ana paid for. Enforce the check in the API, not only in the interface.
Rule 8: queue writes and show their state. EvenOut lets you add, edit, delete and restore expenses, record payments, comment, and create groups and friends without a connection, and syncs them later. A failed sync stays visible as “N changes couldn’t sync” with a “Retry” button. Some things need a connection, such as photo upload, setting up a repeat, invites and importing, so decide which writes can be replayed safely and which cannot.
What should you build first?
Build in the order of the rules: one container per expense, then paid minus share with the zero-sum check, then whole-cent shares, then per-currency balances. Deleting, pending, permissions and offline queuing come after that, and simplify last. The Splitwise low-level design walkthrough turns the first four into classes and a runnable Java sketch, and bill splitting apps on GitHub lists open source projects to read. How to figure out who owes who covers the same net-balance idea for people doing it by hand.
Frequently asked questions
How would you model an expense that two people paid for?
Store the payers as a list of person and amount paid, so one payer is a list of one. Say a $60.00 taxi is paid $45.00 by Tess and $15.00 by Uri, and four people share it at $15.00 each. Tess is at +$30.00, Uri at $0.00, and the other two at -$15.00. EvenOut's hand-added expenses have one payer, and imported Splitwise expenses can carry several.
What happens to a guest's shares when they join?
In EvenOut, a guest is a placeholder for someone not on the app yet. The guest's creator makes a single-use claim link that lasts 7 days, and a new link replaces the old one. Claiming it asks to merge into the person's own account, which cannot be undone, and the guest's shares move to that account.
Should you store balances or compute them?
Compute them from the expense, share and payment rows, minus anything deleted or pending, and cache the result if it is slow. A cached balance can be rebuilt at any time, while a lost expense cannot, and the zero-sum check only means something when balances come straight from the rows.
Sources
Checked October 6, 2026.
- Splitwise: What is Simplify Debts?
- Splitwise: How can I manage a friendship or group with multiple currencies?
- Splitwise: Can I prevent group members from changing expenses or set permissions?
- Splitwise: How can I restore a deleted expense?
Keep reading
- Guide Splitwise low-level design: classes, splits and balances Design a Splitwise-style expense splitter: money in cents, one strategy per split method, net balances, simplify debts and a Java sketch that compiles and runs.
- Guide Minimum transactions to settle debts: the algorithm Settling N people takes at most N minus 1 payments, but not always the fewest. A five-person example needs 4 payments greedily and only 3 at best.
- Guide How simplify debts works, with worked examples Simplify debts cuts the payments a group needs without changing anyone's total. Six IOUs worth $105 become 3 payments worth $50, with the arithmetic shown.
- Comparison Bill splitting apps on GitHub: what to check before you use one Spliit, SplitPro and Cospend are open source bill splitters on GitHub. Their licenses, how you run them, five checks and a $50 test before you trust one.
- Guide Split expenses in two currencies without converting Track a €300 hotel and a £120 dinner as two balances, then settle each one or agree a rate once. Also what Splitwise and EvenOut do with currencies.
- Guide How to figure out who owes who after shared expenses Add up what each person paid, divide by the people sharing, and subtract. Four friends and five expenses settle in 3 payments instead of 6 pairwise debts.