Know where your money is, and where it went.

Every account on one page, bank statements that file themselves, and reports that trace back to the entries that made them. Self-hosted, so the only copy of your transactions is the one you keep.

Hosted version soonGet the source

Self-host it today — AGPL-3.0, one machine and a PostgreSQL. A hosted version you do not have to run is coming.

The Simple Balance overview: balance, deposits, withdrawals and net cash flow for the month, then accounts and spending by category, reported separately for each currency the ledger holds.

Why bother

Four things that are true of almost every other way of doing this.

Your net worth is spread across eight logins.

Checking, savings, cards, cash, loans, investments and crypto wallets sit on one page, each in its own currency, with balances as of any date you ask for.

Currencies are never added together, because there are no exchange rates here to add them with. A total in dollars and a total in euros are two totals, reported side by side, and neither is a guess.

Importing a statement costs you an evening.

Point it at a CSV your bank exported and it works out the format, maps the columns, and files the payees and categories it recognises.

Anything that looks like a row you already have is opened beside the one it resembles, so you can fix either side. Nothing counts toward a balance until you say so.

A bank CSV part-way through import: the columns it worked out, the rows it will stage, and three flagged as possible duplicates of entries already in the ledger.
The importer maps the columns itself, then shows you what it will do.

You find out about the annual renewal when it leaves the account.

Rent, a salary, a subscription: set it up once and it proposes itself on the day, as a draft you approve rather than a transaction that appeared.

If you want an email about it, it sends one. If you never configure a mail server, everything else still works — nothing here breaks because a feature you did not set up is missing.

The numbers in your budgeting app do not tie out.

Underneath this is real double-entry bookkeeping. Every transaction settles to zero in every currency it touches, checked before anything is written.

That is what lets any figure on any page be traced back to the entries that made it. When a number looks wrong you can open the register and find the row it went wrong on, instead of taking a dashboard's word for it.

The net worth report, with a separate table per currency: euro accounts totalled in euro, dollar accounts in dollars, and no combined figure.
Net worth, per currency, with closing balances that reconcile to the postings behind them.

A look at it

The pages you would actually live in.

The transactions list: dated rows with payee, account, category and amount, dollar and euro entries side by side, each amount signed and right-aligned.
Every entry, filterable, with transfers shown as one row moving between two accounts.
The budgets page, showing each category's assigned amount against what was actually spent, with the remainder carried from the previous period.
Budgets compared against what was really spent, including what a refund gave back.

Screenshots show a demo ledger seeded with example transactions, captured from the running application.

What else is in it

The parts you only notice when they are missing.

Currencies kept apart

A conversion records what left one account and what arrived in the other, and the rate it implies. No global rate table, no overnight revaluation, no figure that changes because a market moved.

One receipt, several categories

Split a transaction across as many categories as it actually covers, each attributed on its own. Recategorising a leg is one update and writes no new postings.

Budgets that carry

Per category, per group, or for a single month. What a period did not spend rolls into the next if you want it to, and a back-dated correction changes every period after it.

Duplicates caught on the way in

A row that resembles one you already have is shown next to it, before either counts. Import the same statement twice and you get one ledger, not two.

Ten thousand rows at a time

Change or delete up to ten thousand transactions in one go, from any view, after seeing exactly what it will touch. It applies atomically or not at all.

A register for every account

Every posting with the balance before and after it. Corrections append rather than overwrite, so the history of a mistake survives the fix.

Self-hosted

The only copy of your transactions is yours.

This is software you run, not a service you join. There is no account on our side, because there is no our side — one deployment, one PostgreSQL, and whoever you choose to give an account to.

  • Your ledger sits on hardware you control, wherever you choose to put it.
  • No analytics, no telemetry, and nothing phoning home to be counted.
  • PostgreSQL is the only thing it needs. No queue, no cache, no object store.
  • AGPL-3.0, so the source is readable and stays that way.

For agents

Let an assistant do the filing, without handing over the keys.

Simple Balance ships an MCP server with the same capabilities as the web app, so an AI agent can import a statement, tidy categories and chase duplicates. What it cannot do is skip the part where you check its work: staged rows affect no balance until they are committed, and a token carries scopes that stop well short of spending money.

# the agent proposes; nothing has moved yet
$ ledger:stage
  42 rows staged from statement-2026-08.csv
   3 flagged as possible duplicates
# you commit, or you do not