AL+

Language: RO (română) EN (English)

Email us: paul@alplustech.com

Looking back at the week of 4–10 December 2024

A database replacement needs two kinds of evidence

Limbo's 2024 experiment paired Rust with deterministic testing. Separate simulated failure coverage from evidence of SQL and database file compatibility.

Citiți articolul în română

A database can survive a simulated storage failure and still answer a valid query differently from the engine it aims to replace. Conversely, matching a set of query results does not prove correct recovery after a partial write. A replacement needs evidence about both failure behavior and compatibility. Limbo's December 2024 announcement is a useful way to keep those obligations separate.

This November 2026 retrospective concerns the week beginning 4 December 2024. In Turso's announcement dated 10 December, Pekka Enberg and Glauber Costa presented Limbo as an official experiment. SQLite language and file-format compatibility, along with high reliability, were goals. The announcement did not establish that full parity had already been reached.

A simulator explores an execution space

Deterministic simulation makes it possible to explore controlled event sequences and reproduce a failing execution. For a database, an illustrative case might vary when an I/O operation completes or fails while checking an invariant about stored data. Keeping the sequence reproducible turns an elusive failure into something engineers can investigate. That describes a testing approach, not a test run performed for this article.

The announcement described deterministic simulation facilities in the database core and a partnership with Antithesis for system-level testing. It also reported a concrete boundary: partial-write issues in the io_uring implementation had been found through the latter approach, while the project's own simulator replaced the real I/O loop. The reported finding belongs to Turso; this article does not independently reproduce it.

That boundary is the important mechanism. A simulator controls the parts it models. If a real implementation is replaced by a simplified one, the resulting executions can reveal errors in the modeled system while missing errors inside the replaced component. This does not invalidate the simulator. It tells reviewers where another kind of evidence is needed.

Compatibility needs an observable reference

Now consider a hypothetical application that opens an existing SQLite database file, runs a query and writes an update. Its expectations include which files can be opened, which SQL is accepted and what result the operation produces. A storage invariant alone cannot establish those expectations. The application may depend on a behavior that the new engine has not implemented at all.

SQLite can serve as a reference, or oracle, for a compatibility comparison. Give both engines carefully chosen inputs and compare the behavior the application observes. The proposed comparison should include errors where they matter, not only successful rows. Differences need interpretation: a query without an ordering requirement should not be treated as incompatible solely because rows appear in a different incidental order.

File compatibility adds another dimension. Reading one small file successfully says less than reading files with the structures the application actually uses. Writing a file raises a further question about what the reference engine can subsequently read. Define the direction of the promised compatibility rather than leaving “works with SQLite” to cover every possibility.

A contemporary failure marks a boundary

In his 10 December account, Simon Willison reported successfully trying Limbo's Python bindings against a simple demonstration database. He then reported a crash with a more complex database containing SQLite full-text search tables. This is attributed firsthand evidence about his attempt, not a claim that every FTS database failed or that the same limitation exists today.

The report usefully limits what could be inferred from a simple success. It does not establish the precise root cause, and this article does not supply one. It shows why an application's real file structures belong in its compatibility inventory. A familiar Python interface and one successful query do not cover an extension-dependent database.

The business consequence is a clearer migration boundary. If search is essential to staff completing their work, accepting ordinary rows while failing to open a search-bearing database is not a minor difference for that product. If the application never uses that structure, the reported case may be outside its required subset. Product dependence determines the significance; the existence of a crash alone does not settle every adoption decision.

A constrained subset can be valuable

The strongest counterargument is that a replacement can be useful before matching an entire mature database. An application with a tightly controlled schema and query set may benefit from an architectural capability while consciously excluding unsupported behavior. Requiring universal parity before any use would rule out many legitimate experiments.

That argument works only if the subset is explicit and enforceable. Include migration scripts, maintenance tools and import paths as well as queries generated by the main application. A feature outside the subset must remain outside it through later changes. Otherwise a narrow acceptance decision quietly becomes a broad replacement claim as the product grows.

For a proposed evaluation, keep two evidence records. One identifies the modeled failures and the real components left outside the simulator. The other identifies the SQL and file behaviors compared with the reference engine. These are suggestions for investigation, not results collected here. Passing one record's cases should never be used to fill gaps in the other.

In custom software development, begin with a compatibility boundary small enough to explain to the person responsible for recovery. State what files and operations are included, what failure scenarios have evidence and what remains uncertain. The December Limbo experiment offered a promising way to explore database design. Its lasting lesson is to ask which promise each test can actually support before entrusting a product's stored data to a replacement.