Core Concepts

  • Movements — directed flows of value from one account to another, not debit/credit legs
  • Batches — linked movements sharing a batch ID for compound transactions
  • Same-exponent rule — movements between accounts with different exponents are rejected (currency conversion must be explicit)
  • Integer amounts — stored as int64 in the smallest currency unit
  • Hierarchical accountsType:Product:AccountID:Address

.goluca Plain Text Format

# A dividend payment
2026-02-07 * Dividend payment
  Asset:Cash  Equity:Capital "Dividend" 200.00 GBP

# Linked payroll movements
2026-02-01 * Payroll
  +Income:Salary  Asset:Bank "net salary" 4000.00 GBP
  +Income:Salary  Expense:Tax "income tax" 1000.00 GBP

# Pending transaction
2026-03-01 ! Pending invoice
  Asset:Bank  Expense:Food 15.50 GBP

Import / Export

Read and write .goluca files with tree-sitter-powered parsing.

// Import
l.Import(file, nil)

// Export
l.Export(os.Stdout)

Balance Queries

Current, point-in-time, path-aggregated, and daily balances.

l.Balance(acctID)
l.BalanceAt(acctID, t)
l.BalanceByPath("Asset:", t)
l.DailyBalances(acctID, from, to)

Interest Engine

Daily interest accrual computed in-transaction with live balance projections.

l.RecordMovementWithProjections(
  from, to, amt, t, desc,
)

Documentation

DocumentDescription
READMEProject overview and chart of accounts
Plain text syntax.goluca format reference (arrow variants, linked movements, parameters)
Ledger interfaceInterface method groups, backend capabilities (SQL/Mem), bitemporal notes, future directions
Database schemaTable definitions, columns, indexes, and ER diagrams (generated by tbls)
BenchmarksPerformance benchmarks and analysis
Balance typesBIGINT vs DOUBLE vs NUMERIC — sub-ms lookups at 36M rows
Compound movementsWrite-time projection: ~586 TPS, eliminates batch processing
SCVSingle Customer View generation and query optimisation
Ledger backendsMemLedger vs SQLLedger vs API — performance across backends

Quick Start

go get github.com/drummonds/go-luca

import (
    "github.com/drummonds/go-luca"
    _ "github.com/drummonds/go-postgres"
)

l, _ := luca.NewLedger(":memory:")
defer l.Close()

cash, _ := l.CreateAccount("Asset:Cash", "GBP", -2, 0)
bank, _ := l.CreateAccount("Asset:Bank", "GBP", -2, 0)
l.RecordMovement(cash.ID, bank.ID, 10000, time.Now(), "Transfer")

References