matt.boats

Ledger

Ask not what your finances can do for you, ask what you can do for your finances

ledger-cli is an open source tool for doing text based double entry accounting. I've been using it over the past few months to keep track of income, expenses, investments, and everything else related to my finances.

I think I find keeping such meticulous record fun, but I'm still not sure.

Double Entry Accounting

This is an accounting technique that is thousands of years old. The idea is pretty straightforward - each transaction must balance, ensuring that the money coming in matches the money going out. For example, paying for a coffee doesn't just have an expense for the coffee, but it also includes a inbound account:

Inbound Outbound
Credit Card 6.00
Coffee 6.00

This technique also allows for more complicated transfers, if you want to track the transfers from multiple parties

Inbound Outbound
Credit Card 6.00
Coffee 5.50
Taxes 0.50
Cash 2.00
Tip 2.00

Plain Text

The ledger cli tool takes plain text files as input. These are human readable, but can be indexed or manipulated by tools like grep, sed, awk, tracked with something like git, and can be generated by python scripts (or even AI - though I haven't had good experiences).

These files have a pretty basic format, here is an example from my ledger

2025/08/27 SQ *REDHAWK COFFEE
    liabilities:venture-x   -$7.42
    expenses:coffee

Here we see:

ledger is able to automatically balance this transactions (so I didn't have to list the coffee amount of $7.42).

There are a lot more features/syntax that are outlined in the docs. Some highlights include being able to assert that accounts hold specific balances at any given time, macros for automating transactions, and commodity support for trading in multiple currencies (or stocks, assets, etc). One of my favorite features is the ability add comments to the ledger!

Querying

A plain text accounting tool that only lets you record transactions is kind of boring. Ledger also allows querying of the recoded data through balance and register reports. These reports can be filtered using the payee, accounts, dates, or other arbitrary queries.

I've created a few dummy transactions to show this off:

2025/08/01 Paycheck
    income           -$2000.00
    assets:bank

2025/08/01 Coffee
    liabilities:card     $6.00
    expenses

2025/08/02 Dinner
    liabilities:card    $30.00
    expenses

2025/08/02 Movie
    liabilities:card    $20.00
    expenses

2025/08/02 Rent
    assets:bank        $750.00
    expenses

2025/08/31 Credit card bill
    assets:bank
    liabilities:card    = $0.0 ; paid off!

Balance

These reports show the total amount in each account at the current time.

] balance
            $2806.00  assets:bank
            $-806.00  expenses
           $-2000.00  income
--------------------
                   0

Register

This report shows each transaction involved as a timeline. Here I show each transaction that touches the "expenses" account. The columns are date, payee, account, amount, and total amount.

] register expenses
25-Aug-01 Coffee   expenses     $-6.00      $-6.00
25-Aug-02 Dinner   expenses    $-30.00     $-36.00
25-Aug-02 Movie    expenses    $-20.00     $-56.00
25-Aug-02 Rent     expenses   $-750.00    $-806.00

Import

My import workflow is somewhat manual, but not very time consuming. I've written a few python scripts that import CSVs from each of my credit card and bank accounts (Venmo, Fidelity, Capital One). I combine these into one single ledger file and use the balance assertion feature to make sure everything adds up. It takes a little bit of time to resolve any errors that are flagged (i.e. if I say the balance should be X but it comes out to X + $2.56, I have to track that down).

Conclusion

So far I've been pretty good about keeping my ledger updated and balanced (everything balanced to the cent!) I find it pretty easy to keep track of balanced owed to others and by others when we do things like split bills. I wish I could automatically import transactions easier, but no credit card or bank accounts I've found support this kind of thing.

There are a few similar tools (like hledger and beancount) so if this doesn't tickle your fancy maybe one of them will!