Saltar al contenido principal

The Accounting Cycle, Beancount-Style

· Lectura de 9 minutos
Mike Thrift
Mike Thrift
Marketing Manager

Financial statements don't appear by magic. They are the final product of a structured, repeatable process known as the accounting cycle. While the principles are universal, the tools you use can dramatically change the experience. This guide walks you through the accounting cycle with a focus on Beancount, the powerful plain-text accounting tool.

We'll see how Beancount's text-first approach eliminates tedious steps, what you should automate, and which reports give you the clearest picture of your financial health. 🧑‍💻

2025-08-13-the-accounting-cycle-beancount-style


TL;DR: The Beancount Workflow

  • Capture & Journal: Record every transaction as a clean, double-entry posting in your .beancount text file.
  • Validate & Reconcile: Use balance assertions to confirm your ledger matches bank statements and run bean-check to catch errors.
  • Review: Generate an unadjusted trial balance for a quick sanity check.
  • Adjust: Post entries for accruals, deferrals, depreciation, and other period-end items.
  • Re-review: Check the adjusted trial balance to ensure everything is correct.
  • Publish & Close: Generate your Income Statement, Balance Sheet, and Cash Flow statement. Closing the books is optional in Beancount, as reports are date-aware.

This flow can be visualized like this:


Step 1: Capture and Record Transactions

This is the foundational step. Every financial event—a sale, a purchase, a bank fee—must be recorded. In Beancount, you do this by creating transactions in a simple text file, typically named main.beancount or organized into multiple files by year.

Each transaction must follow the rules of double-entry bookkeeping, meaning the sum of all postings must be zero. Beancount enforces this for you.

2025-08-10 * "Walmart" "Purchase of office supplies"
Expenses:Office:Supplies 45.67 USD
Assets:Bank:Checking -45.67 USD
  • Pro-Tip: Use tags like #project-phoenix or #client-acme to add dimensions to your data. This makes querying and reporting incredibly flexible later on.

Reconciliation Hygiene ✅

The most powerful feature for ensuring accuracy is the balance assertion. At the end of a statement period (e.g., end of the month), you declare what the balance of an account should be.

2025-08-31 balance Assets:Bank:Checking  12345.67 USD

If the sum of all transactions affecting Assets:Bank:Checking up to that date doesn't equal 12345.67 USD, Beancount will raise an error. This simple directive turns your ledger into a self-auditing document.

For those backfilling historical data, the pad directive can automatically create a balancing transaction to make your opening balances match your first assertion.


Step 2: "Post to the Ledger" (A Freebie!)

In traditional accounting systems, you first write entries in a "journal," and then a separate "posting" step copies those values to the "general ledger."

With Beancount, your .beancount file is both the journal and the ledger. When you write and save a transaction, you've already posted it. There is no separate step. This directness is a core advantage of plain-text accounting—what you see is what you get.


Step 3: Prepare an Unadjusted Trial Balance

Before you start making adjustments, you need a quick "does this all add up?" check. A trial balance is a simple report that lists every account and its total balance. The grand total of all debit balances must equal the grand total of all credit balances.

You can generate this with a simple query:

bean-query main.beancount \
"SELECT account, sum(position) GROUP BY 1 ORDER BY 1"

Or, for a more visual approach, open your ledger in Fava (the web interface for Beancount) and navigate to the "Trial Balance" report. Look for anything unusual—an asset account with a credit balance, or an expense account with a strange value.


Step 4: Book Adjusting Entries

Adjusting entries are crucial for accurate reporting under the accrual basis of accounting. They ensure that revenues are recognized when earned and expenses are recognized when incurred, regardless of when cash changes hands.

Common adjustments include:

  • Accruals: Recording revenue you've earned but haven't invoiced yet, or an expense you've incurred but haven't paid.
  • Deferrals: Handling prepayments. If a customer pays you for a year of service upfront, you book it as a liability (Liabilities:UnearnedRevenue) and recognize 1/12th of it as income each month.
  • Non-Cash Items: Recording things like depreciation of assets.
  • Corrections: Fixing errors or accounting for missed items from bank feeds, like a small interest payment.

Example: Accruing Revenue

You finished a project on August 31st but won't send the invoice until September. To recognize the income in the correct period (August), you make an adjusting entry:

2025-08-31 * "Accrue revenue for client project #1042"
Assets:AccountsReceivable 3000.00 USD
Income:Consulting -3000.00 USD

Example: Recording Depreciation

Your company has a depreciation schedule for its assets. At the end of the period, you book the expense:

2025-12-31 * "Annual depreciation on computer equipment"
Expenses:Depreciation 4800.00 USD
Assets:Fixed:AccumulatedDepreciation -4800.00 USD

Step 5: Run an Adjusted Trial Balance & Validate

Once your adjusting entries are in, run the trial balance report again. This is your Adjusted Trial Balance. It provides the final set of numbers that will be used to create the financial statements.

This is also the perfect time to run Beancount's built-in sanity check:

bean-check main.beancount

This command verifies all syntax, balancing rules, and assertions. If it runs without any output, your books are mechanically sound.


Step 6: Publish Financial Statements 📊

This is the payoff. Using the numbers from your adjusted trial balance, you can now generate the key financial reports. Fava is the easiest way to do this, as it provides interactive, drill-down reports out of the box.

  • Income Statement (Profit & Loss): Shows your revenues and expenses over a period, resulting in your net income or loss.
  • Balance Sheet: A snapshot of what you own (Assets) and what you owe (Liabilities), as well as your net worth (Equity), on a specific date.
  • Cash Flow Statement: Reconciles your starting cash with your ending cash by showing where money came from and where it went.

For custom reports, you can use Beancount Query Language (BQL). Here’s a query for a monthly income statement:

-- P&L for August 2025
SELECT account, sum(position)
WHERE account ~ '^(Income|Expenses)'
AND date >= 2025-08-01 AND date <= 2025-08-31
GROUP BY account ORDER BY account;

Step 7: Closing the Books (Optional)

In traditional accounting, the "closing" process involves creating journal entries to zero out all temporary accounts (Income and Expenses) and transfer the net income into an equity account called Retained Earnings. This formally resets the temporary accounts for the next year.

In Beancount, this step is usually unnecessary. Fava's reports are date-aware; if you ask for a 2025 P&L, it will only use 2025 data. The balances don't "spill over." Most users simply leave the balances as they are.

However, if you need to perform a formal close for compliance or shareholder reporting, you can do so with a simple year-end transaction that moves the total income and expense balances into Equity:Retained-Earnings.


A Practical Monthly Close Checklist

Here’s a repeatable checklist to close your books each month using Beancount.

  • Capture: Import all bank and credit card transactions. Manually enter any cash expenses or out-of-band items.
  • Reconcile: Add balance assertions for all bank accounts, credit cards, and loan accounts, matching them to your statements.
  • Review: Scan the unadjusted trial balance in Fava. Investigate any strange or unexpected balances. Check for stale unpaid invoices (Assets:AccountsReceivable) or bills (Liabilities:AccountsPayable).
  • Adjust: Book entries for accrued revenue/expenses, deferred revenue, and any necessary corrections.
  • Validate: Run bean-check. Review the final adjusted trial balance.
  • Publish: Generate the P&L and Balance Sheet. Send them to stakeholders or save them for your records.
  • Wrap-up: Optionally, perform a closing entry if your business requires it. Archive a copy of your .beancount files for the period.

Why Beancount Shines for the Accounting Cycle

  • Transparency and Auditability: Your ledger is a text file. You can use git to version control your financial history, review changes with diff, and collaborate with your accountant in a clear, unambiguous format.
  • Total Control: You define your chart of accounts. You aren't locked into a software vendor's structure. Your data is yours, forever, in an open format.
  • Unmatched Power: The combination of SQL-like queries (BQL) and a rich web interface (Fava) gives you unparalleled power to slice, dice, and understand your financial data.

Copy-Paste Snippets to Get Started

Simple Chart of Accounts:

option "title" "My Personal Ledger"
option "operating_currency" "USD"

;; --- Accounts ---
1970-01-01 open Assets:Bank:Checking
1970-01-01 open Assets:AccountsReceivable
1970-01-01 open Liabilities:CreditCard
1970-01-01 open Liabilities:UnearnedRevenue
1970-01-01 open Equity:Owner:Capital
1970-01-01 open Equity:Retained-Earnings
1970-01-01 open Income:Consulting
1970-01-01 open Expenses:Office:Supplies
1970-01-01 open Expenses:Software
1970-01-01 open Expenses:Depreciation

Useful BQL Query:

-- Find all customers with an outstanding balance
SELECT payee, sum(position)
WHERE account = 'Assets:AccountsReceivable'
GROUP BY payee
HAVING sum(position) > 0
ORDER BY sum(position) DESC;

By mapping the timeless accounting cycle to Beancount's modern, text-based tools, you gain a system that is robust, transparent, and built to last. Happy bookkeeping!