# 1.4 The Sharpie Ledger (MVCC)

In the depot of the Lazy Elephant, there is a strict rule: **Never use an eraser.**
If you ask the elephant to update a record—say, changing a user's phone number—a high-effort database would find the exact spot on disk, carefully rub out the old data, and write the new one in its place. This is called "In-Place" updating, and it’s exhausting. It requires locking the door to the filing cabinet so nobody else can read while you’re erasing, which leads to long lines and grumpy elephants.
## The Art of the Sharpie
Instead of erasing anything, Postgres uses **Multi-Version Concurrency Control (MVCC)**. When you tell the elephant to UPDATE a row, it performs a simple, two-step lazy dance that is as utterly absurd as it is mathematically profound:
1. **Ignore the old one**: It leaves the old row exactly where it is. "It’s an un-update!"
2. **Write a new one**: It walks to a fresh, empty spot at the end of the page and writes the entire row from scratch with the new phone number.
3. **The Scribble**: It walks past the old row and quickly scribbles a tiny "EXPIRED" note with an invisible red Sharpie.
Because the old version still exists, other elephants who were already reading it can finish their business without being interrupted. They see the version they started with, while new visitors see the fresh one. This is how Postgres allows multiple people to read and write the exact same data at the same time without ever fighting over locks.
### Watching the Sharpie in Action
Let’s watch the elephant handle an order update in our cafe. Imagine **Babu the Elephant** has a pending order:
```sql
-- Check the current state of an order
SELECT ctid, xmin, xmax, status FROM orders WHERE id = 1;
-- Results:
-- ctid | xmin | xmax | status
-- -------+------+------+---------
-- (0,5) | 600 | 0 | Pending
```
Now, the chef finishes the dish, and we update the status:
```sql
UPDATE orders SET status = 'Served' WHERE id = 1;
-- Now look again...
SELECT ctid, xmin, xmax, status FROM orders WHERE id = 1;
-- Results:
-- ctid | xmin | xmax | status
-- -------+------+------+--------
-- (0,6) | 601 | 0 | Served
```
**Wait, what happened to (0,5)?** If we could look at the "hidden" deleted rows, we'd see that `(0,5)` now has an `xmax` of `601` (the transaction that replaced it), and its `ctid` actually points to the new location: `(0,6)`.
The old suitcase is still there, scribbled on with the invisible Sharpie. How very civil!
### The Physical Reality (Before & After)
Let's look at what the elephant actually sees in the depot. Imagine we have an order for **Babu the Elephant** in our `orders` table.
#### State 1: The Initial Insert
The moment an order is added (Transaction 100), the table looks like this:
| ctid | xmin | xmax | id | animal_id | status |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **(0,1)** | **100** | **0** | 1 | 5 | Pending |
*Notice that **xmax is 0**. This means the order is alive and well!*
#### State 2: After an UPDATE
Now, the chef serves the dish and we update the status (Transaction 101). The elephant **leaves the old row** and **writes a new one**:
```sql
UPDATE orders SET status = 'Served' WHERE id = 1;
```
Now, the physical depot floor has **two** rows for the same order:
| ctid | xmin | xmax | id | animal_id | status | Notes |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| **(0,1)** | 100 | **101** | 1 | 5 | Pending | **[DEAD]** Replaced by 101 |
| **(0,2)** | **101** | **0** | 1 | 5 | Served | **[ALIVE]** Created by 101 |
The elephant uses the **`xmax`** of the first row to determine it is no longer visible to new visitors. To the outside world, there is only one "Order #1." But in the depot, the history of the world is written in "Sharpie-marked" luggage!
## The Cost of Garbage
This "Append-Only" lifestyle makes Postgres incredibly fast and consistent, but it leaves the depot floor covered in old, crossed-out suitcases. In technical terms, we call this **Bloat**.
If left alone, the elephant would eventually be wading knee-deep through dead rows just to find a single living one. This is where the **[[Workloads/Sub/Autovacuum|Autovacuum Roomba]]** comes in—a background worker that silently sweeps up the "Sharpie-marked" rows and marks their space as `Available for Rent` for future suitcases.
Doing the least work possible today (just crossing it out) ensures we don't have to wait around for erasers, even if it means we need a little cleanup tomorrow. It’s always tea-time somewhere in the engine!
---
[[Chapter 1/1.3 - The Depot (The Table)|← 1.3 - The Architectural Permit (DDL)]] | [[Chapter 1/1.0 - The Building Blocks of Storage|↑ 1.0 - The Logical vs. The Physical]] | [[Chapter 2/2.1 - The Balanced Bookshelf (The B-Tree)|2.1 - The B-Tree →]]