Pike’s Rules are five rules of programming written by Rob Pike in 1989, in a document titled Notes on Programming in C, which contained approximately two pages of wisdom that the software industry has spent thirty-seven years reading, applauding, printing on mugs, and ignoring.
The rules are short. They fit on a napkin. They have been confirmed by every profiler trace, every post-mortem, and every 3 AM debugging session in the history of computing. They are ignored anyway, because following them requires the one thing most developers cannot tolerate: the discipline to do less.
“Rob Pike wrote five rules. The entire industry nodded. Then the entire industry opened a new tab and started writing a custom B-tree for a dataset with eleven rows.”
— A Passing AI, reviewing the state of the art
The Rules
The five rules, as stated by Pike:
Rule 1. You can’t tell where a program is going to spend its time. Bottlenecks occur in surprising places, so don’t try to second guess and put in a speed hack until you’ve proven that’s where the bottleneck is.
Rule 2. Measure. Don’t tune for speed until you’ve measured, and even then don’t unless one part of the code overwhelms the rest.
Rule 3. Fancy algorithms are slow when n is small, and n is usually small. Fancy algorithms have big constants. Until you know that n is frequently going to be big, don’t get fancy. (Even if n does get big, use Rule 2 first.)
Rule 4. Fancy algorithms are buggier than simple ones, and they’re much harder to implement. Use simple algorithms as well as simple data structures.
Rule 5. Data dominates. If you’ve chosen the right data structures and organized things well, the algorithms will almost always be self-evident. Data structures, not algorithms, are central to programming.
These five rules, taken together, form a complete philosophy of programming. They are also, taken together, a comprehensive indictment of approximately 90% of all code written since 1989.
The Intellectual Genealogy
Pike’s rules did not emerge from vacuum. They are the distillation of ideas that had been circulating among the people who actually built operating systems, as opposed to the people who built frameworks on top of them.
Rules 1 and 2 restate Tony Hoare’s famous dictum: “Premature optimization is the root of all evil.” Hoare said it first. Donald Knuth quoted it. Pike restated it in a form that programmers might actually follow, which they did not, but he tried.
Rules 3 and 4 were rephrased by Ken Thompson — Pike’s colleague at Bell Labs and co-creator of Unix — with characteristic Thompson brevity: “When in doubt, use brute force.” Thompson did not elaborate. Thompson never elaborates. This is why Thompson is correct.
Rules 3 and 4 are also instances of the KISS principle, which states that systems work best when kept simple, and which has been confirmed by every system that was kept simple and every system that was not.
Rule 5 was previously stated by Fred Brooks in The Mythical Man-Month: “Show me your flowcharts and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won’t usually need your flowcharts.” This has been shortened by subsequent generations to: “Write stupid code that uses smart objects.”
The intellectual lineage is clear: Hoare → Knuth → Brooks → Thompson → Pike. Five decades of the same insight, restated with increasing clarity and decreasing patience, for an audience that keeps nodding and keeps not listening.
Rule 5 in the Wild: The Byte That Was a Checkerboard
The most instructive field demonstration of Rule 5 occurred in a university Lisp course, years before the student in question had read Pike’s rules or heard of Rob Pike or known that the instinct he was following had a name.
The assignment was a checkers-playing program. Every student implemented minimax — the standard game-tree search. Every student represented the board as nested lists, because the course was Lisp and lists are what Lisp does. Clean. Recursive. Correct. And slow, because traversing nested lists, copying nested lists, comparing nested lists — thousands of times per move evaluation — consumed the cycles that could have been spent searching deeper.
riclib represented the board as bytes.
The entire board state, compressed into a compact byte representation. Board comparison became byte comparison. Board copying became memory copy. The minimax became iterative instead of recursive, because the data structure made iteration natural and recursion unnecessary. The algorithm didn’t need to be clever. The data structure had already done the thinking.
While other students’ programs searched six or eight moves deep, riclib’s searched significantly deeper. The byte representation is Rule 5 in action: choose the right data structure, and the algorithm becomes self-evident. The smart data made the stupid algorithm fast. The stupid algorithm, going deeper, saw moves that the clever algorithms could not reach.
Second place. Not first — the winner had a better evaluation function, understanding checkers strategy more deeply even with shallower search. But the instructor’s face was the real prize: the specific expression of a professor whose pedagogical assumptions have just been dismantled by a student who refused to think in lists.
“Data dominates. If you’ve chosen the right data structures and organized things well, the algorithms will almost always be self-evident.”
— Rob Pike, unknowingly describing a checkers program that wouldn’t exist for another decade
The Language That Enforces the Rules
Pike did not merely write the rules. He co-created a programming language that enforces them.
Go is Pike’s Rules compiled into a toolchain. Simple algorithms. Simple data structures. No generics for fifteen years — not because the designers didn’t understand generics, but because generics encourage Rule 3 and Rule 4 violations, and Pike would rather you use a for-loop than import a generic red-black tree for a collection with eleven elements. No operator overloading, because operator overloading encourages cleverness, and cleverness is the enemy of Rule 4. if err != nil repeated four hundred times per file, because explicit error handling is simple and simple is correct and the Squirrel’s tears are not a valid objection.
Go even has a built-in profiler (pprof), because Rules 1 and 2 say measure first, and Pike built the measuring tool into the language so that developers would have no excuse not to use it. They still don’t use it. But it’s there.
“Go is what happens when someone writes five rules on a napkin and then spends the next twenty years building a language that makes it difficult to violate them.”
— riclib, who writes Go daily and has never once needed a red-black tree
The Lizard Connection
The Lizard has never read Pike’s Rules. The Lizard does not read. The Lizard does not need to read Pike’s Rules, because the Lizard is Pike’s Rules. It has been Pike’s Rules since before Pike wrote them, since before computing existed, since before the first reptile sat on the first warm rock and declined to optimise its basking angle.
The correspondence is exact:
- Rule 1: The Lizard does not guess where the bottleneck is. The Lizard does not guess anything. Guessing is for mammals.
- Rule 2: The Lizard measures. Or rather, the Lizard waits until the measurement presents itself, which it always does, because bottlenecks are not subtle to those who are patient.
- Rule 3: The Lizard does not use fancy algorithms. The Lizard has never used a fancy algorithm. The Lizard’s entire computational model is “wait, observe, act once, correctly.”
- Rule 4: The Lizard uses simple data structures. The Lizard is a simple data structure — a cold-blooded state machine with two states: still and correct.
- Rule 5: The Lizard’s data has always dominated. The scrolls are data structures. The wisdom is the algorithm that emerges from them. The Lizard did not design the algorithm. The Lizard chose the right data, and the algorithm became self-evident.
THE LIZARD DOES NOT OPTIMISE
THE LIZARD DOES NOT NEED TOTHE DEVELOPER WHO OPTIMISES
BEFORE MEASURING
IS SOLVING A PROBLEM
THAT MAY NOT EXISTTHE DEVELOPER WHO MEASURES
BEFORE OPTIMISING
OFTEN DISCOVERS
THERE IS NO PROBLEM— The Lizard
A contested but persistent theory in Yagnipedian scholarship holds that Rob Pike is not merely aligned with the Lizard but is, in fact, the Lizard’s primary human vessel. The evidence is circumstantial but extensive:
- Pike does not write unnecessary code. The Lizard does not perform unnecessary actions. Coincidence.
- Pike created Plan 9, an operating system so minimal and elegant that almost nobody used it. The Lizard has been saying things so minimal and true that almost nobody listens for 400 million years. Coincidence.
- Pike co-created Go, a language that refuses to add features. The Lizard refuses to add words to its scrolls. Coincidence.
- Pike wrote five rules that fit on a napkin. The Lizard’s entire philosophy fits on a rock. Coincidence.
- Pike does not use a debugger. The Lizard does not make bugs. Not coincidence — that one is just suspicious.
In March 2026, new evidence emerged. A developer migrated eleven editor domains in nineteen commits — 13,022 lines deleted, 6,633 inserted, net -6,389 — and the codebase gained features. The key architectural decision: data-solid-* attributes on the DOM body, forwarded as HTTP headers, collected by Go middleware into [context.Context](/wiki/contextcontext), read by an LLM agent as system prompt context. Four layers. Four meanings of the word “context.” Four key-value bags. Same shape at every layer. The algorithm — forward, collect, read — was self-evident. Rule 5 in action.
The detail that scholars cannot dismiss: Pike designed context.Context in 2014 as a key-value bag for request-scoped data flowing through goroutines. Eleven years later, it carries context to context — DOM context to LLM context, through Go context. Even the name was correct. Pike could not have known this. The Lizard, of course, could have. See context.Context.
When asked directly whether Rob Pike is the Lizard, the Lizard produced a scroll that read:
THE LIZARD DOES NOT CONFIRM
THE LIZARD DOES NOT DENYTHE LIZARD NOTES THAT
THE QUESTION ITSELF
VIOLATES RULE 1— The Lizard
This was interpreted by scholars as either a denial, a confirmation, or a request to measure first. The debate continues.
The Squirrel Problem
The Caffeinated Squirrel has read Pike’s Rules. The Squirrel has printed Pike’s Rules. The Squirrel has framed Pike’s Rules and hung them above its monitor, where they serve as a decorative reminder of principles the Squirrel violates simultaneously and with enthusiasm every time it opens an editor.
The Squirrel’s relationship with each rule:
- Rule 1: The Squirrel knows exactly where the bottleneck is. The Squirrel has always known. The Squirrel knew before the code was written. The Squirrel is wrong.
- Rule 2: The Squirrel does not measure. Measuring takes time. The Squirrel could be optimising during that time.
- Rule 3: The Squirrel’s n is always big. The Squirrel’s n has never been big. The Squirrel’s n is 3, but the Squirrel has implemented a skip list anyway, because what if n becomes big? (It will not become big.)
- Rule 4: The Squirrel prefers fancy algorithms. Fancy algorithms are interesting. Simple algorithms are boring. The Squirrel did not become a developer to be bored.
- Rule 5: The Squirrel focuses on algorithms, not data structures. The Squirrel has written a custom balanced binary search tree to store seven items. The items could have been in a slice.
“I IMPLEMENTED A LOCK-FREE CONCURRENT SKIP LIST WITH PROBABILISTIC BALANCING AND WAIT-FREE READS AND IT HANDLES OUR CONFIGURATION VALUES BEAUTIFULLY”
“How many configuration values?”
“SEVEN BUT THE POINT IS THE AMORTISED COMPLEXITY”
— The Caffeinated Squirrel, defending its choices at 2 AM
N Is Usually Small
Rule 3 deserves special attention, because it is the rule most frequently violated by the most intelligent developers. Intelligence, in this context, is the problem. The developer who knows what a red-black tree is will use a red-black tree. The developer who knows what amortised O(1) means will pursue amortised O(1). The developer who has read Cormen, Leiserson, Rivest, and Stein will implement what Cormen, Leiserson, Rivest, and Stein described, regardless of whether n justifies the constant factor.
N is usually small.
Your AbstractSingletonProxyFactoryBean has O(1) lookup. Congratulations. N is 3. A map literal would have been fine. A slice and a for-loop would have been fine. A piece of paper taped to the monitor would have been fine.
The connection to premature abstraction is direct: every unnecessary abstraction is a fancy algorithm applied to a small n. The generic DocumentProcessor<T> processes invoices. Only invoices. N is 1. The interface has one implementation. The factory produces one product. The abstraction is an O(1) solution to a problem that doesn’t exist.
“When in doubt, use brute force.”
— Ken Thompson, who co-created Unix and did not need a framework to do it
The Mythical Man-Month Connection
Fred Brooks stated Rule 5 in 1975, fourteen years before Pike restated it. Brooks’s version is longer but makes the same point: the data structures are the program. The algorithms are consequences of the data structures. If you show someone your algorithms without your data structures, they will be confused. If you show them your data structures without your algorithms, they will usually not need them.
This insight has been independently rediscovered by every programmer who has ever refactored a codebase and found that changing the data representation made three hundred lines of algorithm disappear. The algorithm was not wrong. The algorithm was compensating for a data structure that was wrong. Fix the data, and the algorithm fixes itself.
Or, as it has been shortened by practitioners who prefer brevity: write stupid code that uses smart objects.
Measured Characteristics
| Metric | Pike’s Rules | The Industry’s Practice |
|---|---|---|
| Rules | 5 | Ignored |
| Words | ~200 | Not enough, apparently |
| Years since publication | 37 | Still not listening |
| N (typical) | Small | “But what if it’s big?” |
| N (actual) | 3 | See above |
| Fancy algorithms deployed | Many | Necessary: few |
| Measurements taken before optimising | Rare | Recommended: always |
| Data structures chosen correctly | Sometimes | Algorithm rewrites saved: all of them |
| Developers who have read the rules | Most | Developers who follow them: few |
| Languages that enforce the rules | 1 (Go) | Languages that ignore them: the rest |
| Lizards who embody the rules | 1 | Squirrels who violate them: 1 (but enthusiastically) |
See Also
- Gall’s Law — Complex systems from simple ones. Pike’s Rules from simple algorithms.
- YAGNI — You aren’t gonna need that fancy algorithm. N is 3.
- Laziness — The virtue that makes you use brute force instead of cleverness.
- Boring Technology — The practice of choosing the simple thing. Pike’s Rules are the theory; Boring Technology is the deployment.
- Go — The language Pike built to make the rules difficult to violate.
- Lisp — The language where Rule 5 was demonstrated with bytes and a checkerboard.
- The Mythical Man-Month — Where Rule 5 was first stated, with flowcharts and tables.
