Ledger Basics and Habits
Some time ago, I wrote about the CLI accounting program ledger, specifically building ledger from source and a small pet project of mine for visualizing ledger data called ledger-stats. I've even given a short presentation on the subject. I thought I'd take a blog post to talk about some basics of using ledger and some of the habits I've cultivated in my own usage of it. For more comprehensive info, check out the ledger manual.
A journal is a file in the ledger format. It can be of any size, though I typically like to keep one per year. This keeps file size relatively small (my largest one to date is about 150 KB), so searching them is easy, and makes it easy to report on annual figures (e.g. business expenses that can be written off) without having to manually specify date ranges.
An account is a label that represents a source or destination of money. A lot of people find this concept confusing because they associate it with an account at a bank rather than considering it as a more general concept. If you do any sort of computer programming, an account is similar in concept to a variable: it's just a name with which a value (in this case an amount of money) can be associated.
ledger supports hierarchical organization of categories separated by colons, so you can have accounts like
Movies is under
Entertainment is under
Expenses. This allows you to have ledger report at various levels in the hierarchy so that you can see what you spend only on
Movies or what you spend for all of your
Conventional top-level accounts are
Income, but I only tend to use the last three myself.
Assets are things I own that hold or are worth money, such as my bank accounts.
Expenses are things I spend money on, such as food and housing.
Income constitutes sources from which I obtain money, such as the salary I draw from my job or book royalty payments.
An event in which an account accumulates a quantity, such as adding $36 to your
Expenses:Auto:Gas account to represent when you topped off your car's gas tank today, is known as a posting. Because ledger uses a double-entry accounting system, however, you also need a posting representing the source of the funds from which you obtained this $36, such as the
Assets:Checking account representing the checking account you have at your bank.
A transaction is two or more postings representing a financial event, such as the above example of purchasing gas, where the amounts balance out to zero. In a journal file, a transaction is formatted like this:
; Comment Date Description Account1 Amount1 Account2 Amount2 AccountN
If you don't include an amount for the last account, ledger will automatically use whatever quantity causes the transaction to balance to zero. Most transactions involve two postings, so the second quantity will often be the same as the first but with the opposite sign (i.e. negative or positive). Here's what a real world transaction might look like:
2006/10/15 McDonald's Expenses:Dining $5.36 Assets:Checking
In this instance, $5.36 is deducted (or debited) from the checking account and added (or credited) to the account for dining expenses. I often include things like initial posting dates (for which you can also use auxiliary dates) or transaction identifiers from paying bills in the transaction description (i.e. "McDonald's" in the above example).
You may have a transaction where you're spending money on several things that you want to track in separate accounts. Here's an example of what that would look like:
2006/10/15 Exxon Expenses:Auto:Gas $15.00 Expenses:Cigarettes $4.80 Liabilities:MasterCard
Here, money is being spent on gas and cigarettes and the total of the two expenses, $19.80, is what's debited from the credit card account.
If you're like me, most of your transactions will only involve two postings, like the first example of an expense above. Another common type of posting represents when you receive income, which might look like this:
2006/10/15 Employer Assets:Checking $1000.00 Income:Salary
These may look a bit odd when they show up in ledger reports because the quantities will be negative since you're debiting the amounts from them. This is normal and you'll get used to seeing it appear this way.
When a transaction clears your account, you can denote this by adding an asterisk delimited by spaces between the transaction date and description like so:
2006/10/15 * McDonald's Expenses:Dining $5.36 Assets:Checking
One small potential pitfall: the segments of account names between colons can have spaces in them. As such, in order to denote the end of an account name, you should place at least two spaces between the account name and amount in each posting.
I use a bank that offers online banking, including a web site and mobile app that allow me to view activity on my accounts almost any time. ledger may seem redundant in relation to something like this, but there are a few reasons why this isn't so:
- Transactions may not show up in the banking interface right away because some vendors often post several days' transactions in a single batch every few days.
- Transaction amounts may not be accurate. For example, initial postings from some gas stations may only show an amount of $1 and won't reflect the correct amount until they clear. Initial postings from restaurants often don't include any added gratuity.
- Some activity may be fraudulent, which may not be immediately obvious if your card information is stolen in a business you frequent.
Every time I spend money and am able to get a receipt, I do so. I save them until they clear or, for larger purchases, until the period in which I may return the purchased item expires.
Tracking these receipts with ledger solves all of the above issues: I know about transactions that may not be reflected in my online account activity yet, I know when transaction amounts are inaccurate, and I can identity potentially fraudulent transactions when my online account activity shows a transaction for which I don't have a receipt.
Every few days, I record any new receipts in my journal file, update any transactions that have cleared, and compare the journal file to my online account activity to ensure the two are consistent. This is a process called reconciliation.
Pro-tip: tracking cash withdrawals and purchases can be a pain. I typically just maintain an
Expenses:Cash account for these sorts of things. If I can remember how I spent a bit of cash, great: I can just debit
Expenses:Cash and credit the appropriate account for what I spent the cash on after the fact. Otherwise, I just leave the amount attributed to
Expenses:Cash. It's often not worth the trouble of trying to keep finer track of cash purchases than that.
register command in ledger displays all postings from a journal file that involve one or more specified accounts. I typically use this to ensure that my journal and online account activity are consistent by listing all activity for those accounts.
$ ledger reg checking -f stan.txt 08-Jan-01 Opening Balances Assets:Checking $1550.00 $1550.00 08-Jan-01 New Seasons Assets:Checking $-60.91 $1489.09 08-Jan-01 Panda Express Assets:Checking $-7.24 $1481.85 08-Jan-02 Sizzle Pie Assets:Checking $-7.38 $1474.47 08-Jan-03 Kettleman Bagels Assets:Checking $-7.60 $1466.87 08-Jan-03 Mio Sushi Assets:Checking $-5.76 $1461.11 08-Jan-03 Eddie's Flat Iron P.. Assets:Checking $-22.26 $1438.85 08-Jan-04 Food Carts Assets:Checking $-7.24 $1431.61 08-Jan-05 Burnside Brewery Assets:Checking $-11.76 $1419.85 08-Jan-05 Tastebud Assets:Checking $-42.13 $1377.72 08-Jan-07 Salary Assets:Checking $1084.00 $2461.72
In the above example of register command output,
reg indicates that the register should be used,
checking is part of the name of the account being queried, and the value following
-f indicates the journal file to be read.
The last column in the command output is a running sum of all quantities from postings for that account, where that column's value in the last row of output is the account balance. The register command is useful when the balances of journal and online accounts aren't consistent and you need to find where a transaction is missing or has an incorrect amount.
The output of the register command can be limited by transaction date (as well as many other options) using either or both of its
--end flags like so:
$ ledger reg --begin=2014/02/01 --end=2014/02/28 -f stan.txt
Speaking of balances, ledger also has a
balance command. This outputs balances for accounts at each hierarchical level. This allows you to see, for example, numbers as general as your total Expenses and as specific as what you spent going to the
$ ledger bal expenses -f stan.txt $157874.79 Expenses $5212.85 Entertainment $21526.95 Food $1377.36 Breakfast $3174.59 Dinner $11171.71 Groceries $5803.29 Lunch $8568.00 Insurance $3948.00 Car $4620.00 Medical $5136.40 Interest $4618.79 Car $517.61 Student $33600.00 Rent ... -------------------- 0
Budgeting and Bills
ledger offers support for budgeting that can forecast when bills come due based on an interval and compare entered transactions against budgeted amounts to show whether you came over or under budget for any given time period. While this is a really cool feature, I don't really use it the way it was intended to be used.
The budgeting feature uses what are called periodic transactions. These are slightly different from normal transactions in that they use a period expression rather than a date and have no description. They are formatted like so:
~ Monthly Expenses:Rent $500.00 Expenses:Food $450.00 Expenses:Auto:Gas $120.00 Expenses:Insurance $150.00 Expenses:Phone $125.00 Expenses:Utilities $100.00 Expenses:Movies $50.00 Assets
I keep blocks of these at the top of my journal, organized by the pay period in which I pay the bills they each contain. When I sit down to pay bills, I make a copy of the appropriate block at the bottom of my journal and comment it out. Then, as I pay each bill, I uncomment the appropriate posting and move it out into an actual transaction. This gives me a way to easily check which bills haven't been paid yet (e.g. if I'm waiting on a paper bill for the exact amount I owe).
I generally use vim to edit my journal files. There's a contributed plugin for adding ledger format syntax highlighting, which is nice. I also use my fork of the visSum plugin for vim (the fork adds support for decimal quantities) to visually highlight and sum remaining bill amounts. I can compare the output of that with the balance of my account (from ledger's register or balance commands) to determine how much I actually have left in excess of bills.
Even though I'm only using a very small amount of ledger's overall feature set, I'm gaining several benefits by putting in the time to maintain these journal files:
- Peace of mind in knowing that I know where my money is and where it's going, despite whatever records my online banking interface may yet be lacking.
- Information I can use to forecast future financial events, such as how much I'll spend on electricity to keep my house at a comfortable temperature during the summer and winter, how much I spend on average for gas and groceries, or how much I spend on sporadic luxuries like eating out.
- At tax time, I can very quickly and easily provide exact figures to my accountant for business-related expenses without having to take time to compile them manually.
Some people have asked me what I think of services like Mint. While such services may offer a nice interface, those interfaces are often intentionally kept very simple, to the point where I'm limited in the ways I can report on my data in their system. Additionally, there's rarely a way for me to easily get that same data out of their system and into a format I can use elsewhere. In short, I like having control of my data and what I can do with it. These services may work for others, but they just don't suit me.
Hopefully this blog post has given you some perspective on the benefits of accounting with ledger and how you can go about adopting this approach yourself if that prospect entices you. Feel free to leave a comment if you have a question or would like to discuss the topic further with me.