storage-format — Claude Code skill: SQLite file format
A reference for the SQLite file format: header, pages, B-trees, cells, overflow, freelist, tied to Turso's storage code.
npx skills add tursodatabase/turso --skill storage-format -a claude-codeWhat storage-format does
The skill walks through the SQLite file layer by layer: the header in the first 100 bytes, pages, B-trees, cells, overflow chains, the freelist. Useful when you need to parse a page dump or work out why a big row ended up in overflow.
It lists the header offsets (page size, schema cookie, text encoding), page type flags from 0x02 to 0x0d, the layout of table leaf and interior cells, and the serial types used in a record. One section maps all of that onto Turso's source: core/storage/sqlite3_ondisk.rs with the PageType enum, plus btree.rs, pager.rs, buffer_pool.rs.
Debugging gets its own part, with commands such as cargo run --bin tursodb test.db "PRAGMA integrity_check;". Those go through the tursodb binary, so they only work from the Turso tree; in your own project you read the skill for reference, not for tooling. Page size is a power of two from 512 to 65536 bytes, 4096 by default.
What it helps with
- parse page layout in a raw SQLite dump
- trace the overflow chain behind a large row
- check big-endian header offsets
- decode serial types inside a record payload
- run
PRAGMA integrity_checkthroughtursodb
Example prompts for the agent
- Walk me through the SQLite file format for a table row with a BLOB larger than one page, from the cell to the overflow chain.
- Where does the schema cookie sit in the database header, and in what byte order?
- Check my page parser against `core/storage/sqlite3_ondisk.rs` in Turso. Which page types did I miss?
How to install storage-format
1Skills CLI (Vercel)
npx skills add tursodatabase/turso --skill storage-format -a claude-code2Manually: put the files in place
~/.claude/skills/storage-format/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/storage-format/
1Skills CLI (Vercel)
npx skills add tursodatabase/turso --skill storage-format -a codex2Manually: put the files in place
.agents/skills/storage-format/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add tursodatabase/turso --skill storage-format -a cursor2Manually: put the files in place
.cursor/skills/storage-format/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install tursodatabase/turso storage-format2Manually: put the files in place
.github/skills/storage-format/SKILL.md1Skills CLI (Vercel)
npx skills add tursodatabase/turso --skill storage-format -a gemini-cli2Platform CLI
gemini skills install https://github.com/tursodatabase/turso --path .claude/skills/storage-formatManually: put the files in place
.devin/skills/storage-format/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add tursodatabase/turso --skill storage-format -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
From the same set10
The whole set →Similar
Questions about storage-format
How do I install storage-format in Claude Code?
Run npx skills add tursodatabase/turso --skill storage-format -a claude-code. The skill lands at ~/.claude/skills/storage-format/SKILL.md.
What does storage-format do?
It documents how SQLite stores data on disk: header, page types, cells, records, overflow and the freelist. The agent uses it when reading or writing code that parses a database file.
Which Turso source files does the skill point to?
core/storage/sqlite3_ondisk.rs, which holds the PageType enum, along with btree.rs, pager.rs and buffer_pool.rs. They show how the format is implemented in practice.
Source text
SKILL.md · MIT
---
name: storage-format
description: SQLite file format, B-trees, pages, cells, overflow, freelist that is used in tursodb
---
# Storage Format Guide
## 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)
| Offset | Size | Field |
|--------|------|-------|
| 0 | 16 | Magic: `"SQLite format 3\0"` |
| 16 | 2 | Page size (big-endian) |
| 18 | 1 | Write format version (1=rollback, 2=WAL) |
| 19 | 1 | Read format version |
| 24 | 4 | Change counter |
| 28 | 4 | Database size in pages |
| 32 | 4 | First freelist trunk page |
| 36 | 4 | Total freelist pages |
| 40 | 4 | Schema cookie |
| 56 | 4 | Text encoding (1=UTF8, 2=UTF16LE, 3=UTF16BE) |
All multi-byte integers: **big-endian**.
## Page Types
| Flag | Type | Purpose |
|------|------|---------|
| 0x02 | Interior index | Index B-tree internal node |
| 0x05 | Interior table | Table B-tree internal node |
| 0x0a | Leaf index | Index B-tree leaf |
| 0x0d | Leaf table | Table B-tree leaf |
| - | Overflow | Payload exceeding cell capacity |
| - | Freelist | Unused 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:
| Type | Meaning |
|------|---------|
| 0 | NULL |
| 1-4 | 1/2/3/4 byte signed int |
| 5 | 6 byte signed int |
| 6 | 8 byte signed int |
| 7 | IEEE 754 float |
| 8 | Integer 0 |
| 9 | Integer 1 |
| ≥12 even | BLOB, length=(N-12)/2 |
| ≥13 odd | Text, 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
```bash
# 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
- [SQLite File Format](https://sqlite.org/fileformat.html)
- [SQLite B-Tree Module](https://sqlite.org/btreemodule.html)
- [SQLite Internals: Pages & B-trees](https://fly.io/blog/sqlite-internals-btree/)
© tursodatabase · MIT · tursodatabase/turso