The problem bookkeeping solves
Imagine tracking money with a singlebalance column. Every bug is
invisible: if the number is wrong, nothing tells you where it went wrong.
Double-entry bookkeeping is the fix, and it’s an engineer’s fix: an
append-only event log with an invariant. Money is never created or
destroyed in the records — it only moves between named buckets, and every
movement records both ends. If the two ends ever disagree, you know
immediately, and you can replay the log to find out where.
Accounts are buckets with a sign convention
An account is a named bucket. Recurso provisions these automatically:
(The full chart adds TDS
Receivable, Credits & Adjustments, and Bad Debt Expense.)
Two intuitions carry you a long way:
- Assets are what you have or are owed. Liabilities are what you owe someone else — including “a month of service the customer already paid for.”
- Debit and credit are not “minus” and “plus.” They’re the two ends of a transfer: debit = where value flows to, credit = where it flows from. Debiting Cash means cash went up; crediting a liability means what you owe went up. The signs feel inverted until you stop reading them as arithmetic and start reading them as direction.
A posting is a transfer
Recurso’s ledger rows look like this — one debit account, one credit account, one amount:code saying what kind of
event produced it and a reference_id pointing at the business object.
The invariant falls out for free: since every row adds the same amount to
one side and the other, total debits always equal total credits.
Checking that is called a trial balance, and Recurso asserts it
continuously — in CI on every commit, and in your books on demand.
One subscription month, end to end
A customer subscribes at ₹4,999/month + 18% GST (₹899.82). Watch the buckets — amounts in minor units: 1. Invoice issued (Code 1 — gross, ₹5,898.82):
Debits = credits at every step. Nothing appeared or vanished — it moved,
and the log says exactly when and why.
Why bother deferring revenue?
Because “we got paid” and “we earned it” are different events, and serious finance (and ASC 606) insists you not confuse them. If a customer prepays a year and cancels in month two, the un-earned ten months were never your income — they were a liability you owed back. Deferral makes refunds, audits, and month-end close boring, which is the goal. One-off charges skip this: a setup fee is earned the moment it’s billed, so its Code-1 entry credits4000 Revenue directly.
Reconciliation: proving the log and reality agree
Balanced books can still be wrong — an invoice could exist with no postings at all, and debits would still equal credits. So Recurso runs a second check: reconciliation walks every billing record (invoices, payments, credits, wallets, write-offs) and verifies its postings exist and sum correctly — about twenty distinct checks, down to the minor unit. The number you want istotal_discrepancies: 0, and the quickstart ends by showing you exactly
that.
Where to go next
- The Ledger — every posting code, the query API, and TigerBeetle
- Revenue Recognition — schedules, the waterfall, and the monthly report
- Month-End Close — turning all of this into a one-call close pack
- Glossary — every term on this page, defined