Release Notes
Added
- stress: Add support for BEGIN CONCURRENT transactions (Pekka Enberg)
- stress: add semi colon to transaction statements when printing to log file (Pedro Muniz)
- Add scripts/corruption-debug-tools (Jussi Saurio)
- add more asserts in balance operation (Pedro Muniz)
- bindings/java: implement JDBC4 CharacterStream binding methods (Orange banana)
- add --db-ref optional arg to run turso-stress against "template" database (Nikita Sivukhin)
- support
format()function (Fahd Ashour) - feat(extensions): add stddev aggregate function to percentile module (Kelvin)
- simulator: add proper handling for deffered transactions in shadow state (Pedro Muniz)
- feat: Add support for HAVING without GROUP BY (Nuno Gonçalves)
- Implement foreign key actions (Preston Thorpe)
- implement pragma cache spill (Preston Thorpe)
- Add multiverse debugging instructions (Mikaël Francoeur)
- Implement busy handlers/callbacks (Preston Thorpe)
- add readonly checks to ensure we do not change the header (Pedro Muniz)
- implement state machine for
op_journal_mode(Pedro Muniz) - Add io_uring option for IO backend to simulator (Preston Thorpe)
- core/storage: implement Cache Spilling (Preston Thorpe)
- Add dotnet bindings to Turso (Kopylov Dmitriy)
- fix bug in the sync engine wasm implementation (Nikita Sivukhin)
- feat(hash-join): add hash matching for equivalent integer and real values (Nuno Gonçalves)
- implement state machine for parsing input in CLI (Pedro Muniz)
- add rust-analyzer component to toolchain (Pedro Muniz)
- Add script to run SQLancer against turso + fix some bugs found by doing so (Jussi Saurio)
- Add greedy join ordering for large queries (>12 tables) (Jussi Saurio)
- core/mvcc/cursor: add missing reset state in
next(Pere Diaz Bou) - Add PR template (Preston Thorpe)
- fix: JSON_INSERT now correctly inserts new keys in nested objects (Mikaël Francoeur)
- Remove unused parameter in
limbo_exec_rowsand add ergonomic ExecRows trait for testing (Pedro Muniz) - translate/optimizer: Finish implementing ANALYZE (Preston Thorpe)
- core/mvcc/cursor: implement count (Pere Diaz Bou)
- support libsql:// protocol as a sync url in python driver (Nikita Sivukhin)
- initialize global header on bootstrap (Pedro Muniz)
- Rust binding add prepare to transaction (Dave Warnock)
- add turso bot config (Pedro Muniz)
- feat: adding check for unquoted literals in values() (Rohith Suresh)
- Improved Python driver with opt-in asyncio support (Nikita Sivukhin)
- tcl,makefile: add tcl test infraestructure for mvcc (Pere Diaz Bou)
- core/mvcc: fix bounds check new rowid (Pere Diaz Bou)
- Added dot product vector distance (Tejas)
- sim: add binary tool that converts plan.sql to rust test file (Jussi Saurio)
- Add explanation for concurrent transactions (Pekka Enberg)
- testing/fuzz: Add new fuzzer for joins (Preston Thorpe)
- add lib-release profile (Nikita Sivukhin)
- planner/vdbe: implement Hash Joins as an alternative to Ephemeral Indexes (Preston Thorpe)
- Add sync support to the SDK kit (Nikita Sivukhin)
- fix/mvcc: always reinitialize index iterator on seek (Jussi Saurio)
- translate/vdbe: add bloom filter (Preston Thorpe)
- mvcc: implement logical log recovery for indexes + checkpointing of indexes (Jussi Saurio)
- Docs: add table of contents to CONTRIBUTING.md (Fahd Ashour)
- finish implementing "quote" scalar function for blob types (Preston Thorpe)
- add alias to colnames explicitly as column-N (Pavan Nambi)
- Add
#[turso_macros::test]to automatically create tests that can run MVCC with minimal code changes (Pedro Muniz) - mvcc: introduce stateful "dual cursor" (Jussi Saurio)
- introduce program execution state in order to run stmt to completion in case of finalize or reset (Nikita Sivukhin)
- mvcc: add some plumbing for index support (Jussi Saurio)
- core/mvcc/tests: add fuzz test for mvcc with checkpoint and with CRUD ops (Pere Diaz Bou)
- translate/planner: Implement Index creation on arbitrary expressions (Preston Thorpe)
- Support table xinfo (Nikita Sivukhin)
- core/mvcc/cursor: implement prev and last (Pere Diaz Bou)
- Trigger support (Jussi Saurio)
- translate/insert: Implement INSERT OR REPLACE (Preston Thorpe)
- Add ColDef struct to make schema::Column creation more ergonomic (Preston Thorpe)
- Support DELETE ... RETURNING (Jussi Saurio)
- Refactor RETURNING to support arbitrary expressions (Jussi Saurio)
- bindings/java: implement JDBC4 InputStream binding methods (ASCII/Binary, no-length and long overloads) (Orange banana)
- Add RowSet<Add/Read/Test> instructions and rowset implementation (Jussi Saurio)
- bindings/java: implement stream binding methods (int, InputStream, int) in JDBC4PreparedStatement (Orange banana)
- workflows: Add GITHUB_TOKEN to all Nyrkiö steps (Henrik Ingo)
- extensions/vtabs: implement remaining opcodes (Preston Thorpe)
- Throw an error when adding generated columns via an alter table (Rohith Suresh)
- add some docs for index method (Nikita Sivukhin)
- bindings/java: Implement setObject(int, Object) in JDBC4PreparedStatement (Orange banana)
Updated
- Minor cleanups in function.rs and refactoring allocations (Preston Thorpe)
- WAL: Stop copying page buffers during checkpoint (Preston Thorpe)
- test runner: Test Converter (Pedro Muniz)
- core/storage: Eliminate buffer copy in begin_write_btree_page() (Pekka Enberg)
- Test runner Foundation (Pedro Muniz)
- show failure output in the end with cargo nextest (Pedro Muniz)
- core/storage: Zero remaining buffer bytes in begin_write_btree_page() (Pekka Enberg)
- core/storage: Make PagerInner::buffer use Arc<Buffer> (Pekka Enberg)
- Adjust merge script to truncate the PR template (Preston Thorpe)
- Improvements to turso_stress (Mikaël Francoeur)
- Page management cleanups (Pekka Enberg)
- btree: reset
AdvanceStateafter last state transition (Pedro Muniz) - Make BTree and MVCC cursor
Send + Sync(Pedro Muniz) - Raise log level polling frequency (Mikaël Francoeur)
- btree/pager: performance tuning (Preston Thorpe)
- chore/btree: remove unused code (Jussi Saurio)
- Modify bench-profile to allow generating better flamegraphs (Jussi Saurio)
- all-mvcc: uncomment working tests (Pere Diaz Bou)
- perf/sorter: sort pointers instead of records, use arena allocation (Jussi Saurio)
- Remove TursoDBFactory (Mikaël Francoeur)
- Save sync configuration (Nikita Sivukhin)
- Optimized RecordCursor, Remove read_varint_fast (Khashayar Fereidani)
- Run statements to completion on reset (Martin Mauch)
- adjust tpc-h bench script to more easily compare results (Preston Thorpe)
- stress: use multithreaded runtime (Jussi Saurio)
- Conflict end txn (Nikita Sivukhin)
- Accept SQL query using
AsRef<str>instead of&str(Arto Bendiken) - core: remove mutex from ImmutableRecord::cursor (Jussi Saurio)
- Enable tokio-unstable in Antithesis image (Mikaël Francoeur)
- Prevent dropping columns that contain fk references (Preston Thorpe)
- lint/perf: deny eager fallback function calls (ok_or, map_or, unwrap_or) (Jussi Saurio)
- reset statement in query() (Mikaël Francoeur)
- User rust-gdb instead of gdb (Mikaël Francoeur)
- Antithesis observability improvements (Mikaël Francoeur)
- Rust bindings sync (Nikita Sivukhin)
- Refactor/improve performance of commit path (Preston Thorpe)
- Sdk kit rust bindings (Nikita Sivukhin)
- Yet another refactor of INSERT translation (Preston Thorpe)
- stress: Make SQLite integrity check more explicit (Pekka Enberg)
- Sdk kit refactoring (Nikita Sivukhin)
- perf/vdbe: reuse&clear ephemeral cursor on repeat invocations (Jussi Saurio)
- perf/prepare: various optimizations (Jussi Saurio)
- Improve lexer performance by using SIMD (Khashayar Fereidani)
- Remove unnecessary
CellandRefCellfor better multithreaded safety (Pedro Muniz) - Partial sync experimental (Nikita Sivukhin)
- remove unneeded Result in exec unixepoch (Juan V. García)
- Lexer/Parser Optimization and refactoring (Khashayar Fereidani)
- tcl: run PRAGMA journal_mode=experimental_mvcc with mvcc (Pere Diaz Bou)
- SDK tweaks (Nikita Sivukhin)
- core/mvcc: set_null_flag(false) when seek is called (Pere Diaz Bou)
- Mark triggers as experimental (Jussi Saurio)
- Set all testing dbs to WAL journal mode (Preston Thorpe)
- Remove run once from
Statement(Pedro Muniz) - Use u64::from instead of .into() (Elina)
- remove the warning directive to allow environment filter to work (Pedro Muniz)
- core/execute: use same code for generating rowid in mvcc as in btree (Pere Diaz Bou)
- Improve MVCC DX by dropping
--experimental-mvccflag (Pekka Enberg) - aws/sim: disable io-uring (Jussi Saurio)
- Local sync server (Nikita Sivukhin)
- Simplify slot bitmap to remove complex unused optimizations (Preston Thorpe)
- clean up core tester to use
conn.executeandconn.exec_rowsfor parsing correctly the expected values from select queries (Pedro Muniz) - Connection small refactor (Dave Warnock)
- Enable MVCC with
PRAGMA journal_mode(Pedro Muniz) - propagate partial sync settings in the web (Nikita Sivukhin)
- Consider Order by expressions collation when deciding candidate index for iteration (Pedro Muniz)
- Checkpoint cleanup (Jussi Saurio)
- use cmath from system libraries only in tests in order to be more portable (Nikita Sivukhin)
- No tempfiles on wasm (Nikita Sivukhin)
- core: Make Pager thread-safe (Pekka Enberg)
- update go mod name as we will serve module through custom proxy (Nikita Sivukhin)
- Install sqlite locally to run tests and other scripts (Pedro Muniz)
- rename speculative load to prefetch (docs already uses this terminology) (Nikita Sivukhin)
- docs: update clippy command in CONTRIBUTING.md to match CI job (Nuno Gonçalves)
- stress: Make random seed configurable (Pekka Enberg)
- Devcontainer setup (Nikita Sivukhin)
- core/mvcc/cursor: return previous max id (Pere Diaz Bou)
- Update wording of AI section of PR template (Jussi Saurio)
- whopper: Simulate time (Pekka Enberg)
- increase lantency check for flaky test in test_read_path.rs (Preston Thorpe)
- run get(...) to completion - otherwise INSERT ... RETURNING will be executed incorrectly (Nikita Sivukhin)
- ci: run TCL tests for MVCC under CI (Pere Diaz Bou)
- Get mutable reference to table in Schema so we can modify it with
Arc::make_mut(Pedro Muniz) - also check for None
checkpointed_txid_max_oldwhen determining ifRowVersionexists in the Db (Pedro Muniz) - Go driver (Nikita Sivukhin)
- Minor improvements and refactoring in btree.rs (Preston Thorpe)
- revert change in index_scan_compound_key_fuzz (Pedro Muniz)
- Make
checkpointed_txid_max_oldbe anOptional<NonZeroU64>(Pedro Muniz) - Remove some useless clones in pager.rs (Preston Thorpe)
- upgrade cargo dist to 0.30.2 (Nikita Sivukhin)
- Partial sync improvements (Nikita Sivukhin)
- Prevent concurrent tx ctrl and write (Nikita Sivukhin)
- core/mvcc/cursor: ignore non visible rows on "last" (Pere Diaz Bou)
- core/mvcc/tests: un-ignore seek tests (Pere Diaz Bou)
- CI: simulator tweaks (Jussi Saurio)
- chore: remove experimental_indexes feature flags (Jussi Saurio)
- do not propagate the MvStore to opcodes (Pedro Muniz)
- Run BEFORE and AFTER update triggers on upserts (Mikaël Francoeur)
- Ignore SQLITE_BUSY during auto-checkpoint (Mikaël Francoeur)
- Allocate Page 1 in pager on open (Pedro Muniz)
- Prevent creating index on rowid pseudo-column (Mikaël Francoeur)
- Improve Android compatibility (Martin Mauch)
- Simulator Roadmap (Alperen Keleş)
- guard subjournal access within single connection (Nikita Sivukhin)
- Turso sdk kit version (Nikita Sivukhin)
- Automatically Propagate Encryption options (Pedro Muniz)
- core/mvcc: state machines for
prev,next,exists,rewind,last(Pere Diaz Bou) - btree/balance: assert that if multiple overflow cells, they are adjacent sequential (Jussi Saurio)
- simulator: generate more INSERT INTO ... SELECT self-inserts (Mikaël Francoeur)
- Arc swap MvStore + centralize MvStore acquisition (Pedro Muniz)
- mvcc: do not store index data twice in Row (Jussi Saurio)
- Col name in trigger subquery (Rohith Suresh)
- Update AEGIS crate version (Avinash Sajjanshetty)
- SDK kit (Nikita Sivukhin)
- Ensure LIKE is case-sensitive for non-ASCII characters (Tejas)
- sim/aws: memory IO 100% of the time, differential 50% of the time (Jussi Saurio)
- mvcc: reconstruct index rows on logical log recovery (Jussi Saurio)
- More mvcc index stuff (Jussi Saurio)
- mvcc: make more MvccLazyCursor ops compatible with indexes (Jussi Saurio)
- drop triggers if table drops (Pavan Nambi)
- Kill unwrap() calls in MVCC module (Pekka Enberg)
- Kill unwrap() in vector module (Pekka Enberg)
- Kill unwrap() calls in VDBE module (Pekka Enberg)
- Tidied imports in Rust binding example without unwrap (Dave Warnock)
- Rust binding example without unwrap (Dave Warnock)
- Kill unwrap() calls in JSON module (Pekka Enberg)
- use i64 for registers p1,p2,p3,p5 in EXPLAIN output (Mikaël Francoeur)
- Kill unwrap() in macros (Pekka Enberg)
- Kill unwrap in incremental module (Pekka Enberg)
- mvcc: refactor RowID.row_id to be either i64 or a record (Jussi Saurio)
- Kill unwrap() calls in extensions (Pekka Enberg)
- SQLite C API improvements (Nikita Sivukhin)
- simulator: only check all tables if we have any tables to check (Pedro Muniz)
- core: Switch to parking_lot::Mutex (Pekka Enberg)
- Simulator: refactor and simplify
InteractionPlan(Pedro Muniz) - Enable nested self-inserts in simulator (Mikaël Francoeur)
- correct order in column creation in join tests (Pavan Nambi)
- Nyrkiö: Set all comment-on to false (Henrik Ingo)
- Partial sync basic (Nikita Sivukhin)
- Use
AsValueRefin more functions (Pedro Muniz) - treat parameters as "constant" within a query (Nikita Sivukhin)
- Completion: make it Send + Sync (Nikita Sivukhin)
- core/mvcc: use btree cursor to navigate rows (Pere Diaz Bou)
- core: update aegis (Daeho Ro)
- Refactor affinity conversions for reusability (Pedro Muniz)
- Create
AsValueReftrait to allow us to be agnostic over ownership ofValueorValueRef(Pedro Muniz) - Move value functions to separate file (Pedro Muniz)
- Avoid heavy macro (Nikita Sivukhin)
- Stop blob json parsing at null terminator (Duy Dang)
- core/translate: Remove unused ParamState (Preston Thorpe)
- Toy index improvements (Nikita Sivukhin)
- use dyn DatabaseStorage instead of DatabaseFile (Nikita Sivukhin)
- Prevent DROP TABLE when table is referenced by foreign keys (Joao Faria)
- core/vdbe Handle renaming child FK definitions in rename table stmt (Preston Thorpe)
- Prevent misuse of subqueries that return multiple columns (Jussi Saurio)
- Optimize and refactor schema::Column type (Preston Thorpe)
- Clean up Connection::from_uri() by using DatabaseOpts (Rohith Suresh)
- Select correct collation sequence for compound select (Pedro Muniz)
- core: Disable autovacuum by default (Pekka Enberg)
- Make mimalloc dependency optional (Pekka Enberg)
- Update Java package version in scripts/update-version.py (Pekka Enberg)
Fixed
- stress: Keep going on I/O errors instead of panicking (Pekka Enberg)
- fix: lint warnings unused variable/import in release build (Khashayar Fereidani)
- integrity check: do not throw errors if pending byte page is never used (Pedro Muniz)
- fix(storage): improve error message for truncated database files (Srinivas A)
- fix/pager&wal: ensure wal write lock held when rolling back frame_cache (Jussi Saurio)
- Enable debug_assertions for antithesis profile (Pekka Enberg)
- General improvements, micro-optimizations and bug fix for core/functions (Khashayar Fereidani)
- fix dockerfiles (Jussi Saurio)
- Fix DROP TABLE to properly handle FK actions and allow for orphaned/NULL FK refs (Preston Thorpe)
- core/mvcc/logical_log: off by one error reading logical log encrypted (Pere Diaz Bou)
- Fix squeue overflow issue in io_uring (Preston Thorpe)
- Affinity fixes (Pedro Muniz)
- Read only fixes (Pedro Muniz)
- slightly adjust fixed unstable test (Nikita Sivukhin)
- CI test setup fixes + fix GroupCompletion bug (Pedro Muniz)
- pyturso: fix panic (Nikita Sivukhin)
- fix(core/translate): apply affinity conversion to hash join build and probe keys (Nuno Gonçalves)
- fix/core: fix transaction issues (Jussi Saurio)
- sim: fix apply_snapshot for create table, create index, drop column (Jussi Saurio)
- fix stack overflow in long unary expressions ("' from Jussi Saurio)
- Fix RTRIM ignoring trailing tabs (Krishna Vishal)
- Fix incorrect conversion from TEXT to INTEGER when text is a number followed by a trailing non-breaking space (Krishna Vishal)
- fix stack overflow in long unary expressions (")
- Sync fixes (Nikita Sivukhin)
- fix(core): prevent ALTER COLUMN from resulting in tables with only generated columns (Nuno Gonçalves)
- core/storage: fixes for the commit path and
io_uring(Preston Thorpe) - aws/sim: fixes and tweaks (Jussi Saurio)
- fix succeeded check (Pedro Muniz)
- fix/sim: all alter table ops must be recorded and applied in order (Jussi Saurio)
- fix coroutine panic: replace ended_coroutine Bitfield with vec (Jussi Saurio)
- Fix: update schema if DDL commit succeeded but checkpoint failed (Jussi Saurio)
- Fix race condition in WAL frame_cache update with io_uring (Mikaël Francoeur)
- fix(json): properly serialize infinite values (Nuno Gonçalves)
- fix(core/util): reject integer primary key underflow (Nuno Gonçalves)
- fix/core: decouple autocheckpoint result from transaction durability (Jussi Saurio)
- Fix StreamingWalReader behavior with checksums of uncommitted frames (Preston Thorpe)
- Fix ignored completion in free_page (Preston Thorpe)
- Fix more instances of marking pages dirty after modification (Jussi Saurio)
- fix/pager: mark freelist trunk page dirty BEFORE modifying it (Jussi Saurio)
- fix/sim: modify rows in ALTER TABLE properly (Jussi Saurio)
- core: Fix integrity_check pragma code generation (Pekka Enberg)
- antithesis: Fix unique constraint exception handling in stress-composer tests (Pekka Enberg)
- Fix Github go workflow (Nikita Sivukhin)
- sim: fix bug in apply_snapshot (Jussi Saurio)
- Sync better error messages (Nikita Sivukhin)
- Fix CTE scope propagation for compound SELECTs (Martin Mauch)
- Sqlite3 compat fix (Nikita Sivukhin)
- Sim transaction fixes (Jussi Saurio)
- sim/aws: comment on existing issues instead of skipping duplicates (Jussi Saurio)
- Fix complex unique sqlite3 compat (Nikita Sivukhin)
- fix/btree: disable move_to_rightmost optimization with triggers (Jussi Saurio)
- Fix descending index scan returning rows when seek key is NULL (Jussi Saurio)
- Fix external sorter losing rows when chunks need async IO (Jussi Saurio)
- sim: stop ignoring sql execution errors (Jussi Saurio)
- Fix two bugs with compound selects (Jussi Saurio)
- Fix IN operator translation logic (Nikita Sivukhin)
- fix/mvcc: seek() must seek from both mv store and btree (Jussi Saurio)
- Fix panic in optimizer when usable constraint refs is empty (Preston Thorpe)
- optimizer: fix incorrect index_col_pos assigned when multiple constraints ref same join key (Preston Thorpe)
- Bloom filter fixes (Preston Thorpe)
- fix: escape backslashes in json_object string values (Martin Mauch)
- fix/mvcc: use existing schema object in mvcc bootstrap (Jussi Saurio)
- Mvcc bugfixes (Jussi Saurio)
- Fix vtab memory leak (Nikita Sivukhin)
- Fix comparison of large numbers (Mikaël Francoeur)
- Fix to Google Books link in CONTRIBUTING (Juan V. García)
- core/mvcc: fix
existsto useBTreeCursoras fallback (Pere Diaz Bou) - core/io: Improve error handling (Pekka Enberg)
- core/index_method: Improve error handling in toy_vector_spare_ivf.rs (Pekka Enberg)
- Triggers: fix issues with ALTER TABLE (Jussi Saurio)
- Return parse error if NULLS LAST used in ORDER BY (Jussi Saurio)
- Fix: Drop internal DBSP table when dropping materialized view (Martin Mauch)
- Fix seek not applying correct affinity to seek expr (Pedro Muniz)
- Fix EXISTS on LEFT JOIN null rows (Duy Dang)
- Fix error handling on provided insert column count mismatch (Jussi Saurio)
- core/vdbe: Fix incorrect
unreachablecondition in op_seek_rowid (Preston Thorpe) - Update and fix nix build (Alexander Hirner)
- Fix INSERT UNION ALL (Duy Dang)
- Fix LEFT JOIN subqueries reusing stale right-side values (Duy Dang)
- Throw an error in case duplicate CTE names are found (Rohith Suresh)
- Fix self-insert SUM when table uses INTEGER PRIMARY KEY (Duy Dang)
Install turso_cli 0.4.0
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/tursodatabase/turso/releases/download/v0.4.0/turso_cli-installer.sh | sh
Install prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/tursodatabase/turso/releases/download/v0.4.0/turso_cli-installer.ps1 | iex"
Download turso_cli 0.4.0
| File | Platform | Checksum |
|---|---|---|
| turso_cli-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| turso_cli-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| turso_cli-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| turso_cli-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| turso_cli-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
Verifying GitHub Artifact Attestations
The artifacts in this release have attestations generated with GitHub Artifact Attestations. These can be verified by using the GitHub CLI:
gh attestation verify <file-path of downloaded artifact> --repo tursodatabase/turso
You can also download the attestation from GitHub and verify against that directly:
gh attestation verify <file-path of downloaded artifact> --bundle <file-path of downloaded attestation>Fetched April 3, 2026


