sylvain durand

Personal finance with Beancount

When I was 7 years old, my parents gave me pocket money for the first time: 10 F per week (about €2 today) accompanied by a small notebook in which I had to do my accounting. I suppose it was a way to monitor what I was going to do with that fortune, but I kept track of my finance.

Since my first debit card 15 years ago, I’ve tracked every expense I’ve made. The goal is pretty simple: to know where my money comes from and where it goes, and how my lifestyle is changing. Over the years, these accounts have also become a very special form of diary: they note each of my outings, each activity, bar, restaurant, cinema or theater.

How I’ve tracked my finances in the past

Despite a few attempts with software like HomeBank, I used a simple Excel sheet for almost twelve years. One line per transaction, with a column for the date, a category, a label, and the amount (one column per account).

This approach has many flaws:

Plain text accounting with Beancount

In 2019, I discovered a concept that has changed the way I track my personal finances: plain text accounting. Basically, it’s very simple: all transactions are written on a simple text file, with a particular syntax. The software reads them and is able to make all kinds of reports, presentation, either from the command line or in a nice web interface.

Above all, the whole thing is based on a logic of double-entry bookkeeping: I didn’t know what it brought, but I couldn’t do without it today!

Several softwares exist, notably ledger who invented the concept, hledger, and beancount which is the one I use to take advantage of the excellent fava web interface.

Why double-entry bookkeeping?

For a long time, the interest of double-entry bookkeeping seemed to me to be limited to the corporate world, and at best useless for an individual. That was before I tried it!

There are two types of things you want to track:

Income and expenses affect your accounts as follows:

Revenues (+)  ⇾  (Assets - Liabilities)  ⇾  Expenses (-)

Each transaction requires at least two balanced transactions involving assets (or liabilities), revenues and expenses. Let’s say I want to buy a good video game. The syntax is as follows:

2022-03-21 * "Steam" "Buying Stardew Valley"
  Assets:Checking                 -13.99 EUR
  Expenses:Games                   13.99 EUR

Here I buy using my checkings account (which is an asset), which will therefore decrease by €13.99. I’m also increasing my expenses, in a subaccount named “games” where, in the future, I will be able to find in it all the games I bought and for how much. The sum of all operations must necessarily be zero (nothing is lost, nothing is created)!

Now let’s imagine that I invite Bob at the restaurant, pay partly with cash, and that I complete it with my bank card:

2022-03-21 * "Susama Sushi" "Lunch with Bob"
  Assets:Cash                     -20.00 EUR
  Assets:Checking                 -15.50 EUR
  Expenses:Restaurant              35.00 EUR

What if Bob promised to pay me back for his meal?

2022-03-21 * "Susama Sushi" "Lunch with Bob"
  Assets:Cash                     -20.00 EUR
  Assets:Checking                 -15.50 EUR
  Assets:Debts:Bob                 17.50 EUR
  Expenses:Restaurant              17.50 EUR

And when Bob pays us back with a bank transfer:

2022-03-23 * "Susama Sushi" "Bob refund"
  Assets:Checking                  17.50 EUR
  Assets:Debts:Bob                -17.50 EUR

Want to know how much you spend on restaurants? Check out the Expenses:Restaurant account balance. Need to know how much you have left on your checking account? This is the balance of Assets:Checking. Does Bob still owe you money? Just look at Assets:Debts:Bob balance.

There are no constraints on the accounts you can create, and you can have longer depths (Expenses:Home:Phone and Expenses:Home:Internet for example, allowing you to simply see a Expenses:Home total).

Other instructions

Beancount file read by beancount consists essentially of a series of transactions as indicated above. You can also open or close accounts, indicate a balance (allowing Beancount to return an error if something does not match), comments, attachments…

You can also make currency conversion, stock market transactions, allowing you to track costs, prices, realized and unrealized capital gains.

For example, I buy here 3 Apple shares at a $163.98 price per unit, with 0.5% fees, so a $164.80 cost per unit:

2022-03-17 * "Buying 3 AAPL"
  Assets:Stocks:Cash             -494.40 USD
  Assets:Stocks:AAPL      3 AAPL {164.80 USD} @ 163.98 USD

Basically, you can count something else than financial values: days off, worked hours…


Through the years, my income and expense accounts have become the following (of course, this hierarchy works well for me, but will depend on your needs):

├─── Scholarships
├─── Gifts
├─── Classes
├─── Pensions
└─── Salaries
     ├─── Gross
     └─── Taxes

├─── Subscriptions
│    ├─── Banks
│    ├─── Internet
│    ├─── Telephone
│    └─── Newspapers
├─── Housing
│    ├─── Rent
│    ├─── Insurances
│    ├─── Electricity
│    └─── Gas
├─── Purchases
│    ├─── Books
│    ├─── Clothing
│    ├─── Cash
│    ├─── Gifs
│    ├─── Electronics
│    ├─── Games
│    └─── Misc
├─── Needs
│    ├─── Groceries
│    ├─── Health
│    └─── Care
├─── Leisure
│    ├─── Bars
│    ├─── Coffee
│    ├─── Cinemas
│    ├─── Concerts
│    ├─── Outings
│    ├─── Sports
│    └─── Theaters
├─── Meals
│    ├─── Bakeries
│    ├─── Deliveries
│    └─── Restaurants
├─── Transportation
│    ├─── Subway
│    ├─── Cabs
│    └─── Trains
├─── Travel
└─── Exceptional

├─── Checkings
│    ├─── Bank1
│    ├─── Bank2
│    └─── Bank3
├─── Deposits
└─── Savings
     ├─── LDDS
     ├─── PEL
     └─── PEA
          ├─── Cash
          ├─── Unit1
          └─── Unit2

Command line usage

Beancount offers several commands to generate reports on your accounts:

Beancount can easily be augmented with plugins written in Python. These allow you to easily modify or add transactions or accounts automatically. It becomes easy to make automatic depreciations, to split transactions, to share expenses or to follow a budget.

The Beancount documentation is particularly complete and allows you to discover the concepts, the most common use cases, but also the most advanced needs:

Web interface with Fava

However, one of the strengths of Beancount is also the Fava web interface (see the demo). Fava proposes to display simply all the accounts, expenses, incomes, assets, with different graphs which allow easily to change views, to filter or to observe only different time steps.

Fava also offers a system of plugins that allows you to build your own personalized report pages, in a very efficient way.


As of today, my file has 30.058 lines, 7259 directives (15.622 postings in 6902 transactions) and includes all my transactions since mid 2007!

The report of the balances is executed in 0.3 seconds. Even if these performances suit me perfectly, the next version of Beancount, planned in C++ against Python today, should largely improve them.