24 min read Storage Engine & Page Layouts Lesson 11 of 15
Part 3 — Performance, Transactions & Storage Engine

How Data is Actually Stored Inside a Database

Under the Hood: Slotted Pages, Buffer Pool, Row vs. Column Store & WAL

Until now, we have interacted with databases primarily from a Logical Level. We designed relational tables, crafted primary and foreign keys, accelerated queries using B+Tree indexes, and guarded integrity through ACID transactions. As application developers, we view a users table as a pristine grid: id | name | email. But does a database engine actually write formatted text lines into disk blocks or SSD chips? Absolutely not! Beneath the logical abstraction lies an intricate mechanical and algorithmic storage architecture: Slotted Pages, In-Memory Buffer Pools, Row vs. Column Layouts, and Write-Ahead Logs. Today, we peel back the abstraction to explore how databases conquer physical storage.

What You Will Master in This Lesson:

Low-level database storage architecture and hardware interaction:

  • Logical vs. Physical Data: Developer schema abstraction vs. binary storage reality
  • Database Page Architecture: The 8KB Slotted Page layout and free-space pointer mechanics
  • Buffer Pool Caching: RAM vs. SSD latency differentials and Cache Hit vs. Miss lifecycle
  • Row vs. Column Stores: Tradeoffs between OLTP transactional workloads and OLAP analytics
  • Write-Ahead Logging (WAL) & Checkpoints: Sequential logging to circumvent random disk I/O
  • End-to-End Query Journey: Dissecting a SELECT and INSERT from parser to physical disk bytes

1 Logical Data vs. Physical Data

When executing queries in a SQL client, developers see neat, tabular output:

id name email
1 Salim salim@example.com
2 Rahim rahim@example.com

However, the database storage engine does not preserve this human-readable grid. From the engine's viewpoint, data exists as a hierarchy of low-level physical structures:

The Abstraction Hierarchy: Logical to Physical

Logical Level
Tables & Rows

Developer-facing schema

Engine Level
Pages & Records

Fixed-size 8KB blocks

Physical Level
OS Files & SSD Sectors

Binary bytes on silicon

Is a Database File Like a Giant CSV File?

Beginners sometimes assume a table is merely stored as a flat comma-separated text file. In reality, CSV files lack binary metadata, have no free space management, cannot support transactional rollbacks or atomic in-place updates, and cannot integrate binary B+Tree pointers. Modern database files are highly sophisticated binary formats engineered for durability and microsecond random access.

2 What is a Database Page? The 8KB Slotted Page Architecture

The fundamental atomic unit of database disk storage is the Page (often called a Block). Just as operating systems allocate memory in 4KB virtual pages, a database engine never reads or writes individual record bytes from disk; storage controllers always transfer data in fixed-size page blocks.

PostgreSQL Standard
8 KB Page

8,192 bytes fixed block

MySQL (InnoDB) Standard
16 KB Page

16,384 bytes fixed block

SQLite Standard
4 KB Page

4,096 bytes fixed block

Internal Slotted Page Layout

How does a page accommodate variable-length rows (e.g., someone with a 4-character name versus a 100-character description) without fragmentation? The industry standard solution is the Slotted Page Architecture:

Slotted Page Anatomy (8,192 Bytes Total)

PAGE HEADER (24–32 Bytes) LSN, Checksum, Flags, Lower & Upper Offsets
SLOT ARRAY / ITEM POINTERS (Growing Downward ↓) Slot 1 → Offset 8000 | Slot 2 → Offset 7850 | Slot 3 ...
↑ FREE SPACE WINDOW ↓

As rows arrive, the slot array expands downward and tuple bytes append upward from the bottom

ROW / TUPLE STORAGE (Growing Upward ↑) Row 3 (Bytes) | Row 2 (Bytes) | Row 1 (Bottom of Page)
Is a Row Equal to a Page?

No! A page is an 8KB container. It holds anywhere from a dozen to hundreds of rows. When a database engine needs to inspect even a single column from a single record, it must fetch the entire 8KB page into memory.

3 The Buffer Pool & Cache Hit/Miss Dynamics

Does a database read from the SSD for every incoming SELECT query? If it did, high-traffic systems would instantly collapse under disk I/O bottlenecks. Hardware latency varies by orders of magnitude:

Memory Tier Access Latency Relative Performance
L1 / L2 CPU Cache ~ 1 nanosecond Fastest possible
RAM (Buffer Pool) ~ 100 nanoseconds (0.0001 ms) 100x slower than CPU cache
NVMe SSD ~ 100 microseconds (0.1 ms) 1,000x slower than RAM
Spinning Magnetic Disk (HDD) ~ 10 milliseconds (10 ms) 100,000x slower than RAM

To bridge this latency chasm, database servers reserve 50% to 80% of system RAM for the Buffer Pool (Buffer Cache). When a query requests a page, the engine checks the pool first:

Cache Hit

The target page already resides in RAM. The engine retrieves the record in sub-millisecond time with zero disk I/O.

Cache Miss

The page is not in RAM. The engine issues a synchronous disk read to load the 8KB page. If the buffer pool is full, an eviction policy like LRU (Least Recently Used) or Clock Sweep evicts an old page to make space.

4 Row-Oriented vs. Column-Oriented Storage

Not all databases organize disk data into rows. Depending on the workload, physical storage engines split into two primary architectures:

Row-Oriented Storage (OLTP)

PostgreSQL, MySQL, SQLite

All column values for a single row are stored contiguously on disk:

[id:1, name:Salim, salary:50000] [id:2, name:Rahim, salary:60000]
  • Blazing fast point lookups and single-row updates
  • Ideal for transactional e-commerce, banking, and SaaS applications
  • Calculating an average over a billion rows requires reading megabytes of unused column data

Column-Oriented Storage (OLAP)

ClickHouse, Snowflake, DuckDB, Parquet

All values for a single column across all rows are packed contiguously into dedicated disk blocks:

[salary: 50000, 60000, 75000, ...] [name: Salim, Rahim, ...]
  • SELECT AVG(salary) reads only the compact 4-byte salary vector, delivering results in milliseconds
  • Homogeneous data types yield incredible compression ratios (>10x file shrinkage)
  • Single-record point updates and inserts are expensive and slow

5 Write-Ahead Logging (WAL) & Checkpointing

If a database had to write directly to random 8KB disk pages on every INSERT or UPDATE, throughput would plummet. Jumping between arbitrary disk sectors is known as Random I/O, the slowest operation in storage engineering.

How do databases achieve both blistering write speed and rock-solid crash safety? Through Write-Ahead Logging (WAL):

The WAL & Buffer Synchronization Lifecycle

1
Sequential Append to WAL:

Before any data page is modified on disk, a compact binary description of the change is appended to the WAL log sequentially and flushed with an OS fsync() call. Sequential disk writes are remarkably fast.

2
Dirty Page in Buffer Pool:

The actual data page is updated in the RAM buffer pool and flagged as "Dirty" (meaning the in-memory state is ahead of the disk file). The engine immediately acknowledges the COMMIT to the client!

3
Checkpointing & Background Flushing:

Periodically, a background thread (the Checkpointer) flushes dirty pages in batches to the main data files. Once completed, older WAL segments are truncated to reclaim disk space.

Crash Recovery Mechanics: REDO & UNDO

If power fails suddenly, all volatile RAM buffer pool frames evaporate. Upon reboot, the storage engine reads the WAL log to restore exact consistency:

REDO

Transactions that were successfully committed before the crash, but whose dirty pages had not yet been flushed to disk, are reapplied from WAL records.

UNDO

Transactions that were actively executing at the moment of the crash are identified as incomplete and their partial writes are cleanly rolled back.

6 End-to-End Journey of a SELECT and INSERT

Let us connect all the pieces. When you submit a SQL query, here is the exact path through the database engine:

SELECT name FROM users WHERE email = 'salim@example.com';
  1. Parser & Optimizer: Validates syntax and determines that an index scan on email is the optimal access path.
  2. Index Root Lookup: The engine locates the index root page in the buffer pool (or reads it from disk on a miss).
  3. Leaf Page & Tuple ID: The B+Tree traversal reaches a leaf page holding the tuple pointer: (Page #42, Slot #3).
  4. Buffer Pool Inspection: Is Page #42 cached in RAM? If yes, access is immediate; if no, an 8KB disk read is issued.
  5. Slot 3 Offset Dissection: The engine reads Slot 3's offset to locate the record bytes, verifies transaction visibility (MVCC), and returns Salim to the client.
INSERT INTO users (name, email) VALUES ('Salim', 'salim@example.com');
  1. Transaction Allocation: The transaction manager assigns a new transaction ID and locks relevant table metadata.
  2. Free Space Map (FSM): The engine queries the Free Space Map to identify an existing page with sufficient bytes (e.g., Page #42).
  3. WAL Append: The binary delta is written to the sequential WAL file and synced via fsync().
  4. Buffer Pool Page Update: Page #42's slot pointer is updated, the tuple is stored, and the frame is marked Dirty.
  5. Index Maintenance: Corresponding entries for primary key and email indexes are updated with (Page #42, Slot #4).
  6. Commit Acknowledgment: Success is returned to the client immediately. The dirty page will be flushed during a future checkpoint.

Interactive Visual Laboratory

Explore slotted page mechanics, buffer pool caching dynamics, row vs. column disk access, and crash recovery in real time:

Live 8KB Slotted Page Inspector

Observe bidirectional growth between slot pointers and tuple data, plus dead space reclamation

Total Page Size
8,192 Bytes
Used Space
340 Bytes
Free Space
7,852 Bytes
Dead Tuples
0
PAGE HEADER (32B) — LSN: 0/1A94B20 Lower: 44 | Upper: 7884
SLOT ARRAY (Growing Down ↓) 3 Slot Pointers
Free Space Window (95.8% available)
TUPLE DATA STORAGE (Growing Up ↑) 3 Active Rows

Inspector initialized. Insert a record to observe page growth.

Knowledge Check — 3 Multiple Choice Questions

Validate your understanding of database physical storage architecture

1. Why do relational database engines utilize the 'Slotted Page' architecture for 8KB disk blocks?

2. What is the fundamental invariant of Write-Ahead Logging (WAL)?

3. Why is a Column-Oriented database (OLAP) vastly faster than a Row-Oriented database for SELECT AVG(salary) FROM employees across 100M rows?

Lesson Summary: Key Architectural Takeaways

  • Logical vs. Physical Separation: Tables and rows are abstractions for humans; storage engines manage slotted pages, slot pointers, and binary disk chunks.
  • 8KB Slotted Page: The slot array grows downward from the header while tuple data appends upward from the bottom; when the middle free space is exhausted, pages split.
  • Buffer Pool Caching: Frequently accessed pages remain pinned or cached in RAM; cache hits eliminate disk latency, delivering sub-millisecond query responses.
  • Row vs. Column Stores: Row stores excel at transactional CRUD (OLTP), while column stores provide orders-of-magnitude acceleration for analytical aggregates (OLAP).
  • WAL & Checkpoints: Sequential log append avoids catastrophic random I/O penalties during transactions while guaranteeing durability through REDO and UNDO recovery.