Storage Format Guide

SkillDatabases & data

SQLite file format, B-trees, pages, cells, overflow, freelist that is used in tursodb

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Storage Format Guide skill

What this skill tells your AI

The instructions your AI receives, as published by tursodatabase/turso-vdbe-doom-example in .claude/skills/storage-format/SKILL.md and read by ahel’s review.

Database File Structure

┌─────────────────────────────┐
│ Page 1: Header + Schema     │  ← First 100 bytes = DB header
├─────────────────────────────┤
│ Page 2..N: B-tree pages     │  ← Tables and indexes
│            Overflow pages   │
│            Freelist pages   │
└─────────────────────────────┘

Page size: power of 2, 512-65536 bytes. Default 4096.

Database Header (First 100 Bytes)

OffsetSizeField
016Magic: "SQLite format 3\0"
162Page size (big-endian)
181Write format version (1=rollback, 2=WAL)
191Read format version
244Change counter
284Database size in pages
324First freelist trunk page
364Total freelist pages
404Schema cookie
564Text encoding (1=UTF8, 2=UTF16LE, 3=UTF16BE)

All multi-byte integers: big-endian.

Page Types

FlagTypePurpose
0x02Interior indexIndex B-tree internal node
0x05Interior tableTable B-tree internal node
0x0aLeaf indexIndex B-tree leaf
0x0dLeaf tableTable B-tree leaf
-OverflowPayload exceeding cell capacity
-FreelistUnused pages (trunk or leaf)

B-tree Structure

Two B-tree types:

  • Table B-tree: 64-bit rowid keys, stores row data
  • Index B-tree: Arbitrary keys (index columns + rowid)
Interior page:  [ptr0] key1 [ptr1] key2 [ptr2] ...
                   │         │         │
                   ▼         ▼         ▼
               child     child     child
               pages     pages     pages

Leaf page:     key1:data  key2:data  key3:data ...

Page 1 always root of sqlite_schema table.

Cell Format

Table Leaf Cell

[payload_size: varint] [rowid: varint] [payload] [overflow_ptr: u32?]

Table Interior Cell

[left_child_page: u32] [rowid: varint]

Index Cells

Similar but key is arbitrary (columns + rowid), not just rowid.

Record Format (Payload)

[header_size: varint] [type1: varint] [type2: varint] ... [data1] [data2] ...

Serial types:

TypeMeaning
0NULL
1-41/2/3/4 byte signed int
56 byte signed int
68 byte signed int
7IEEE 754 float
8Integer 0
9Integer 1
≥12 evenBLOB, length=(N-12)/2
≥13 oddText, length=(N-13)/2

Overflow Pages

When payload exceeds threshold, excess stored in overflow chain:

[next_page: u32] [data...]

Last page has next_page=0.

Freelist

Linked list of trunk pages, each containing leaf page numbers:

Trunk: [next_trunk: u32] [leaf_count: u32] [leaf_pages: u32...]

Turso Implementation

Key files:

  • core/storage/sqlite3_ondisk.rs - On-disk format, PageType enum
  • core/storage/btree.rs - B-tree operations (large file)
  • core/storage/pager.rs - Page management
  • core/storage/buffer_pool.rs - Page caching

Debugging Storage

# Integrity check
cargo run --bin tursodb test.db "PRAGMA integrity_check;"

# Page count
cargo run --bin tursodb test.db "PRAGMA page_count;"

# Freelist info
cargo run --bin tursodb test.db "PRAGMA freelist_count;"

References

Signals

GitHub stars
36
Forks
2
Last commit
Jul 2026

ahel recommends instead

Advanced
Catalog kind
skill
Gateway key
storage-format-2
Source
github.com/tursodatabase/turso-vdbe-doom-example