Every table and every index is a b-tree, and every page of a b-tree has the same layout. There are two kinds of b-tree. A table b-tree is keyed by a 64-bit rowid and keeps its rows on its leaf pages. An index b-tree is keyed by records and keeps entries on every page. Each kind has interior pages, which point to child pages, and leaf pages, which do not.
Layout of a page
0Database header page 1 only100 bytes0 / 100Page header the page type, the cell count and where the cells are8 or 12 bytes…Cell pointer array one 2-byte offset for each cell, in key order2 bytes × cells…Unallocated space free space between the pointers and the cellsvaries…Cell content area the cells, with freeblocks and fragments between themto the usable size…Reserved region only when the header reserves space0 to 255 bytes
Offsets on a b-tree page are counted from the start of the page, even on page 1, where everything is shifted by the database header.
Page header
Eight bytes on a leaf page, twelve on an interior page. Every number is big-endian.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 1 | u8 | Page type | 2, 5, 10 or 13. |
| 1 | 2 | u16 | First freeblock | The offset of the first freeblock on the page, or 0 when there is none. |
| 3 | 2 | u16 | Cell count | The number of cells on the page. |
| 5 | 2 | u16 | Cell content start | The offset where the cell content area starts. 0 means 65,536. |
| 7 | 1 | u8 | Fragmented free bytes | The total of the fragments in the cell content area. |
| 8 | 4 | u32 | Right-most pointer | Interior pages only: the child page holding the keys greater than every key on this page. |
Page types
| Value | Page | Header | Cells hold |
|---|---|---|---|
2 (02) | Interior index page | 12 bytes | an index entry and a left child page |
5 (05) | Interior table page | 12 bytes | a rowid and a left child page |
10 (0A) | Leaf index page | 8 bytes | an index entry |
13 (0D) | Leaf table page | 8 bytes | a row: its rowid and record |
Any other value is an error. Leaf pages have no right-most pointer, so their header is 4 bytes shorter. The cell layouts are on Cells.
Cell pointer array
Straight after the page header: one 2-byte big-endian offset for each cell, from the start of the page. The pointers are in key order, smallest key first; the cells they point to can be anywhere in the content area and in any order. Removing or inserting a cell moves pointers, not cells.
Unallocated space
The free space between the end of the cell pointer array and the start of the cell content area. SQLite puts cells as far towards the end of the page as it can, so the pointer array grows into this space from one side and the cell content area from the other. On a page with no cells the content start equals the usable size, or 0 on an empty 65,536-byte page.
Cell content area
From the cell content start to the end of the usable space. It holds the cells, in any order by offset, and the free space between them, which is either a freeblock or a fragment. Free space on a page is the unallocated space plus the freeblocks plus the fragments.
When SQLite defragments a page it packs the cells together at the end of the page and turns all free space into unallocated space, with no freeblocks and a fragment count of 0.
Freeblocks
Free spaces of 4 bytes or more inside the content area, chained in order of offset from the first freeblock field of the page header. Each starts with two big-endian numbers:
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
| 0 | 2 | u16 | Next freeblock | The offset of the next freeblock, or 0 for the last. |
| 2 | 2 | u16 | Size | The size of this freeblock in bytes, these 4 included. |
The rest of a freeblock means nothing. In a well-formed page at least one cell comes before the first freeblock.
Fragments
Runs of 1 to 3 free bytes, too small to hold a freeblock’s 4-byte header. They are not chained; byte 7 of the page header adds them up. In a well-formed page the total is at most 60.
In about a dozen of the files examined for this site, some pages had free runs of 4 to 32 bytes that were neither freeblocks nor covered by any cell, and their total always matched byte 7. They appear to be fragments that ended up side by side, as when a cell is rewritten smaller in place more than once. The explorer treats every such gap as fragments when the gaps add up to byte 7.
A real page header
The page header of page 1 of the database shown under Database header, at offset 100, after the database header:
00000060 00 2D E6 02 0D 0F FC 00 0C 0A 0E 00
0D: a leaf table page, so the header is 8 bytes.0F FC: the first freeblock is at offset 4,092.00 0C: 12 cells, so the cell pointer array takes the 24 bytes from offset 108 to 131.0A 0E: the cell content area starts at offset 2,574. Offsets 132 to 2,573 are unallocated.00: no fragments.
The freeblock at offset 4,092 is 00 00 00 04: no next freeblock, and a
size of 4 bytes, the last 4 bytes of the page.