Skip to main content
Turso aims towards full SQLite compatibility, but there are known limitations. This page documents all current constraints so you can plan accordingly.
Some limitations listed here apply only to experimental features (MVCC, triggers, views). Stable WAL-mode operation is unaffected by experimental-only restrictions.

General Limitations

The following limitations apply to all Turso databases regardless of journal mode or feature flags:
LimitationDetail
Query result orderingNot guaranteed to be the same as SQLite (see #2964)
Multi-process accessNot supported — only one process may open a database file at a time
Multi-threadingNot supported within a single connection
SavepointsNot implemented
TriggersExperimental — not enabled by default
ViewsExperimental — not enabled by default
VACUUMNot supported
Character encodingUTF-8 only; UTF-16 is not supported

Query Result Ordering

Unordered SELECT queries may return rows in a different sequence than SQLite would. If your application depends on a specific row order, always use an explicit ORDER BY clause:
-- Unreliable: order is not guaranteed
SELECT * FROM users;

-- Reliable: explicit ordering
SELECT * FROM users ORDER BY id;

Multi-Process and Multi-Thread Access

Turso does not support concurrent access from multiple processes or from multiple threads sharing a single connection. Each process must open its own database file, and each connection should be used from a single thread.
-- Each process/thread must use its own connection
-- Sharing a sqlite3* handle across threads is not safe
Multiple concurrent transactions within a single process are supported through MVCC mode using BEGIN CONCURRENT. See MVCC Limitations below.

Savepoints

SAVEPOINT and RELEASE SAVEPOINT syntax is parsed but not functionally implemented. Nested transaction control must be managed at the application level.
-- Parsed but not functional:
SAVEPOINT my_savepoint;
RELEASE SAVEPOINT my_savepoint;

Triggers

Triggers are experimental and not enabled by default. Enable them with the --experimental-views flag when starting tursodb.
Triggers are not production-ready. Do not use them for critical data.

Views

Views are experimental and not enabled by default. Enable them with the --experimental-views flag:
tursodb --experimental-views mydb.db
Views are not production-ready. Do not use them for critical data.

VACUUM

VACUUM is not supported. Turso uses WAL mode by default, which manages space differently from SQLite’s rollback journal. There is no current workaround for reclaiming space via VACUUM.
-- Not supported — will return an error:
VACUUM;

UTF-8 Only

Turso only supports UTF-8 character encoding. SQLite’s UTF-16 encoding (used by sqlite3_open16, sqlite3_bind_text16, sqlite3_column_text16, etc.) is not available.
-- UTF-8 encoding is the only valid value:
PRAGMA encoding;
-- Returns: UTF-8

-- Attempting to set UTF-16 will not work:
PRAGMA encoding = 'UTF-16';

MVCC Limitations (Experimental)

MVCC (Multi-Version Concurrency Control) is enabled by switching to mvcc journal mode:
PRAGMA journal_mode = mvcc;
MVCC is not production-ready. Queries may return incorrect results, features may not work, and panics may occur. Do not use MVCC for critical data.

Summary of MVCC Limitations

LimitationDetail
No indexesIndexes cannot be created; databases with existing indexes cannot be used
Eager data loadingAll data is loaded from disk into memory on first access
Checkpoint supportOnly PRAGMA wal_checkpoint(TRUNCATE) is supported; it blocks both readers and writers
No AUTOINCREMENTTables with AUTOINCREMENT cannot be created or inserted into
Incorrect resultsQueries may return incorrect results
MVCC-to-WAL visibilityChanges written in MVCC mode are not visible after reopening in WAL mode unless checkpointed first

No Indexes with MVCC

When MVCC mode is active, indexes are not supported. Attempting to create an index or open a database that already has indexes will fail.
-- In MVCC mode, this will fail:
CREATE INDEX idx ON users(email);
As a workaround, drop all indexes before switching to MVCC mode, or use WAL mode if your workload requires indexes.

Eager Data Loading

MVCC loads all data from disk into memory on first access. For large databases this means:
  • Startup time is proportional to the total data size
  • Memory consumption equals the full uncompressed database size
Only use MVCC with databases that comfortably fit in available memory.

Limited WAL Checkpoint Support

Only the TRUNCATE checkpoint mode is supported under MVCC, and it blocks all readers and writers during the checkpoint:
-- Only this form is supported under MVCC:
PRAGMA wal_checkpoint(TRUNCATE);

-- Other checkpoint modes are not supported under MVCC:
-- PRAGMA wal_checkpoint;
-- PRAGMA wal_checkpoint(PASSIVE);
-- PRAGMA wal_checkpoint(FULL);
-- PRAGMA wal_checkpoint(RESTART);

No AUTOINCREMENT

AUTOINCREMENT is not supported in MVCC mode. Tables that declare AUTOINCREMENT columns cannot be created or inserted into while MVCC is enabled.
-- Not supported in MVCC mode:
CREATE TABLE events (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT
);
Use a plain INTEGER PRIMARY KEY (which still auto-assigns rowids) as an alternative:
-- Works in MVCC mode:
CREATE TABLE events (
    id INTEGER PRIMARY KEY,
    name TEXT
);

MVCC-to-WAL Visibility

If a database is written to using MVCC and then reopened without MVCC (i.e., in WAL mode), the changes written in MVCC mode are not visible unless they were checkpointed first:
-- Before switching back to WAL mode, checkpoint to persist MVCC changes:
PRAGMA wal_checkpoint(TRUNCATE);
PRAGMA journal_mode = wal;

Journaling Limitations

Turso supports wal and mvcc journal modes. Legacy SQLite rollback journal modes are not supported.
ModeStatusReason
wal✅ SupportedDefault mode; recommended for all production use
mvcc✅ SupportedExperimental concurrent transactions
delete❌ Not supportedLocks the database file during writes
truncate❌ Not supportedLocks the database file during writes
persist❌ Not supportedLocks the database file during writes
memory❌ Not supportedLocks the database file during writes
wal2❌ Not supportedExperimental feature in SQLite; not planned
Turso has no plans to support rollback journal modes. The design goal is WAL-first durability without file-level locking during writes.
Attempting to switch to an unsupported journal mode returns an error:
-- Returns an error:
PRAGMA journal_mode = delete;
Legacy SQLite databases (which may use delete journal mode) are automatically converted to WAL mode when first opened by Turso.

Workarounds Summary

LimitationWorkaround
No VACUUMUse WAL checkpointing to reclaim WAL space: PRAGMA wal_checkpoint(TRUNCATE)
No multi-threadingOpen a separate connection per thread
No savepointsManage nested transaction logic at the application level
No views (stable)Materialize view logic in application code or use CTEs
No indexes in MVCCDrop indexes before enabling MVCC, or use WAL mode
No AUTOINCREMENT in MVCCUse INTEGER PRIMARY KEY without AUTOINCREMENT
UTF-8 onlyEnsure all text data is encoded as UTF-8 before writing
Unordered resultsAlways use ORDER BY when row order matters

Build docs developers (and LLMs) love