Software and engineering
Leaky abstractions
Every non-trivial abstraction leaks: sooner or later the thing it hides shows through, so you need to understand one layer down.
Joel Spolsky, "The Law of Leaky Abstractions", Joel on Software, 11 November 2002.
Spolsky's law: all non-trivial abstractions, to some degree, are leaky. His example is TCP over IP. The Internet Protocol (IP) drops, duplicates and corrupts packets; the Transmission Control Protocol (TCP) sits on top and promises reliable, ordered delivery. The promise holds until a cable is cut or the network is overloaded, and then TCP cannot deliver either, so the unreliability it was built to hide comes back as a hang. He lists more: iterating a two-dimensional array row-wise or column-wise can differ hugely in speed because virtual memory is really pages; two SQL queries with the same result can differ a thousandfold because the planner is real; a network file system looks like a disk until the network goes; a web framework that hides JavaScript breaks when a user turns JavaScript off.
It holds because an abstraction hides a mechanism without removing it. The mechanism keeps its costs and its failure modes, and both come through at the edges: performance leaks, like an object-relational mapper (ORM) that turns a loop over objects into one query per object; and failure leaks, like a remote procedure call that looks like a function call but can time out, partially succeed, or succeed without telling you. The Amazon EBS outage of April 2011 is the distributed-systems case: volumes that looked like local disks were network replicas, and a network change left 13 percent of them stuck. Spolsky's conclusion was that abstractions save working time but not learning time: when the leak comes, you need the layer below.
The law is an argument for understanding, not against abstraction. Abstractions remain the main tool for building anything large, and most of them hold almost all of the time; the law says to budget for the moments they do not. The misreading is 'it leaks, so I will write it myself', which reproduces the same leaks with less testing. The better response is to know the mechanism one layer under the abstractions you lean on most, and to design for the leak: timeouts on calls that look local, idempotent retries, and metrics on the layer below so you see the leak before your users do.
Example
Amazon's Elastic Block Store (EBS) presents a network-replicated volume as if it were a local disk. At 12:47 AM Pacific time on 21 April 2011 a network change in the US East region, meant to move traffic between routers, sent the EBS replication traffic onto a lower-capacity secondary network instead. When connectivity returned, every node that had lost its replica searched for space at once, exhausted the cluster, and got stuck in a loop looking for more. At the peak about 13 percent of the volumes in the affected Availability Zone were stuck, and 45 percent of single-zone Relational Database Service (RDS) databases there had stuck I/O, and 0.07 percent of volumes could never be restored in a consistent state. The applications had been written for a disk and got a distributed system.
Where it applies
For each abstraction you lean on daily, learn what it does one layer down: what the ORM sends, what the vector database does on a metadata filter, what a large language model (LLM) API resends on every call. Then design for the leak with timeouts on 'local' calls, idempotent retries, and dashboards on the layer below.
Think about it
Which abstraction in your stack do you understand least, and what does it do when the layer below it fails?
Applied it to something real? Log it.
Test yourselfTCP promises reliable delivery on top of unreliable IP. In what sense does the abstraction leak?
When the network is cut or overloaded, TCP cannot deliver either, so the unreliability it hides reappears as stalls; the user of TCP still has to handle the failure the abstraction was meant to remove.
Related models
- The map is not the territoryEvery model, metric or plan is a simplification, and the parts it leaves out can matter more than the parts it shows.
- Hyrum's lawWith enough users of an interface, every observable behaviour gets depended on by someone, whatever the contract promises.
- The CAP theoremDuring a network partition each operation must give up either availability or consistency; the rest of the time the trade is latency against consistency.
- Redundancy and slackSpare parts and spare capacity look like waste until the day they are the only thing between a fault and a failure.