Journaling accepted the double-write cost to keep the old in-place layout. In 1991 Mendel Rosenblum and John Ousterhout asked a more radical question: what if writing to the log was not the overhead but the entire file system? Their Log-Structured File System (LFS) treats the whole disk as one enormous append-only log. Nothing is ever overwritten in place; every new or changed block — data and metadata — is simply appended to the end of the log in one long sequential stream.
The motivation was a hardware trend that is even truer today. Disk seeks barely improved while bandwidth and RAM sizes exploded. Big RAM caches absorb most reads, so the disk's job becomes dominated by writes — and the fastest thing a disk (or an SSD) can do is a large sequential write, with no seeking. LFS is built to make every write sequential. Buffer thousands of small random updates in memory, then flush them as one giant contiguous segment, and you convert a seek-bound workload into a bandwidth-bound one. The ideas that felt exotic in 1991 now run inside every SSD and every flash-aware file system.
LFS never issues a small write to the disk. It accumulates dirty blocks in an in-memory segment (typically 512 KB–several MB) and writes the segment out whole, sequentially, once it is full. Because a block's location changes every time it is rewritten, the classic problem appears: where is a file's inode now? In a normal file system inodes live at fixed spots; in LFS they wander down the log with everything else.
Reads still work: consult the checkpoint region → find the imap → find the inode → find the block. The imap is small and heavily cached, so in practice reads cost about the same as any other file system. Writes, meanwhile, are always one big sequential append — the point of the whole design.
Appending forever has an obvious problem — you run out of disk. When you overwrite block 5 of a file, LFS writes a new version further down the log and the old version becomes dead garbage, still occupying space in an old segment. Over time segments become a patchwork of live and dead blocks. To keep going, LFS must reclaim that space with a cleaner (garbage collector / segment cleaning):
This is LFS's Achilles heel. Cleaning is extra I/O that competes with real work, and its cost depends on
utilisation
The model below holds several segments, each a mix of live and dead blocks. The cleaner scans them, copies the live blocks into a new compact segment, and reports how much space it reclaimed and how much I/O the copying cost — the tension at the heart of LFS.
Flash cannot overwrite a byte in place: you can write a fresh page, but to re-use a page you must erase its whole surrounding block (hundreds of pages) first, and each cell tolerates only a limited number of erasures. So the SSD's controller runs a Flash Translation Layer that does exactly what LFS does — write every update to a fresh location, keep a map from logical to physical address, and run a garbage collector to reclaim pages whose data has been superseded, spreading erasures evenly to wear-level. Rosenblum and Ousterhout designed LFS for spinning disks whose seeks were slow; the design turned out to be the native shape of flash. This is why "write amplification" and "over-provisioning" — LFS cleaning concepts — are the vocabulary of every SSD datasheet, and why flash-friendly file systems like F2FS are explicitly log-structured.
A frequent misconception is that a log-structured file system reads fast because everything is "in order." The opposite can be true. LFS optimises write throughput by turning random writes into one sequential stream; it says nothing kind about read layout. In fact a file that was written a few blocks at a time over its lifetime ends up scattered across many segments down the log, so reading it back sequentially may require hopping all over the disk — the very fragmentation LFS created by never overwriting in place. LFS bets that big RAM caches absorb most reads so this rarely bites, and that write speed is what's scarce. When that bet is wrong (large files read cold, sequentially), LFS read performance can disappoint. Know which side of the trade you are optimising.
Because LFS only ever appends, crash recovery is easy — a pleasant side effect of the design. After a crash, LFS
starts from the last checkpoint and rolls forward through the segments written
since, incorporating the complete ones and discarding a torn tail. There is no whole-disk