/transaction-correctness
How WAL mechanics, checkpointing, concurrency rules, recovery work in tursodb
$ npx -y skills add tursodatabase/turso --skill transaction-correctness --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/transaction-correctness
Context preview
The summary Claude sees to decide when to auto-load this skill.
How WAL mechanics, checkpointing, concurrency rules, recovery work in tursodb
SKILL.md
transaction-correctness.SKILL.mdname: transaction-correctness
description: How WAL mechanics, checkpointing, concurrency rules, recovery work in tursodb
Transaction Correctness Guide
Turso uses WAL (Write-Ahead Logging) mode exclusively.
Files: `.db`, `.db-wal` (no `.db-shm` - Turso uses in-memory WAL index)
WAL Mechanics
Write Path
1. Writer appends frames (page data) to WAL file (sequential I/O) 2. COMMIT = frame with non-zero db_size in header (marks transaction end) 3. Original DB unchanged until checkpoint
Read Path
1. Reader acquires read mark (mxFrame = last valid commit frame) 2. For each page: check WAL up to mxFrame, fall back to main DB 3. Reader sees consistent snapshot at its read mark
Checkpointing
Transfers WAL content back to main DB.
WAL grows → checkpoint triggered (default: 1000 pages) → pages copied to DB → WAL reused
Checkpoint types:
- **PASSIVE**: Non-blocking, stops at pages needed by active readers
- **FULL**: Waits for readers, checkpoints everything
- **RESTART**: Like FULL, also resets WAL to beginning
- **TRUNCATE**: Like RESTART, also truncates WAL file to zero length
WAL-Index
SQLite uses a shared memory file (`-shm`) for WAL index. **Turso does not** - it uses in-memory data structures (`frame_cache` hashmap, atomic read marks) since multi-process access is not supported.
Concurrency Rules
- One writer at a time
- Readers don't block writer, writer doesn't block readers
- Checkpoint must stop at pages needed by active readers
Recovery
On crash: 1. First connection acquires exclusive lock 2. Replays valid commits from WAL 3. Releases lock, normal operation resumes
Turso Implementation
Key files:
- [WAL implementation](../../../core/storage/wal.rs) - WAL implementation
- [Page management, transactions](../../../core/storage/pager.rs)
Connection-Private vs Shared
**Per-Connection (private):**
- `Pager` - page cache, dirty pages, savepoints, commit state
- `WalFile` - connection's snapshot view:
- `max_frame` / `min_frame` - frame range for this connection's snapshot
- `max_frame_read_lock_index` - which read lock slot this connection holds
- `last_checksum` - rolling checksum state
**Shared across connections:**
- `WalFileShared` - global WAL state:
- `frame_cache` - page-to-frame index (replaces `.shm` file)
- `max_frame` / `nbackfills` - global WAL progress
- `read_locks[5]` - read mark slots (TursoRwLock with embedded frame values)
- `write_lock` - exclusive writer lock
- `checkpoint_lock` - checkpoint serialization
- `file` - WAL file handle
- `DatabaseStorage` - main `.db` file
- `BufferPool` - shared memory allocation
Correctness Invariants
1. **Durability**: COMMIT record must be fsynced before returning success 2. **Atomicity**: Partial transactions never visible to readers 3. **Isolation**: Each reader sees consistent snapshot 4. **No lost updates**: Checkpoint can't overwrite uncommitted changes
References
- [SQLite WAL](https://sqlite.org/wal.html)
- [WAL File Format](https://sqlite.org/walformat.html)
Read more
name: transaction-correctness description: How WAL mechanics, checkpointing, concurrency rules, recovery work in tursodb
Transaction Correctness Guide
Turso uses WAL (Write-Ahead Logging) mode exclusively.
Files: `.db`, `.db-wal` (no `.db-shm` - Turso uses in-memory WAL index)
WAL Mechanics
Write Path
1. Writer appends frames (page data) to WAL file (sequential I/O) 2. COMMIT = frame with non-zero db_size in header (marks transaction end) 3. Original DB unchanged until checkpoint
Read Path
1. Reader acquires read mark (mxFrame = last valid commit frame) 2. For each page: check WAL up to mxFrame, fall back to main DB 3. Reader sees consistent snapshot at its read mark
Checkpointing
Transfers WAL content back to main DB.
WAL grows → checkpoint triggered (default: 1000 pages) → pages copied to DB → WAL reused
Checkpoint types:
- **PASSIVE**: Non-blocking, stops at pages needed by active readers
- **FULL**: Waits for readers, checkpoints everything
- **RESTART**: Like FULL, also resets WAL to beginning
- **TRUNCATE**: Like RESTART, also truncates WAL file to zero length
WAL-Index
SQLite uses a shared memory file (`-shm`) for WAL index. **Turso does not** - it uses in-memory data structures (`frame_cache` hashmap, atomic read marks) since multi-process access is not supported.
Concurrency Rules
- One writer at a time
- Readers don't block writer, writer doesn't block readers
- Checkpoint must stop at pages needed by active readers
Recovery
On crash: 1. First connection acquires exclusive lock 2. Replays valid commits from WAL 3. Releases lock, normal operation resumes
Turso Implementation
Key files:
- [WAL implementation](../../../core/storage/wal.rs) - WAL implementation
- [Page management, transactions](../../../core/storage/pager.rs)
Connection-Private vs Shared
**Per-Connection (private):**
- `Pager` - page cache, dirty pages, savepoints, commit state
- `WalFile` - connection's snapshot view:
- `max_frame` / `min_frame` - frame range for this connection's snapshot
- `max_frame_read_lock_index` - which read lock slot this connection holds
- `last_checksum` - rolling checksum state
**Shared across connections:**
- `WalFileShared` - global WAL state:
- `frame_cache` - page-to-frame index (replaces `.shm` file)
- `max_frame` / `nbackfills` - global WAL progress
- `read_locks[5]` - read mark slots (TursoRwLock with embedded frame values)
- `write_lock` - exclusive writer lock
- `checkpoint_lock` - checkpoint serialization
- `file` - WAL file handle
- `DatabaseStorage` - main `.db` file
- `BufferPool` - shared memory allocation
Correctness Invariants
1. **Durability**: COMMIT record must be fsynced before returning success 2. **Atomicity**: Partial transactions never visible to readers 3. **Isolation**: Each reader sees consistent snapshot 4. **No lost updates**: Checkpoint can't overwrite uncommitted changes
References
- [SQLite WAL](https://sqlite.org/wal.html)
- [WAL File Format](https://sqlite.org/walformat.html)
A SQL database in Rust: SQLite-compatible, now also speaking Postgres (experimental). The LLVM of databases.
Repo: tursodatabase/turso
Other skills on turso.
- /async-io-model
Explanations of common asynchronous patterns used in tursodb. Involves IOResult, state machines, re-entrancy pitfalls, CompletionGroup. Always use these patterns in `core` when doing anything IO
Open skill - /cdc
Change Data Capture - architecture, entrypoints, bytecode emission, sync engine integration, tests
Open skill - /code-quality
General Correctness rules, Rust patterns, comments, avoiding over-engineering. When writing code always take these into account
Open skill - /debugging
How to debug tursodb using Bytecode comparison, logging, ThreadSanitizer, deterministic simulation, and corruption analysis tools
Open skill - /differential-fuzzer
Information about the differential fuzzer tool, how to run it and use it catch bugs in Turso. Always load this skill when running this tool
Open skill - /index-knowledge
Generate hierarchical AGENTS.md knowledge base for a codebase. Creates root + complexity-scored subdirectory documentation.
Open skill

