Accrued Expenses in Beancount: A Practical Guide (with copy-paste ledger examples)
Accrued expenses sound abstract until month-end closes start piling up. They are a cornerstone of proper accrual accounting, ensuring your financial reports reflect economic reality, not just when cash changes hands. Here’s a clear, Beancount-first walkthrough of what they are, why they matter, and exactly how to book, reverse, and report them in your plain-text ledger.
TL;DR ⚡
- Accrued expenses are costs you’ve incurred this period but haven’t paid yet. They are recorded as a liability until the cash goes out.
- In Beancount, this is simple: you debit an
Expenses:
account and credit aLiabilities:Accrued:
account. Later, you clear the liability when you pay.- To report, you can see what you owe as of a specific date by running a
bean-query
withCLOSE ON
andCLEAR
to get a clean balance-sheet snapshot.
What is an Accrued Expense?
An accrued expense is a cost that a business has incurred, but has not yet paid. It's recorded when the service is received or the cost is incurred, even if the invoice hasn't arrived or the payment isn't due yet. This practice follows the matching principle of accrual accounting, which dictates that expenses should be recorded in the same period as the revenues they helped generate.
Common examples include:
- Wages earned by employees at the end of a month but paid in the next.
- Utilities (electricity, water) you used in December but won't be billed for until January.
- Interest on a loan that has accumulated over the month but has not yet been withdrawn from your account.
By recording these costs when they happen, you get a much truer picture of your company's financial performance for that period.
How Beancount Thinks About It (in 30 seconds)
Beancount is a plain-text, double-entry accounting system. Everything is a dated directive or transaction in a text file. The system is built on five core account types: Assets, Liabilities, Equity, Income, and Expenses.
Entries are always ordered by date. A key detail is that balance
assertions are checked before same-day transactions are processed. This is important to remember when you place checks and reversing entries.
Finally, the bean-query
language provides a powerful, SQL-like way to generate reports. With operators like OPEN ON
, CLOSE ON
, and CLEAR
, you can create precise "as-of" views for financial statements.
Your Chart of Accounts (Suggested)
A clean, hierarchical chart of accounts is your best friend. For accrued expenses, the structure is straightforward. You'll need:
- An expense account: e.g.,
Expenses:Utilities
,Expenses:Payroll:Wages
- A corresponding liability account: e.g.,
Liabilities:Accrued:Utilities
,Liabilities:Accrued:Payroll
- Your cash account: e.g.,
Assets:Bank:Checking
Beancount enforces the five top-level account types. Keeping your account names organized makes querying and reporting much easier down the road.
The Core Pattern (No Plugin, No Magic)
This is the most direct way to handle accruals in Beancount. It involves two steps: accruing the expense at month-end and clearing the liability when you pay.
Step 1: Accrue the Expense at Month-End
On the last day of the period, you record the expense and create the liability.
2025-02-28 * "Accrue February electricity" #accrual
Expenses:Utilities 120.00 USD
Liabilities:Accrued:Utilities
Step 2: Clear the Accrual When You Pay
When the bill comes and you pay it, you don't hit the expense account again. Instead, you debit the liability account to clear it out.
2025-03-05 * "Pay Feb electricity - City Power"
Liabilities:Accrued:Utilities 120.00 USD
Assets:Bank:Checking
This is the cleanest approach for small teams. It correctly places the expense in February and ensures you don't double-count it in March. Notice that in Beancount, leaving one amount blank lets the system balance the transaction for you automatically.
Alternative: Reversing Entry on Day 1
If you prefer the classic "auto-reverse" accounting style, you can post the opposite of your accrual entry on the first day of the next month. Then, you book the actual vendor bill to the expense account as you normally would.
Step 1: Accrue at Month-End (Same as before)
2025-02-28 * "Accrue February electricity" #accrual
Expenses:Utilities 120.00 USD
Liabilities:Accrued:Utilities
Step 2: Reverse on the First Day of the Next Month
2025-03-01 * "Reverse Feb electricity accrual" #reversal
Liabilities:Accrued:Utilities 120.00 USD
Expenses:Utilities
Step 3: Book the Payment as Usual
2025-03-05 * "City Power - February bill"
Expenses:Utilities 120.00 USD
Assets:Bank:Checking
Heads-up on checks: Remember that balance
assertions evaluate before same-day transactions. If you want to check your Liabilities:Accrued:Utilities
account balance, place the assertion on 2025-02-28
to confirm the accrual or on 2025-03-01
after the reversal transaction to confirm it's zero. Placing it before the reversal on 2025-03-01
will cause a false failure.
Six Common Accruals (Copy-Paste Patterns) 📋
Here are some ready-to-use examples for common business accruals.
1. Rent Not Yet Invoiced
2025-01-31 * "Accrue January rent" #accrual
Expenses:Rent 3000.00 USD
Liabilities:Accrued:Rent
2. Wages Earned but Unpaid
2025-03-31 * "Accrue March wages" #accrual
Expenses:Payroll:Wages 8500.00 USD
Liabilities:Accrued:Payroll
3. Vacation Pay (PTO) Earned
2025-03-31 * "Accrue PTO earned in March" #accrual
Expenses:Payroll:PTO 900.00 USD
Liabilities:Accrued:Payroll
4. Interest Accrued on a Loan
2025-02-29 * "Accrue monthly loan interest" #accrual
Expenses:Interest 210.00 USD
Liabilities:Accrued:Interest
5. Professional Fees (Audit/Legal)
2025-12-31 * "Accrue year-end audit fees" #accrual
Expenses:Professional:Audit 4200.00 USD
Liabilities:Accrued:Professional
6. Utilities Used but Not Billed
2025-04-30 * "Accrue April utilities" #accrual
Expenses:Utilities 95.00 USD
Liabilities:Accrued:Utilities
Reporting: "What do I owe as of a certain date?"
bean-query
is your tool for getting answers. Here’s how you can get a proper balance sheet snapshot of your accrued expenses.
Get All Accrued Liability Balances at Period-End
This query gives you the balance of each accrued liability account as of March 31, 2025.
bean-query main.beancount '
SELECT account, UNITS(SUM(position)) AS balance
FROM OPEN ON 2025-01-01 CLOSE ON 2025-04-01 CLEAR
WHERE account ~ "^Liabilities:Accrued"
GROUP BY 1
ORDER BY 1;
'
OPEN ON
sets starting balances at the period start.CLOSE ON
truncates transactions before this date (it's exclusive). That's why we use2025-04-01
to get data up to and including2025-03-31
.CLEAR
zeroes out Income and Expenses, giving you a clean balance sheet view (Assets, Liabilities, Equity).
See a Register of All Accrual Postings
If you want to see the raw transaction history for your accrual accounts:
bean-query main.beancount '
SELECT date, payee, narration, position
WHERE account ~ "^Liabilities:Accrued"
ORDER BY date;
'
Get a Single Total for All Accruals
For a quick summary of the total amount you owe:
bean-query main.beancount '
SELECT UNITS(SUM(position)) AS total_accruals
FROM OPEN ON 2025-01-01 CLOSE ON 2025-04-01 CLEAR
WHERE account ~ "^Liabilities:Accrued";
'
Controls & "Gotchas" Specific to Beancount
- Balance Assertions Timing: As mentioned, assertions check the balance at the start of the day.
2025-03-01 balance ...
runs before any transactions on2025-03-01
. Plan accordingly. - Naming and Hierarchy: A tidy tree like
Liabilities:Accrued:*
is not just for looks. It makes your queries simpler and your reports instantly understandable. - Pad with Caution: The
pad
directive can fix opening balances, but avoid using it to "fix" recurring accruals. Making explicit entries provides a clear audit trail. - As-Of Reporting: For balance-sheet snapshots, always prefer
OPEN ... CLOSE ... CLEAR
inbean-query
. This prevents income and expense accounts from polluting your liability totals.