WHERE filter on created_at can drop rows inside those days. It does not choose which days to open.
Your ledger
System of record
transactionsbalancesledgersidentitywrites
Lake builder
Continuous copy
Every posted record is appended to daily history
partitioned by dateCopy with a lag
stores
Daily history
Read-only, immutable
2026-09-01.parquet2026-09-02.parquet2026-09-03.parquetNever updated in place. History is append-only.
scans
DuckDB
Query engine
Reads only the days in your date range
Insights / APIFrom a ledger write to a query result
- Daily history is append-only. Insights opens every day file in your toolbar date range. Files are never updated in place.
- Transactions are lifecycle rows. Core stores each status change as its own row (
QUEUED,INFLIGHT,APPLIED, and so on). Filter bystatus, and useparent_transactionwhen you need commit or void outcomes. See Transaction lifecycle. - Balances, ledgers, and identities can repeat across days. The same ID may appear in more than one day file. Before you join them to transactions, collapse to one row per ID (for example
GROUP BY balance_idwithANY_VALUE(...)). Do not order bycreated_atto pick a “latest” wallet snapshot:created_atis when the wallet was created, so daily copies can tie and DuckDB can pick any copy. - Current wallet holdings belong on the live ledger. The lake is for history and reports. For live balance amounts, use the Data API or Ledger API.
- Parent and child rows can fall on different days. Inflight commits and voids create new rows. Set a date range wide enough to include both the parent and its outcomes, or the report can miss a resolution.
- Use
TRY_CASTon dates and amounts. See Use TRY_CAST on dates and amounts.