Problems solved

Every problem, with its proof.

These are the business problems TulaDB solves, in the words of the people who feel them — and the ones it doesn't yet. Each row says what the ledger does, whether it ships today, and the test or tool that holds it in place.

87problems listed
59shipped and on by default
15shipped, switched on in configuration
4recipes built from shipped parts
9by design or not built yet — so you can plan for them

Posting money correctly

The failures that cost money directly, and the ones auditors find later.

The problem
What TulaDB does
Status & proof
One leg of a payment posts without the other, and the books stop balancing.Everyone
Every transfer debits one account and credits another atomically. Conservation is checked after every event in simulation and at the end of every chaos run. Read more →
Shippedtsim conservation; test-cluster-conservation-under-fault
A failure halfway through leaves money half-moved.Risk & audit
A posting that fails after a balance change is undone; if the undo itself fails, the node halts instead of running on an unbalanced state. Read more →
Shippedhalt reason posted_undo_failed
Two payments race and overdraw an account.Credit unions, payment providers
Limits are checked in the same step as the write, one write per account at a time — two concurrent payments cannot both pass the check. Read more →
Shippedtuladb-jepsen limits; test-limit-prefix-oracle
An e-money or wallet account exceeds its maximum balance.Payment providers
A maximum balance per account; credits that would cross it are refused. Read more →
Shippedtest-core-invariants
A fat-finger or fraudulent payment is far larger than any real one.Treasury, switch operators
A per-ledger cap on any single movement, set at creation or changed at runtime; anything above it is refused and recorded. Off until you set it. Read more →
Opt-intest-registry-admission-parity
Someone "fixes" a balance by editing it directly.Risk & audit
There is no set-balance operation. Value enters and leaves only through transfers and control accounts, so every change has a counter-entry. Read more →
By designno set-balance message in the wire protocol

Retries, resends and duplicates

Networks time out and messages get resent. None of that may move money twice.

The problem
What TulaDB does
Status & proof
A resent payment message, or a redelivered queue message, posts twice.Everyone
Each write has a durable identity — source, ledger, currency and your reference. A resend returns the original outcome instead of applying again. Read more →
Shippedtest-dup-response-contract; jepsen idempotence
A declined payment, retried, quietly succeeds.Risk & audit
A retry gets the original decline back. The answer comes from replicated state, so every node agrees. Read more →
Shippedtest-declined-retry
Duplicate protection is lost in a crash or failover.Everyone
Duplicate detection is replicated ledger state carried through snapshots, not a cache. Read more →
Shippedtest-idempotency-recovery
A momentary overload "burns" a payment reference.Platform engineering
Transient refusals write nothing, so the same reference is admitted fresh once the condition clears. Read more →
Shippedtest-reject-not-durable
A retry arriving long after the original posts again.Risk & audit
Not by default: duplicate protection lasts as long as history does, forever unless you set a retention window. With a window, a retry older than it posts again — a sizing decision. Read more →
Shippedtest-idem-retire-at-purge
A double-click in the operator console posts a payment twice.Operations
Console forms bind their reference to their contents, so a resubmitted form is the same operation. Read more →
Shippeddashboard idempotency.test.js

Holds and money in flight

Between "sent" and "accepted", funds must be unavailable to everything else — and recoverable if the payment fails.

The problem
What TulaDB does
Status & proof
Funds in flight are spent twice, or a hold is orphaned.Everyone
Hold, then post or release. Exactly one of a competing post and release wins, and open holds can be listed. Read more →
Shippedtuladb-jepsen twopc; test-2pc-*
An abandoned hold locks a customer’s funds indefinitely.Payment providers, treasury
A per-ledger expiry releases holds nobody settles; leader, followers and restarts agree on the outcome. Read more →
Opt-intest-reserve-expiry, test-dst-reserve-expiry
Stuck holds pile up unnoticed.Operations, treasury
Shipped alerts for stale and unresolved holds and for an expiry backlog. Read more →
Shippedalert group tuladb-reserve-expiry-holds; test-stale-hold-alert

Several rails, one balance

Each rail integration with its own view of the balance is where money gets spent twice.

The problem
What TulaDB does
Status & proof
Two rails approve against the same funds.Credit unions, payment providers
Every rail posts to the same account; a hold for one rail lowers what every rail can spend, checked in the same step as the write. Read more →
Shippedtuladb-jepsen limits; test-limit-prefix-oracle; test-2pc-*
Two rails’ references collide, or one rail’s resends match another’s.Switch operators, payment providers
Each rail is its own source; its references and resends are its own. Read more →
Shippedtest-cross-sdk-vectors
A rail’s refusal reason is lost.Switch operators, credit unions
A refusal is a durable record carrying the rail’s code verbatim; four-character ISO 20022 codes fit exactly. Read more →
Shippedtest-tiered-reject-positions
A misbehaving or compromised integration keeps posting.Operations, risk
Switch a source off and its writes are refused; restrict which sources may post to which ledger. Read more →
Shippedtest-source-registry-e2e
Reconciling each rail’s settlement file by hand.Finance
Search one rail’s activity in the ledger, or filter by source in the lake. Read more →
Shippedsearch_transactions by source; export source_id column
Connecting to a rail’s message network.Credit unions, hub vendors
Not in the engine: an adapter maps a rail’s messages onto holds, postings and refusals. A Real-Time Rail reference adapter is next.
Not yet—

Intraday liquidity

On an instant rail, the payments that drain a position settle before any report arrives.

The problem
What TulaDB does
Status & proof
The settlement position is breached before a report shows it.Treasury
The position is an account with a floor; a payment that would cross it is refused at the moment of posting. Read more →
Recipetest-limit-prefix-oracle
One sponsored client drains the liquidity posted for all of them.Sponsor banks, aggregators
A net debit cap per client account, changeable intraday in one call. Read more →
Recipetest-limit-prefix-oracle, test-account-key-history
Known obligations get eaten by the stream of instant payments.Treasury
Hold the obligation on the position, with expiry. Read more →
Recipetest-reserve-expiry
No intraday position curve for monitoring or audit.Treasury, risk
The export can carry both accounts’ balances after every posting; the curve is one query. Read more →
Opt-inexporter full_txn_record
Pooled account drifts from the sum of client positions.Sponsor banks, hub vendors
Position and settlement legs move in one atomic transaction. Read more →
Shippedtuladb-jepsen tiered; test-tiered-core-invariants
Liquidity alerts, forecasts, sweeps between settlement accounts, payment queueing.Treasury
—
Not yet—

Account controls

What compliance, fraud and member services need to do to an account.

The problem
What TulaDB does
Status & proof
Freeze an account (fraud, sanctions, deceased member) without losing its history.Credit unions, risk
Mark an account inactive (reversible) or closed (terminal). Accounts are never deleted. Read more →
Shippedtest-account-active-e2e
An account should only ever receive, or only ever pay out.Payment providers
One-way account flags refuse the other direction. Read more →
Shippedtest-core-invariants
Who changed this limit, and when?Risk & audit
Every change to an account’s limits and flags is kept as history. Read more →
Shippedtest-account-history
A client holds balances in several currencies.Payment providers
One account id across currencies, with a currency registry (up to 8 decimal places) and currencies that can be disabled. Read more →
Shippedtest-currency-registry-e2e

Answering "what happened?"

Support, disputes and finance need answers from records, not log archaeology.

The problem
What TulaDB does
Status & proof
Support can’t explain why a payment was refused.Operations, member services
Every decline is a record — searchable by rail, outcome, account and time. Read more →
Shippedtest-restart-reject-parity
A member paid but doesn’t see it in their history yet.Payment providers
A read can wait until it has caught up with a given write. Read more →
Shippedtest-ryw-token-bound
Paged reports drop or duplicate rows.Finance
A page never splits a batch, and paging is stable across crashes. Read more →
Shippedtest-page-order-after-crash
A query gives a partial answer while a node rebuilds.Operations
A node that cannot vouch for an answer refuses instead of returning part of one. Read more →
Shippedtest-query-rebuild-keeps-reads-closed
Reporting load slows down payments.Platform engineering
A separate read-only port, and history exported to Apache Iceberg for heavy analytics. Read more →
Shippedquery port refuses writes

Balances you can trust

A balance shown to an approval decision must be the real one.

The problem
What TulaDB does
Status & proof
A stale balance is read just after a leader change.Everyone
Balance reads on the client port are linearizable by default, including right after an election; the read-only query port can be configured to match. Read more →
Shippedtest-cluster-linearizability-failover
A balance shows money that has not committed yet.Risk & audit
Reads subtract in-flight effects until they commit. Read more →
Shippedtest-cluster-dirty-read, test-committed-balance-reads
Clock problems cause stale reads.Platform engineering
A node refuses to start with an unsafe clock-skew and heartbeat combination. Read more →
Shippedtest-cluster-clock-skew

Crashes, disks and restores

What happens to acknowledged payments when hardware fails.

The problem
What TulaDB does
Status & proof
A crash loses payments that were already acknowledged.Everyone
A payment is acknowledged only after it is on disk and confirmed by a quorum. In a power-loss test, 0 of 37,392 acknowledged writes were lost in the default mode. Read more →
Shippedtest-async-ack-power-loss; test-cluster-sync-quorum-matrix
A fast-but-lossy mode is switched on by accident.Risk & audit
The lossy mode is refused on a single node unless explicitly acknowledged in configuration. Read more →
Shippedtest-config-warn
A damaged or missing log is served as truth.Risk & audit
The node refuses to start and names the damaged range; committed writes are never truncated to make it boot. Read more →
Shippedtest-wal-boot-hole
A full disk crashes the node.Operations
Free-space reserves shed new writes before the disk fills. Read more →
Shippedtest-disk-guard
Restore to just before a bad batch.Operations, risk
Online backups with verification, and point-in-time restore by position or time from archived logs. Read more →
Opt-intest-backup-restore, test-pitr-install-chain
"Our backups have never been tested."Risk & audit
A restore-drill tool runs restores on a schedule and records the result. Read more →
Shippedtuladb_backup_catalog.py drill
An auditor wants to check a store independently.Risk & audit
Offline tools verify a store and its log chain without a running engine. Read more →
Shippedtest-verify-store, test-chain-offline-verify

Staying up

An instant rail has no maintenance window.

The problem
What TulaDB does
Status & proof
Losing a server stops payments.Everyone
A 3- or 5-node cluster keeps posting through the loss of a minority. Read more →
Shippedtest-cluster-conservation-under-fault; published chaos verdicts
A replica silently diverges from the others.Risk & audit
A replica’s acknowledgement counts only if its log chain matches the leader’s; nodes can prove state agreement at one position. Read more →
Shippedtest-cluster-chain-divergence, test-digest-at-cut
A replacement server takes over without the full history.Operations, risk
A joining node copies and verifies the full history before it can vote or serve it. Read more →
Shippedtest-cluster-join-full-sync, test-cluster-join-full-voter
Upgrading means downtime.Operations
Rolling upgrades node by node; new features switch on only when every voter supports them. Read more →
Shippedtest-upgrade-drill, test-cluster-feature-activation
Can we roll back halfway through an upgrade?Operations
Until the upgrade is finalised, a tool answers ROLLBACK SAFE or ROLLBACK NOT SAFE. After finalising, going back means a restore. Read more →
Shippedtuladb_upgrade --compat-with
Planned maintenance triggers an unplanned failover.Operations
Hand leadership to another node before maintenance. Read more →
Shippedtest-cluster-leader-transfer
A standby site can’t be promoted safely.Operations, treasury
Promote a group of standby nodes in one step. Read more →
Shippedtest-cluster-promote-standby-chaos
Two voters sit in one zone, and a zone outage loses quorum.Platform engineering
A topology policy refuses configurations that put a quorum in one failure domain. Read more →
Opt-intest-cluster-topology-failover-chaos

Peaks and overload

A retry storm or a payroll peak must slow new payments down, not break settlement.

The problem
What TulaDB does
Status & proof
A peak or retry storm collapses latency for everyone.Platform engineering, operations
An adaptive limiter refuses new writes with a retryable answer when latency would breach its target. Read more →
Opt-intest-slo-limiter, test-cluster-write-slo-guard
Payments in flight can’t complete during overload.Payment providers, treasury
With the limiter on, posting or releasing an existing hold is never shed, so money in flight always settles. Read more →
Opt-intest-slo-limiter, test-cluster-write-slo-guard
The server runs out of memory mid-write.Operations
A memory budget closes admission before the limit, and boot checks the plan fits the machine. Read more →
Opt-intest-memory-budget, test-daemon-memory-budget
Configuration tuned for the wrong hardware.Platform engineering
Autotune measures the disks and derives settings; a calibration tool finds the rate a cluster sustains. Read more →
Opt-intest-autotune, test-resource-ceiling
One slow client stalls the server.Operations
A client that stops reading is disconnected. Read more →
Shippedtest-conn-slow-io
A typo in configuration starts an unsafe node.Platform engineering
Unknown keys and unsafe timing settings refuse to boot. Read more →
Shippedtest-config-contract

Security and access

Who can move money, and how you prove it.

The problem
What TulaDB does
Status & proof
An insecure configuration goes live.Risk & audit
Beyond loopback, a node refuses to start without mTLS on its cluster port or with anonymous access above read-only. Read more →
Shippedtest-fabric-port-requires-mtls
Who can move money?Risk & audit
Four roles plus an explicit deny, checked on every message; unknown operations need the highest role. Read more →
Shippedtest-authz, test-authn-role-gate
Plugging into corporate identity.Platform engineering
Client certificates, API keys (only a digest is stored) or OIDC tokens; rights end when the token expires. Read more →
Opt-intest-authn-msg-auth
Password and key guessing.Risk & audit
Repeated authentication failures on a connection are throttled. Read more →
Shippedtest-authn-msg-auth
A stolen disk or a modified block.Risk & audit
At-rest encryption with an integrity tag; startup fails closed without the key. Read more →
Opt-inencrypted checkpoint tests; no dedicated tamper-refusal test yet
Was history altered?Risk & audit
A hash-chained audit log and a tamper-evident log mode, both verifiable offline. Read more →
Opt-intest-audit-log-chain, test-chain-mode-offline-tools
Operators move money without a trail.Risk & audit
The operator console has roles and an audit log, and can be set to refuse any action it cannot record. Read more →
Shippeddashboard backend tests
A certificate expires and takes the cluster down.Operations
Days-to-expiry is a metric; shipped alerts warn at 21 days and page at 7. Read more →
Shippedtuladb-alerts.yml
Where does our payment data go?Risk & audit
TulaDB is self-hosted: it runs in your environment and sends nothing to us. Read more →
By designself-hosted distribution; no telemetry in the engine or console
Separating tenants inside one cluster.Hub vendors, sponsor banks
Roles control operation classes, not tenants. Run a cluster per tenant, or scope tenants in your service tier. Read more →
Not yet—

Running it at 3 a.m.

The on-call engineer needs a signal and a runbook, not an investigation.

The problem
What TulaDB does
Status & proof
Alerts that don’t match what actually breaks.Operations
156 alert rules, 64 of them paging, each with a runbook; the alert pipeline watches itself. Available to design partners; not in the 0.0.1-preview downloads. Read more →
Shippeddeploy alert rules (linted)
Retry storms and decline spikes go unseen.Operations, risk
Alerts on duplicate and decline ratios. Read more →
Shippedalert group tuladb-availability
The disk fills overnight.Operations
Alerts project time-to-full before it happens. Read more →
Shippedalert group tuladb-capacity
Fitting into existing telemetry.Platform engineering
Prometheus metrics, OpenTelemetry traces, JSON or syslog logs. Read more →
Opt-inotlp_endpoint config

Finance, reconciliation and reporting

Finance works from the lake; the lake has to be exactly the ledger.

The problem
What TulaDB does
Status & proof
Finance queries load the production ledger.Finance
Committed history streams to Apache Iceberg (AWS S3 Tables, Google BigLake), off the payment path. Read more →
Opt-inexporter test suite
The lake has duplicates or gaps.Finance, risk
Each commit carries its range and a SHA-256 receipt; the exporter stops rather than skip a range. Read more →
Shippedexporter exit 87 on a reclaimed range
History is purged before it reaches the lake.Risk & audit
The ledger keeps history until the exporter has durably acknowledged it. Read more →
Shippedtest-export-lease, test-partitioned-purge-credit
The lake disagrees with the ledger.Finance
The console reconciles the lake against the ledger on a schedule and holds reports until they match; the exporter repairs on request. Read more →
Opt-inconsole reconcile_auto; exporter reconcile/repair
Comparing a new posting layer with the existing books.Credit unions
Run TulaDB beside existing posting on replayed traffic and compare from the lake. The comparison itself is yours to build. Read more →
Recipeexporter + lake query (comparison is yours to build)
Feeding postings back to the core banking system.Credit unions
The export is the outbound path today; a connector to a specific core is not built. Read more →
Not yet—

Integrating it

What the engineers wiring it in will hit first.

The problem
What TulaDB does
Status & proof
Every language handles errors differently.Platform engineering
Five SDKs (C, Go, Java, Python, Rust) share one status contract and one retry rule. Read more →
Shippedcontracts/status-codes.env; SDK test suites
Load balancers page on business declines.Platform engineering
Three REST gateways answer identically: a decline is 200 with ok:false, a retryable refusal is 503 with Retry-After, a duplicate is 409. Read more →
Shippedshared gateway contract suite
Unknown outcome after a dropped connection.Platform engineering
Resubmit with the same reference; the original outcome comes back. Read more →
Shippedtest-dup-response-contract
Reusing a reference with a different amount.Platform engineering
The original wins and is returned; there is no mismatch error. Use one reference per payment. Read more →
By designtest-dup-response-contract
Installing it safely.Platform engineering
The installers verify their own checksum, check every download against embedded digests and refuse to run piped from the network; the native installer requires a cosign signature. Images are pinned by tag, not digest. Read more →
Shippedtuladb-install install.sh
Packages on public registries (PyPI, Maven, crates).Platform engineering
SDKs ship as a preview distribution. Read more →
Not yet—
Certifications (SOC 2, PCI DSS, ISO 27001).Risk & audit
None yet. Read more →
Not yet—

Read against the engine's main branch (fa7b2206) and the exporter, console, deploy and SDK repositories on 2026-10-29. Test names are build targets in the engine repository unless another repository is named. The engine's core guarantees are detailed on the evidence page; tuladb-jepsen is our own Jepsen-style checker, not a Jepsen analysis.

Design partners

Find the rows that matter to you — then test them.

Bring the problems you care about to a design-partner conversation, and we'll scope an evaluation that exercises exactly those rows in your environment.