# Financial Ledger System Low-Level Design: Double-Entry Accounting, Account Hierarchy, and Reporting

Source: https://www.techinterview.org/post/3233469735/lld-ledger-system/
Updated: 2026-06-30 · techinterview.org

## Double-Entry Bookkeeping

Every financial transaction in the system uses double-entry bookkeeping: each transaction debits one or more accounts and credits one or more accounts, with total debits always equaling total credits. This invariant — the accounting equation — ensures the ledger is always balanced:


```
Assets = Liabilities + Equity
```

No single-sided entries are permitted. Every journal entry is validated before persistence: `SUM(debit_amounts) = SUM(credit_amounts)` must hold exactly. If this check fails, the entry is rejected.

## Chart of Accounts

The chart of accounts is a hierarchical taxonomy of all accounts in the organization:


```
accounts {
  account_id      UUID PK
  org_id          UUID FK
  parent_account_id UUID FK nullable
  name            VARCHAR(255)
  code            VARCHAR(20)    -- e.g. "1010"
  type            ENUM(ASSET, LIABILITY, EQUITY, REVENUE, EXPENSE)
  normal_balance  ENUM(DEBIT, CREDIT)
  is_leaf         BOOLEAN
  active          BOOLEAN DEFAULT true
}
```

Example hierarchy: Assets (1000) → Current Assets (1010) → Cash (1011); Liabilities (2000) → Accounts Payable (2010). Normal balance is DEBIT for assets and expenses; CREDIT for liabilities, equity, and revenue. This determines how increases and decreases are recorded.

## Journal Entry Schema

A journal entry records one complete transaction across two or more accounts:


```
journal_entries {
  journal_id   UUID PK
  org_id       UUID FK
  description  VARCHAR(500)
  date         DATE
  reference    VARCHAR(100)   -- invoice number, receipt, etc.
  created_by   UUID FK users
  created_at   TIMESTAMP
}

journal_lines {
  line_id      UUID PK
  journal_id   UUID FK
  account_id   UUID FK
  debit_amount  DECIMAL(18,4) DEFAULT 0
  credit_amount DECIMAL(18,4) DEFAULT 0
  description  VARCHAR(255)
}
```

A journal entry with two lines (one debit, one credit) is the simplest case. Complex transactions can span many lines, as long as the total debit equals total credit.

## Journal Entry Immutability

Once posted, journal entries are never modified or deleted. This is a core accounting principle — altering historical records destroys the audit trail and violates accounting standards. Corrections use a two-step process:

  - **Reversing entry:** create a new journal entry that exactly inverts the original (debits and credits swapped) to cancel its effect

  - **Correcting entry:** create a new journal entry with the correct amounts

The original entry, the reversing entry, and the correcting entry all remain in the ledger, linked by a `reversal_of` reference field.

## Account Balance Calculation

The current balance of an account is derived by summing all journal lines for that account:


```
-- For DEBIT-normal accounts (Assets, Expenses):
balance = SUM(debit_amount) - SUM(credit_amount)

-- For CREDIT-normal accounts (Liabilities, Equity, Revenue):
balance = SUM(credit_amount) - SUM(debit_amount)
```

For performance, a materialized `account_balances` table stores running totals, updated transactionally on each journal entry insert. Point-in-time balances are computed by summing lines up to a given date.

## Period Closing

At the end of each accounting period (month, quarter, year):

  - Calculate net income: SUM(revenue account balances) - SUM(expense account balances)

  - Post a closing journal entry: debit all revenue accounts to zero, credit all expense accounts to zero, with the net income flowing to Retained Earnings (equity account)

  - Mark the period as CLOSED in the `accounting_periods` table

  - Reject any new journal entries dated within a closed period

After closing, revenue and expense account balances reset to zero for the new period, while asset, liability, and equity balances carry forward.

## Balance Sheet

The balance sheet is a point-in-time report showing financial position. It aggregates account balances as of a specific date:

  - **Assets section:** sum of all ASSET account balances grouped by sub-category

  - **Liabilities section:** sum of all LIABILITY account balances

  - **Equity section:** sum of all EQUITY account balances including retained earnings

  - **Validation:** Total Assets must equal Total Liabilities + Total Equity

## Profit and Loss Report

The P&L (income statement) covers a date range and shows:

  - **Revenue:** sum of all REVENUE account activity for the period

  - **Expenses:** sum of all EXPENSE account activity, broken down by category

  - **Net Income:** Revenue - Expenses

Both reports support drill-down: clicking a line item shows the individual journal entries that compose it.

## Multi-Currency Support

All amounts are stored in the organization's functional currency. Foreign currency transactions are recorded with the exchange rate at transaction date:


```
journal_lines + { foreign_currency CHAR(3), foreign_amount DECIMAL(18,4), exchange_rate DECIMAL(12,6) }
```

At period end, a revaluation run recalculates the functional currency value of foreign-denominated balances at the current exchange rate. The difference is posted as an unrealized FX gain or loss to a dedicated equity account.

## Audit Trail

Every journal entry is immutable and carries the creator's user_id and creation timestamp. No UPDATE or DELETE is permitted on journal_entries or journal_lines — enforced at the database level via trigger or application-level constraint. The full history of every transaction is always recoverable, making the ledger suitable for external audit and regulatory compliance.

See also: [Stripe Interview Guide 2026: Process, Bug Bash Round, and Payment Systems](https://www.techinterview.org/post/3233460268/stripe-interview-guide-2026-process-bug-bash-round-and-payment-systems/)

See also: [Coinbase Interview Guide](https://www.techinterview.org/post/3233459920/coinbase-interview/)

See also: [Scale AI Interview Guide 2026: Data Infrastructure, RLHF Pipelines, and ML Engineering](https://www.techinterview.org/post/3233460275/scale-ai-interview-guide-2026-data-infrastructure-rlhf-pipelines-and-ml-engineering/)
