A Friendly Field Guide to 88 Timeless Principles That Shape How We Build Software.

View the interactive searchable html page

Foreword

Software engineering looks like a young craft, but the patterns that cause projects to thrive or stumble are surprisingly ancient. Over decades, engineers, managers, scientists, and even satirists have noticed the same things happening again and again — teams that mirror their org charts, deadlines that quietly slide, simple rules that quietly outperform clever ones. They condensed those observations into “laws.”

These laws are not laws of physics. They are laws of human nature applied to software. They describe what tends to happen when people, code, time, and complexity collide. Knowing them won’t guarantee success, but it will make you smarter than you were yesterday — and far less surprised by tomorrow.

This book takes 88 of the most influential laws and turns each one into a short, plain-English chapter. You will find:

  • The original wording of the law
  • plain-words explanation anyone can understand
  • Multiple bite-sized examples drawn from real software life
  • Tags so you can jump between related ideas (architecture, teams, testing, biases, etc.)
  • “watch out for” note with one practical takeaway

You don’t have to read the book in order. Skim the table of contents, find a law that’s biting you this week, and read just that page.

How to Use This Book

  • New to software? Start with Chapter 3 (Code Quality & Craft) and Chapter 8 (Cognitive Biases). They give you mental tools that pay off immediately.
  • Tech lead or engineering manager? Chapters 1, 2, and 4 will feel like a mirror.
  • Architect or distributed-systems engineer? Chapters 4 and 5 are where the deep dragons live.
  • Designer, frontend engineer, or product manager? Chapter 9 (UX & Human Factors) is built for you.
  • Curious reader? Chapter 8 is half psychology, half common sense, and worth the price of admission alone.

Each law follows the same simple template:

Law Name

Tags: tag-1tag-2 The Law: the original quote. In plain words: what it really means. Examples: three or four short, real-world illustrations. Watch out for: one practical takeaway.

Table of Contents

  1. People, Teams & Organizations — Conway’s LawBrooks’s LawDunbar’s NumberRingelmann EffectPrice’s LawPutt’s LawPeter PrincipleBus FactorDilbert PrincipleJoy’s Law
  2. Time, Estimation & Productivity — Parkinson’s LawParkinson’s Law of Triviality (Bikeshedding)Ninety-Ninety RuleHofstadter’s LawGoodhart’s LawGilb’s LawPareto Principle (80/20)Eagleson’s LawStein’s Law
  3. Code Quality & Craft — Boy Scout RuleYAGNIBroken WindowsTechnical DebtDRYKISSSOLIDLaw of DemeterPrinciple of Least AstonishmentChesterton’s FenceRule of ThreeWheeler’s LawGreenspun’s Tenth RuleSeparation of ConcernsComposition over InheritanceConvention over ConfigurationFail FastWorse Is Better
  4. Architecture & Design — Premature OptimizationHyrum’s LawGall’s LawLeaky AbstractionsTesler’s LawSecond-System EffectZawinski’s LawPostel’s LawEnd-to-End PrinciplePrinciple of Least PrivilegeGIGO
  5. Distributed Systems & Performance — CAP TheoremFallacies of Distributed ComputingAmdahl’s LawGustafson’s LawMetcalfe’s LawReed’s LawMoore’s LawWirth’s Law
  6. Testing, Debugging & Bugs — Murphy’s LawLinus’s LawKernighan’s LawTesting PyramidPesticide Paradox
  7. Software Evolution & Change — Lehman’s LawsSturgeon’s LawUnintended ConsequencesHype Cycle / Amara’s LawLindy EffectAtwood’s LawStroustrup’s LawWadler’s LawNaur’s Theory BuildingCargo Cult Programming
  8. Cognitive Biases & Mental Models — Dunning-KrugerHanlon’s RazorOccam’s RazorSunk Cost FallacyMap Is Not the TerritoryConfirmation BiasFirst Principles ThinkingInversionCunningham’s LawCurse of KnowledgeSurvivorship BiasPlanning Fallacy
  9. UX & Human Factors — Miller’s Law (7±2)Fitts’s LawHick’s LawJakob’s LawDoherty Threshold

Appendix A: Index of laws by tag Appendix B: A one-page cheat sheet

Chapter 1 — People, Teams & Organizations

“The hardest part of software isn’t the software. It’s the people who build it.”

Code doesn’t write itself, and humans aren’t compilers. The nine laws in this chapter describe what happens when groups of humans try to build something complex together — how communication shapes architecture, why adding people can slow you down, and why every team eventually has a “bus factor.”

Conway’s Law

Tags: architectureteamsorganizationcommunication

The Law: “Organizations design systems that mirror their own communication structure.”

In plain words: Software ends up looking like the org chart of the company that built it. If your teams don’t talk, your services won’t either.

Examples:

  1. Three teams, three services. A company with a frontend team, a backend team, and a database team almost always ships a three-tier app — even if a different shape would be simpler.
  2. Microservices follow squads. When Spotify split engineering into autonomous “squads,” the architecture naturally split into many small services, each owned by one squad.
  3. The shared library nobody owns. If two teams must edit the same module but rarely meet, that module turns into a bug-ridden swamp. The code can only be as healthy as the conversation around it.

Watch out for: Don’t fight Conway’s Law — use it. If you want a clean architecture, design the team boundaries first. This is sometimes called the “inverse Conway maneuver.”

Brooks’s Law

Tags: teamsproject-managementproductivity

The Law: “Adding manpower to a late software project makes it later.”

In plain words: When a project is already behind, throwing more people at it slows things down further, because existing team members must stop working to onboard the new ones.

Examples:

  1. The doomed deadline. A six-person team is two weeks behind. Management adds four engineers. The veterans now spend half their time explaining the codebase, and the deadline slips another month.
  2. Mythical man-month. Brooks pointed out you can’t simply trade “9 women × 1 month” for “1 woman × 9 months.” Some work has irreducible sequencing.
  3. Communication overhead. A 4-person team has 6 communication links; a 10-person team has 45. Each new person adds more coordination than capacity.

Watch out for: When a project is late, the answer is rarely “more people.” It’s usually “less scope,” “fewer dependencies,” or “more focus.”

Dunbar’s Number

Tags: teamsorganizationsocial

The Law: “There is a cognitive limit of about 150 stable relationships one person can maintain.”

In plain words: Humans can only really know about 150 other humans. Beyond that, relationships get shallow and tribal.

Examples:

  1. Engineering org scaling. Many companies notice culture starts to fracture around 150 employees — the moment when you stop recognizing everyone in the cafeteria.
  2. Open-source projects. Long-lived OSS communities tend to have a core of around 100–150 active contributors. Above that, governance has to formalize.
  3. Smaller teams ship faster. Amazon’s “two-pizza team” rule (small enough to feed with two pizzas) is Dunbar in disguise — keep groups small enough that everyone genuinely knows each other.

Watch out for: When your team or company crosses ~150 people, invest deliberately in structure, written communication, and rituals — informal trust will no longer scale on its own.

The Ringelmann Effect

Tags: teamsproductivityorganization

The Law: “Individual productivity decreases as group size increases.”

In plain words: The bigger the team, the less work each person does. People unconsciously slack off when responsibility is diluted — sometimes called “social loafing.”

Examples:

  1. The 12-person standup. With 12 people on a call, individuals contribute less, get less feedback, and quietly disengage. Split them into two teams of 6 and output goes up.
  2. Group code reviews. Asking “the team” to review a PR usually means no one reviews it. Assigning one named reviewer fixes it instantly.
  3. The huge hackathon team. A team of 8 at a hackathon often produces less than two teams of 4 — coordination cost overtakes added capacity.

Watch out for: Always assign work to a person, not a group. “Someone should fix this” is a nearly perfect way to ensure no one does.

Price’s Law

Tags: teamsproductivitypower-law

The Law: “The square root of the total number of participants does 50% of the work.”

In plain words: In any creative group, a small minority delivers most of the output. In a team of 100 people, about 10 of them produce roughly half of everything.

Examples:

  1. Open-source contributions. Look at any popular GitHub repo: a tiny core of maintainers writes the bulk of the commits.
  2. Stack Overflow answers. A small fraction of users wrote most of the high-quality answers used by millions.
  3. Team feature delivery. On a 25-person engineering team, the top ~5 ICs typically ship the lion’s share of the product roadmap.

Watch out for: Price’s Law is descriptive, not prescriptive. The danger is using it to justify ignoring everyone else — because today’s “average” contributor often becomes tomorrow’s top performer if invested in. Protect your top contributors and grow the rest.

Putt’s Law

Tags: managementorganizationhumor

The Law: “Those who understand technology don’t manage it, and those who manage it don’t understand it.”

In plain words: A satirical observation that technical depth and management authority rarely live in the same person.

Examples:

  1. The architect-turned-VP. A brilliant engineer is promoted to VP, stops writing code, and within two years is several frameworks behind the team they lead.
  2. The MBA dictating frameworks. A non-technical director mandates a rewrite in a trendy language they read about, ignoring the team’s protests.
  3. The “decoupled” decision. A roadmap is set without input from the engineers who will actually build it, then everyone is surprised when the estimates explode.

Watch out for: Pair every technology decision with a hands-on engineer. Treat Putt’s Law as a warning, not an excuse — the cure is curiosity on both sides.

Peter Principle

Tags: managementorganizationcareers

The Law: “In a hierarchy, every employee tends to rise to their level of incompetence.”

In plain words: People keep getting promoted as long as they’re good at their current job. Eventually they’re promoted into a role they’re not good at — and there they stay.

Examples:

  1. Star coder, struggling manager. The 10x engineer is promoted to manage a team. Coaching and conflict resolution turn out to be a different skill set entirely.
  2. The reluctant tech lead. A senior dev is promoted to tech lead, hates meetings, can’t context-switch, and the team loses both their best coder and their leadership.
  3. The senior architect who never architects. Someone is promoted for tenure rather than aptitude and now bottlenecks every design review.

Watch out for: Build dual career ladders. Engineers should be able to grow in pay and influence without being forced into management.

Bus Factor

Tags: teamsriskknowledge-management

The Law: “The minimum number of team members whose loss would put the project in serious trouble.”

In plain words: How many people would have to be hit by a bus before your project is in real trouble? If the answer is “1,” you have a problem.

Examples:

  1. The lone deploy script. Only one engineer knows how production deploys actually work. They go on vacation; releases freeze for two weeks.
  2. The undocumented payments service. A long-tenured engineer leaves; nobody else fully understands the billing service. Months of fear-driven, careful changes follow.
  3. The single AWS root account. One person holds all the master credentials. Everything is fine — until they’re not.

Watch out for: Pair programming, documentation, knowledge-sharing sessions, rotating on-call, and explicit “no single point of failure” reviews all raise your bus factor.

Dilbert Principle

Tags: managementorganizationhumor

The Law: “Companies tend to promote incompetent employees to management to limit the damage they can do.”

In plain words: A more cynical cousin of the Peter Principle. Instead of promoting people because they’re good, organizations sometimes promote them out of doing real work because they’re bad at it.

Examples:

  1. The kicked-upstairs engineer. A struggling coder is given a “leadership” title with no real responsibility — protecting both the codebase and HR.
  2. The committee assignment. Difficult employees end up on internal committees and process-improvement task forces, far from production code.
  3. The newly minted VP of Innovation. A rebrand of “we don’t know what to do with this person.”

Watch out for: This is a satire, not a strategy. If you find your company actually doing this, the underlying issue is usually a lack of courage to have honest performance conversations.

Joy’s Law

Tags: teamshiringhumility

The Law: “No matter who you are, most of the smartest people work for someone else.”

In plain words: Coined by Sun co-founder Bill Joy, this is a humbling reminder that no team — however elite — has a monopoly on talent. The best ideas are constantly being thought of outside your walls.

Examples:

  1. Open source. Companies that resist using outside libraries because “we have the best engineers” end up reinventing wheels — usually worse than the open-source ones built by thousands of contributors.
  2. Hiring blinders. A company that only hires from “top schools” or “top tech firms” misses 95% of the world’s brilliant engineers.
  3. External feedback. Soliciting design reviews, audits, or community input regularly catches mistakes your internal team’s groupthink missed.

Watch out for: Joy’s Law is not an excuse to underinvest in your own team — it’s an argument for humility and openness. Read papers. Watch other people’s talks. Hire people who’ll teach you something.

Chapter 2 — Time, Estimation & Productivity

“The first 90% of the work takes 90% of the time. The last 10% takes the other 90%.”

If software engineers had a national sport, it would be missing deadlines. The six laws below explain why — and how to think about time, measurement, and productivity without lying to yourself.

Parkinson’s Law

Tags: productivityproject-managementtime

The Law: “Work expands to fill the time available for its completion.”

In plain words: Give yourself two weeks for a task and it will take two weeks. Give yourself two days, and somehow the same task fits.

Examples:

  1. The two-week feature. A simple feature is scheduled for a sprint. It expands — gold-plating, extra refactors, “while we’re here” cleanups — to fill the entire sprint.
  2. Meetings. A 60-minute meeting almost always uses all 60 minutes, even when the agenda is 15 minutes long.
  3. Hackathons. A team builds an entire MVP in 24 hours that they previously claimed would take six months. The constraint creates the focus.

Watch out for: Use deliberately tight, short iterations. “What’s the smallest version we can ship by Friday?” beats “what can we deliver in Q3?” almost every time.

Parkinson’s Law of Triviality (Bikeshedding)

Tags: productivitymeetingsdecision-making

The Law: “The time spent on any agenda item is in inverse proportion to the sum of money or importance involved.”

In plain words: The bigger and more complex a decision, the less people debate it — because most people don’t feel qualified to weigh in. The trivial stuff, however, everyone has an opinion on. Hence: hours spent picking the color of the bike shed, minutes spent on the nuclear reactor.

Examples:

  1. The button color marathon. A team meeting allocates “30 minutes for the database choice, 30 minutes for the button color.” Both meetings overrun — only the second one.
  2. Naming things. A 90-minute argument over whether a class should be UserManagerUserService, or UserHandler — while a load-bearing architectural decision is rubber-stamped in a Slack thread.
  3. The CI pipeline cleanup. Major migration discussions are deferred “to think about more”; the indentation style PR has 47 comments.

Watch out for: When a debate is heating up, ask: “Are we arguing about this because it matters, or because it’s the part we all understand?” Time-box trivial decisions and force a coin flip if needed.

The Ninety-Ninety Rule

Tags: productivityestimationhumor

The Law: “The first 90% of the code accounts for the first 90% of development time; the remaining 10% accounts for the other 90%.”

In plain words: Software is “almost done” for far longer than it’s actually done. The last details — edge cases, polish, deployment, performance — eat enormous amounts of time.

Examples:

  1. The “demo-ready” prototype. It looks finished, but error handling, security, and accessibility take another month.
  2. The migration that was “almost done in March.” It ships in October, after every weird historical record is finally accounted for.
  3. The 99% mobile app. All features work — except the rare iOS version that crashes, the offline mode, and the App Store review.

Watch out for: When someone says “I’m 90% done,” ask what’s left. The remaining 10% is almost always more dangerous than the first 90%.

Hofstadter’s Law

Tags: estimationproductivitytime

The Law: “It always takes longer than you expect, even when you take into account Hofstadter’s Law.”

In plain words: Even when you pad your estimates because you know you’ll be late, you’ll still be late. Estimation is humbling and recursive.

Examples:

  1. “This will take a week.” Two weeks later, it’s still going. You add a buffer next time. It still takes longer.
  2. OS rewrites. Every major operating system rewrite — from Windows Vista to Android updates — has overshot its plan, often by years.
  3. Personal coding projects. “I’ll have my side project done this weekend.” Six months later, it’s still sitting on a feature branch.

Watch out for: Use historical data, not gut feelings, to estimate. And add a buffer to your buffer.

Goodhart’s Law

Tags: metricsmanagementincentives

The Law: “When a measure becomes a target, it ceases to be a good measure.”

In plain words: The moment you start judging people on a metric, they game it — and the metric stops reflecting reality.

Examples:

  1. Lines of code. Reward LOC and developers write longer, worse code.
  2. Bug count as KPI. If testers are paid per bug, they file lots of trivial ones. If devs are penalized per bug, they hide them.
  3. Velocity / story points. Treat sprint velocity as a target and teams quietly inflate point estimates until the chart looks good.

Watch out for: Use metrics for conversation, not control. The job of a metric is to spark a useful question, not to assign blame.

Gilb’s Law

Tags: metricsmeasurementimprovement

The Law: “Anything you need to quantify can be measured in some way better than not measuring it.”

In plain words: A rough, imperfect measurement beats a vague, untested feeling. Don’t refuse to measure something just because the measurement isn’t perfect.

Examples:

  1. “Our system is fast.” Compared to what? A simple p95 latency number — even if approximate — turns the conversation from feelings to facts.
  2. Developer happiness. A monthly 1-question survey (“How happy are you, 1–5?”) is crude but enormously more useful than guessing.
  3. Onboarding effectiveness. Time-to-first-PR for new engineers is a noisy metric, but tracking it reveals trends you’d otherwise miss.

Watch out for: Pair every imperfect metric with humility. Measure to learn, not to decide blindly. (See Goodhart’s Law for the dark side.)

Pareto Principle (the 80/20 Rule)

Tags: productivityprioritizationpower-law

The Law: “80% of the problems result from 20% of the causes.”

In plain words: A small slice of inputs creates most of the output — good or bad. Find that slice and focus there.

Examples:

  1. Bugs. Roughly 80% of crashes come from 20% of the code paths. Fixing those few hot spots produces an outsized improvement.
  2. Performance. A few slow queries usually account for most of the database load. Optimize them first.
  3. Customer support. Twenty percent of customers tend to file 80% of the tickets. Either help them succeed or build self-service for their use case.
  4. Features. Most users only use a handful of features. Knowing which ones are vital prevents you from wasting time polishing the rest.

Watch out for: Pareto is a prioritization tool, not an excuse to ignore the long tail forever. Use it to choose what to do first, not what to do only.

Eagleson’s Law

Tags: productivitycrafthumor

The Law: “Any code of your own that you haven’t looked at for six or more months might as well have been written by someone else.”

In plain words: Your future self is a stranger. The clever code you wrote last spring will look just as confusing as anyone else’s by autumn.

Examples:

  1. The “obvious” function. A clever one-liner that needed no comment when written becomes a 20-minute mystery six months later.
  2. The undocumented script. “I’ll remember why this lives here.” You won’t.
  3. Your own bug fix from 2021. You stare at your old commit message — “fix edge case in parser” — and you have no idea what edge case, what parser, or why.

Watch out for: Write for the stranger you’ll become. Comments, README updates, and tests are letters to your future self.

Stein’s Law

Tags: mental-modeleconomicstechnical-debt

The Law: “If something cannot go on forever, it will stop.”

In plain words: Coined by economist Herb Stein, this dryly obvious sentence is a powerful tool for technical debt and unsustainable practices. If a trend mathematically can’t continue — escalating outages, exploding costs, ballooning build times — it will stop. The only question is whether you stop it on your terms or it stops on its own.

Examples:

  1. Cloud bill doubling every quarter. It cannot keep doubling forever. Either you optimize, or finance does it for you with a hatchet.
  2. Build times growing every sprint. “It’s only 30 seconds longer this month.” Compounded, in a year you’ll have a 90-minute build that nobody trusts. The trend will stop — productively or painfully.
  3. A flaky test you keep retrying. It cannot stay flaky-but-tolerated forever. Either you fix it, or it eventually masks a real bug that ships to customers.

Watch out for: Use Stein’s Law to build the case for now. “We can’t keep doing this” is the start of the conversation, not the end. Project the trend and show what “stop” actually looks like.

Chapter 3 — Code Quality & Craft

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”

These nine laws are the daily craft of professional software development. Most of them are about restraint: not writing code, not duplicating yourself, not surprising the next developer (who is often you, six months from now).

The Boy Scout Rule

Tags: code-qualitymaintenancecraft

The Law: “Leave the code better than you found it.”

In plain words: Every time you touch a file, leave it slightly cleaner than you found it. Tiny improvements compound; tiny rots compound just as fast in the other direction.

Examples:

  1. Renaming as you go. While fixing a bug, you spot a confusingly named variable. Rename it. The PR grows by two lines and the next reader is grateful.
  2. Deleting dead code. You see an unused import or a commented-out function. Remove it. There’s version control if you ever miss it.
  3. One extra test. Each time you fix a bug, add the test that would have caught it. The codebase ratchets toward safer.

Watch out for: Don’t let “clean it up” become “rewrite the whole module while I’m here.” Keep cleanups small enough to land in the same PR.

YAGNI (You Aren’t Gonna Need It)

Tags: code-qualitydesignsimplicity

The Law: “Don’t add functionality until it is necessary.”

In plain words: Build only what you need right now. The “we might need this someday” feature usually never gets used — but it always has to be maintained.

Examples:

  1. The configurable everything. A simple constant becomes a config flag, then an environment variable, then a UI toggle — for a setting nobody has ever changed.
  2. The premature plug-in system. A small app gains a plugin architecture before it has any plugins. Three years later, it still has no plugins, just complexity.
  3. The future-proof interface. An interface designed for “any backend” gets used with exactly one backend forever. The abstraction adds bugs without paying for itself.

Watch out for: Whenever you say “we might need…”, write down the cost of building it now versus the cost of adding it later. Most of the time, “later” is cheaper.

Broken Windows Theory

Tags: code-qualitymaintenanceculture

The Law: “Don’t leave broken windows (bad designs, wrong decisions, or poor code) unrepaired.”

In plain words: Once a codebase has visible signs of decay — broken tests, obvious hacks, ugly code — people stop caring about quality. The damage spreads.

Examples:

  1. The flaky test. One flaky test gets ignored. Soon the whole suite is “mostly green,” and real failures slip through.
  2. The TODO graveyard. A few TODO comments become hundreds. Nobody believes any of them will ever be addressed, including the people who wrote them.
  3. The first hack. “Just this once” string-concatenated SQL becomes the pattern; six months later the entire data layer is unsafe.

Watch out for: Fix small problems immediately. Quality culture is built by what you tolerate, not by what you talk about in retros.

Technical Debt

Tags: code-qualitymaintenancemetaphor

The Law: “Technical Debt is everything that slows us down when developing software.”

In plain words: A shortcut today is a loan from your future self. Like financial debt, a little is fine and even useful — but unpaid interest piles up until you can barely move.

Examples:

  1. The “we’ll refactor it later” module. Two years later, every change to it takes three times as long as it should.
  2. No tests on a critical service. Each release is a hand-tested, white-knuckled event. Velocity grinds to a halt.
  3. An ancient framework version. Upgrading is now a multi-month project because no one paid the small upgrade cost when it was easy.

Watch out for: Tracked, intentional debt is a tool. Untracked, accidental debt is a slow disaster. Make a list, prioritize it, and pay it down a little every sprint.

DRY (Don’t Repeat Yourself)

Tags: code-qualitydesignprinciples

The Law: “Every piece of knowledge must have a single, unambiguous, authoritative representation.”

In plain words: Don’t have two places where the same fact lives — they will eventually disagree. Each rule, value, or piece of logic should live in one definitive spot.

Examples:

  1. One source of truth for tax rules. If tax logic lives in both the frontend and backend, one will quietly fall behind, and customers will be over- or under-charged.
  2. Constants over magic numbers. MAX_ATTEMPTS = 3 defined once and imported everywhere beats if attempts > 3 scattered across the codebase.
  3. Schema generated from one place. Backend models, API contracts, and database tables generated from a single schema avoid the “three shapes of the same object” anti-pattern.

Watch out for: DRY is about knowledge, not code. If two functions look alike but represent different concepts, leave them separate. Premature DRY creates tangled dependencies.

KISS (Keep It Simple, Stupid)

Tags: code-qualitydesignsimplicity

The Law: “Designs and systems should be as simple as possible.”

In plain words: Simpler is better. Smart-looking complexity is usually a sign you don’t understand the problem yet.

Examples:

  1. The for-loop that beats the framework. A 5-line loop replaces a 60-line use of a streaming library — and is easier to debug forever.
  2. A scheduled cron job. A simple cron beats spinning up a distributed scheduler for a job that runs once a night.
  3. A single SQL query. A clever microservice mesh replaced by one well-indexed JOIN. Fewer moving parts; fewer 3 a.m. pages.

Watch out for: “Simple” doesn’t always mean “small.” It means easy to understand and change. Sometimes the simpler solution is more code, written more clearly.

SOLID Principles

Tags: code-qualityobject-orientedprinciples

The Law: “Five main guidelines that enhance software design, making code more maintainable and scalable.”

In plain words: SOLID is a set of five rules from Robert C. Martin for writing object-oriented code that doesn’t fall apart over time:

  • S — Single Responsibility: A class should do one thing.
  • O — Open/Closed: Open for extension, closed for modification.
  • L — Liskov Substitution: Subclasses should work wherever their parent works.
  • I — Interface Segregation: Many small interfaces beat one fat one.
  • D — Dependency Inversion: Depend on abstractions, not concrete classes.

Examples:

  1. Single Responsibility. A User class that handles authentication, sends emails, and logs activity is doing three jobs. Split it into three.
  2. Open/Closed. Want to add a new payment method? You should be able to add a new class, not modify the existing payments engine.
  3. Liskov. If Square extends Rectangle but breaks code that resizes rectangles, the inheritance is wrong even if the geometry feels right.
  4. Interface Segregation. A Printer interface with print()scan()fax() forces every printer to implement methods it doesn’t support. Split the interface.
  5. Dependency Inversion. A reporting module depending on IDatabase (an interface) — not MySQLDatabase (a concrete class) — can be tested with a fake and swapped in production.

Watch out for: SOLID is heuristics, not religion. Treat it as a way to ask better questions, not a checklist to mechanically apply.

Law of Demeter

Tags: code-qualityobject-orientedcoupling

The Law: “An object should only interact with its immediate friends, not strangers.”

In plain words: Don’t reach through chains of objects. If you find yourself writing a.getB().getC().doSomething(), you’ve coupled your code to the inner structure of ab, and c. Talk to a only.

Examples:

  1. Train wreck code. order.getCustomer().getAddress().getZip() breaks every time the customer or address structure changes. Add a method on order instead: order.getCustomerZip().
  2. Service-to-service. A service calling deep into another service’s internal classes is fragile. Hide the internals behind a clean API.
  3. UI components. A child component reaching into a grandparent’s state via props chains is a Demeter violation in React/Vue/Angular.

Watch out for: Sometimes a bit of “law breaking” is fine for clarity. The rule is a smell test, not a courtroom verdict.

Principle of Least Astonishment

Tags: code-qualityuxdesign

The Law: “Software and interfaces should behave in a way that least surprises users and other developers.”

In plain words: Things should do what people expect. If your function is called getUser(), it shouldn’t also write to the database.

Examples:

  1. Surprising side effects. A “read” function that mutates state is the classic violation. Reading should be safe.
  2. Convention over invention. A “Cancel” button on the right and an “OK” button on the left, when every OS does the opposite, is a small daily papercut.
  3. Consistent error handling. If 90% of your API returns JSON errors but one endpoint returns plaintext, every integrator wastes an afternoon discovering that.

Watch out for: When in doubt, do what your language, framework, and ecosystem do. Boring, predictable code is a feature.

Chesterton’s Fence

Tags: code-qualitylegacy-codemental-model

The Law: “Don’t remove a fence until you know why it was put there.”

In plain words: If you find code that looks pointless, the safe assumption is not that it’s pointless — it’s that you don’t yet understand why it exists. Investigate before deleting.

Examples:

  1. The mysterious sleep(50). “What is this 50 ms wait for?” Removing it works perfectly in dev — and breaks a fragile race condition in production once a week.
  2. The strange data conversion. A piece of code converts strings to lowercase before comparison. Looks redundant. Removing it breaks a 5-year-old integration with a vendor whose API isn’t case-consistent.
  3. The “dead” feature flag. Looks unused. Was actually keeping a tiny set of legacy enterprise customers from breaking. Their support tickets explain it.

Watch out for: Before removing anything you don’t understand, run git blame, search the issue tracker, and ask the team. Add tests that capture the current behavior before changing it.

Rule of Three (Refactoring)

Tags: code-qualityrefactoringdesign

The Law: “The third time you see the same pattern, it’s time to refactor.”

In plain words: Once is fine. Twice may be coincidence. Three times means you’ve found a real pattern worth abstracting. Premature abstraction (after only one or two cases) usually creates bad abstractions.

Examples:

  1. The duplicated validator. You write a similar validation in two places. Resist consolidating yet — they may diverge. When the third one appears, now you know the shared concept.
  2. The “shared” library that wasn’t. A team extracted shared logic from two services. It turned out the third use case had different requirements; the shared lib became a knot of conditional flags. (Repeat: see DRY.)
  3. Helper functions. Two slightly different formatCurrency calls? Leave them. A third one? Now extract — and you’ll usually see what the real abstraction should be.

Watch out for: Wrong abstractions are more expensive than duplication. When in doubt, duplicate first, abstract later.

Wheeler’s Law (Fundamental Theorem of Software Engineering)

Tags: code-qualityarchitecturedesign

The Law: “All problems in computer science can be solved by another level of indirection — except for the problem of too many levels of indirection.”

In plain words: Whenever something is hard to change, hard to test, or tightly coupled, the answer is usually “add a layer.” But every layer has a cost; pile too many on and you’ve made the system worse, not better.

Examples:

  1. Interfaces save the day. A class needs to be tested in isolation? Wrap the dependency in an interface — instant testability.
  2. Adapter pattern. A new vendor’s API looks different from the old one? Add a thin adapter; nothing else has to change.
  3. The over-layered nightmare. A class instantiates a factory that builds a strategy that wraps a service that delegates to a handler that calls a repository. Adding a field requires editing six files.

Watch out for: Add indirection when it solves a real problem. Each layer should justify its existence with a concrete win — testability, configurability, swap-ability.

Greenspun’s Tenth Rule

Tags: code-qualityhumorlanguage-design

The Law: “Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.”

In plain words: As programs grow, they tend to reinvent features that more powerful languages already provide — usually badly. The point isn’t really about Lisp; it’s that complex systems eventually grow their own malformed configuration languages, plugin systems, and macro systems.

Examples:

  1. The home-grown rules engine. Every large business app eventually invents one — usually with a custom DSL nobody can debug.
  2. The YAML that became Turing-complete. What started as simple config now has loops, conditionals, and templates. Congratulations, you wrote a language.
  3. The framework’s “advanced configuration.” Spring, Webpack, and similar tools accumulate so many configuration features they essentially become programming languages.

Watch out for: When you find yourself building “config that’s actually code,” step back. Either embrace it (use a real language) or simplify the system so the elaborate config isn’t needed.

Separation of Concerns

Tags: code-qualitydesignprinciples

The Law: “Each module or layer should address one concern, and only that concern.”

In plain words: Coined by Edsger Dijkstra. Mixing different responsibilities — say, business logic, persistence, and UI — into one component makes the whole thing brittle and hard to change. Pull them apart so each can evolve independently.

Examples:

  1. MVC. Model (data), View (display), Controller (orchestration) — each does one job, each can change without dragging the others along.
  2. Pure functions. A function that just transforms input to output, separately from one that reads/writes the database, is much easier to test and reason about.
  3. The 1,000-line “controller.” When auth, validation, business logic, and database calls all live in one place, every change risks breaking unrelated features.

Watch out for: Don’t confuse “many files” with “good separation.” Concerns should be cleanly separated, not just chopped into smaller chunks of the same tangle.

Composition Over Inheritance

Tags: code-qualityobject-orienteddesign

The Law: “Favor composing objects from smaller pieces over deep inheritance hierarchies.”

In plain words: Inheritance is one of the most-loved, most-misused features of object-oriented programming. Deep class trees are rigid: you can’t change a parent without risking every descendant. Composing behavior from small, focused parts is more flexible.

Examples:

  1. The Animal class tragedy. Animal → Mammal → Dog → ServiceDog → GuideDog looks elegant — until you need a class that’s a dog and a robot. Inheritance can’t model that without contortions.
  2. Plug-in behavior. Instead of a LoggingUser subclass, give the User class a Logger it composes with. Now any object can have a logger, and you can swap loggers easily.
  3. React/Vue components. Modern UIs avoid inheritance trees in favor of composition: small components, combined like Lego.

Watch out for: Inheritance is still useful — for true “is-a” relationships and well-defined extension points. The rule is “favor composition,” not “ban inheritance.”

Convention Over Configuration

Tags: code-qualitydesignframeworks

The Law: “A framework should provide sensible defaults; configuration is only required when you deviate.”

In plain words: Popularized by Ruby on Rails. The philosophy: rather than asking developers to specify every detail, the system assumes something reasonable. You only override the assumptions you actually want to change.

Examples:

  1. Rails project layout. Drop a controller in app/controllers/users_controller.rb and it Just Works — no configuration needed.
  2. Maven/npm defaults. Run a command and the tool knows where source, tests, and outputs go. You don’t write hundreds of lines of XML for a “hello world.”
  3. The opposite trap. A poorly designed framework might require 200 lines of config before it does anything useful. Onboarding a new developer takes a week.

Watch out for: Conventions only help when they’re well chosen and consistent. Bad conventions are worse than explicit configuration, because they fail silently when you don’t follow them.

Fail Fast

Tags: code-qualityreliabilitydesign

The Law: “When something goes wrong, fail loudly and immediately rather than silently corrupting state.”

In plain words: Errors that surface immediately are easier to debug than errors that quietly mutate data and explode three hours later in a totally unrelated service.

Examples:

  1. Validate inputs at the boundary. A function that throws on invalid input at call time is a friend. One that returns a confusing default and crashes deep in the call stack is an enemy.
  2. Crash on unexpected nulls. Better to raise an explicit exception than to use ?? "default" and quietly skip a critical record.
  3. Startup health checks. A service that won’t start if a critical dependency is unreachable saves you from a half-functional system that pretends to be healthy.

Watch out for: “Fail fast” doesn’t mean “be fragile.” Resilience patterns like retries and circuit breakers still apply — but for expected, transient failures, not for unknown corruption.

Worse Is Better (Gabriel)

Tags: code-qualityphilosophydesign

The Law: “A simpler design that is shipped and adopted often beats a more elegant design that isn’t.”

In plain words: Richard Gabriel’s famous essay argued that Unix and C “won” — even though they were arguably less elegant than alternatives like Lisp Machines — because their simpler, more pragmatic design was easier to build, port, and adopt. Sometimes “good enough now” beats “perfect later.”

Examples:

  1. Unix vs. Lisp Machines. The “right” design lost; the rough-but-shippable design conquered the world.
  2. JavaScript. Rushed in 10 days, full of quirks, runs everything on the planet.
  3. MVPs. A minimum viable product that real users use beats a polished prototype nobody has tried.

Watch out for: “Worse Is Better” is not “ship garbage.” It’s “favor simplicity, portability, and momentum over theoretical elegance.” The crap you ship still has to actually work for real users.

Chapter 4 — Architecture & Design

“You should never start with the architecture. You should start with the simplest thing that could possibly work.”

Architecture is the art of choosing what to not build, what to hide, and what to expose. The eight laws below cover the most common pitfalls of designing systems that have to last more than a quarter.

Premature Optimization (Knuth’s Optimization Principle)

Tags: architectureperformancedesign

The Law: “Premature optimization is the root of all evil.”

In plain words: Don’t make code complicated to make it fast until you have proof that it’s actually slow. Optimize later, with data.

Examples:

  1. The micro-optimized loop. Hours spent shaving microseconds off a function that ran twice a day. The bottleneck was elsewhere.
  2. The caching layer nobody needed. A new app gets Redis “for performance” before it has 100 users. Now the team has caching bugs and low traffic.
  3. The unreadable bit-twiddling. Clever bitwise tricks save a few cycles but make the code unmaintainable, while the real bottleneck is a slow database query.

Watch out for: Knuth’s full quote includes “yet we should not pass up our opportunities in that critical 3%.” Profile first. Optimize the proven hot spots.

Hyrum’s Law

Tags: architectureapiscompatibility

The Law: “With a sufficient number of API users, all observable behaviors of your system will be depended on by somebody.”

In plain words: Once enough people use your API, every quirk of its behavior — even bugs and undocumented details — becomes part of its contract.

Examples:

  1. Order of map keys. A library “happens” to return JSON keys in insertion order. Customers depend on it. The next version sorts them; everyone breaks.
  2. Error message text. Tools parse your error string. You polish the wording in v2. Their parsers explode.
  3. Default sort order. Your DB query returned rows in id order “by accident.” A customer’s report relies on it. You add an index; the order changes; revenue dashboards go sideways.

Watch out for: Document what you guarantee, randomize what you don’t (e.g., shuffle JSON key order in test environments), and expect that your “internal” behavior is somebody’s external contract.

Gall’s Law

Tags: architecturedesignevolution

The Law: “A complex system that works is invariably found to have evolved from a simple system that worked.”

In plain words: You can’t design a complex working system from scratch. Successful big systems always grew up from smaller systems that were already working.

Examples:

  1. The internet. Today’s global network grew from ARPANET — a tiny, simple, working system between four universities.
  2. Unix and Linux. Decades-old, originally minimal kernels evolved feature by feature into the foundation of the modern world.
  3. Big Bang rewrites. Most “rebuild it from scratch” projects fail; the few that succeed look suspiciously like incremental migrations in disguise.

Watch out for: When tackling a complex problem, build something embarrassingly small first. Make it work, then make it bigger. Resist the urge to design the cathedral on day one.

The Law of Leaky Abstractions

Tags: architecturedesignabstraction

The Law: “All non-trivial abstractions, to some degree, are leaky.”

In plain words: Every abstraction hides details — until it doesn’t. Eventually you have to know what’s underneath.

Examples:

  1. TCP/IP. It pretends to be a reliable byte stream. But on a flaky network, latency, retransmissions, and packet loss reach up and bite you.
  2. ORMs. SQLAlchemy or Hibernate hide the database — until they generate a query that takes 30 seconds and you have to read the SQL.
  3. Cloud “magic.” Serverless platforms promise “no infrastructure,” yet you’ll still hit cold-start latency, memory limits, and obscure timeouts.

Watch out for: Use abstractions, but learn the layer beneath them. The day the abstraction leaks is the day you’ll need that knowledge most.

Tesler’s Law (Conservation of Complexity)

Tags: architecturedesignux

The Law: “Every application has an inherent amount of irreducible complexity that can only be shifted, not eliminated.”

In plain words: A problem only has so much complexity. You can move it around — onto users, onto developers, onto operators — but you can’t make it disappear.

Examples:

  1. Date/time zones. Either your code handles every weird case, or your users are forced to. Somebody has to know about DST.
  2. Configuration vs. defaults. Sensible defaults move complexity from the user to the developer. Required config moves it the other way.
  3. Error messages. Either the system handles errors gracefully, or the user has to interpret a stack trace.

Watch out for: A great design moves complexity to whoever is best able to handle it — usually the developers, not the user. Ask: “Whose life is this making harder?”

Second-System Effect

Tags: architecturedesignover-engineering

The Law: “Small, successful systems tend to be followed by overengineered, bloated replacements.”

In plain words: Once a team finishes a successful, lean version 1, the version 2 they design is often bloated with every feature they ever wanted. It usually takes years and may never ship.

Examples:

  1. OS/2 and the original Macintosh System 7 — both heavier than their predecessors, both struggled.
  2. Internal frameworks v2. A simple, useful internal library is replaced by a “platform” that does everything and pleases no one.
  3. The grand replatform. A small, trusted product gets a Big Rewrite that adds plug-ins, multi-tenancy, theming, and AI before its users asked for any of those things.

Watch out for: Resist the urge to “fix everything” in v2. Ship a v2 that does one thing better than v1, and then iterate.

Zawinski’s Law

Tags: architecturefeature-creephumor

The Law: “Every program attempts to expand until it can read mail.”

In plain words: A satirical observation that successful software accretes features over time, often growing beyond its original purpose.

Examples:

  1. Slack. Started as team chat. Now it does video, voice, polls, workflow automation, and yes — email-like channels.
  2. Visual Studio Code. A text editor that became a full IDE, terminal, debugger, and remote-development platform.
  3. Browsers. Chrome and Firefox now host word processors, video calls, IDEs, and entire operating systems.

Watch out for: Feature creep is gravity. Pick what your product won’t be at least as deliberately as what it will be.

Postel’s Law

Tags: architectureapisprotocols

The Law: “Be conservative in what you do, be liberal in what you accept from others.”

In plain words: When you receive data, be forgiving. When you send data, be strict. This is also called the “Robustness Principle.”

Examples:

  1. HTML. Browsers accept all kinds of malformed HTML and try to render it. That tolerance helped the web grow.
  2. REST APIs. Accept extra unknown fields gracefully (don’t crash); only emit fields you know are correct.
  3. Email. Mail servers accept a wide variety of header oddities; sending strictly conforms to RFCs.

Watch out for: There’s a downside — too much liberality lets bad data fester and creates Hyrum’s-Law nightmares. Modern thinking favors a balance: tolerant but logged, and rejected at boundaries you control.

End-to-End Principle (Saltzer)

Tags: architecturedistributed-systemsdesign

The Law: “Application-specific functions should reside at the endpoints of a system, not in the middle.”

In plain words: Coined by Jerry Saltzer and others in the 1980s. The middle of the network — routers, intermediaries, proxies — should stay simple. The smarts (encryption, retries, validation, application logic) belong at the endpoints, where they have full context.

Examples:

  1. TCP error correction. The network doesn’t guarantee perfect delivery; the endpoints do, with checksums and retransmissions. The web only works because of this division of labor.
  2. End-to-end encryption. Don’t trust the middle (ISPs, CDNs, mailboxes) to keep secrets. Encrypt at the sender, decrypt at the receiver.
  3. The over-smart middlebox. A “helpful” proxy that rewrites headers, caches things it shouldn’t, or modifies bodies is a nightmare to debug — because it’s making decisions without the application’s context.

Watch out for: Resist the urge to push features into shared infrastructure. Smart networks tend to break in surprising ways; smart endpoints with dumb pipes are more flexible and reliable.

Principle of Least Privilege

Tags: architecturesecuritydesign

The Law: “Every component should have only the permissions it strictly needs to do its job — and no more.”

In plain words: A core principle of security from the 1970s (Saltzer & Schroeder). If a service is compromised, its blast radius is limited to whatever access it had. Less access = less damage.

Examples:

  1. Read-only DB users. A reporting service connects to the database with read-only credentials. Even if it’s hijacked, the attacker can’t modify data.
  2. Scoped API tokens. A CI deploy token that can deploy just one service, not everything. If it leaks, the damage is bounded.
  3. The over-privileged dev account. An engineer’s laptop is breached. They had admin everywhere “for convenience.” Now the attacker has admin everywhere too.

Watch out for: Least privilege creates friction. Build tooling that makes it easy to do the right thing — auto-rotate credentials, create scoped tokens on demand — or developers will route around it.

GIGO (Garbage In, Garbage Out)

Tags: architecturedataquality

The Law: “A computer cannot produce good output from bad input.”

In plain words: Old, but more relevant than ever in the age of data pipelines and AI. No matter how sophisticated your model, dashboard, or ML system is, if the input data is wrong, the output will be wrong — often in ways that look perfectly plausible.

Examples:

  1. The biased ML model. A hiring model trained on historical hires reproduces (and amplifies) the historical biases in those decisions.
  2. The “perfect” dashboard. A beautiful executive dashboard pulls from a feed where 30% of records have null categories. Every chart is silently wrong.
  3. The CSV import that ate Friday. Someone uploads a file with a misordered column. Three days later, support is full of customer complaints with mysterious symptoms.

Watch out for: Validate aggressively at the boundary. Treat input data as adversarial (even when it isn’t), and reject what you can’t make sense of rather than silently coercing it. Pair with Fail Fast.

Chapter 5 — Distributed Systems & Performance

“There are only two hard things in distributed systems: exactly-once delivery, ordered messages, and exactly-once delivery.”

The moment you cross a network, the laws of physics — and the laws of probability — start ruling your code. Five laws below describe what those rules feel like in practice.

CAP Theorem

Tags: distributed-systemsarchitecturedatabases

The Law: “A distributed system can guarantee only two of: consistency, availability, and partition tolerance.”

In plain words: When some part of your distributed system can’t talk to another part, you must choose: keep returning data that might be stale (Available), or refuse to answer until everyone agrees (Consistent). You can’t have both at the same time during a partition.

Examples:

  1. Banking systems. Strongly consistent: better to show “service unavailable” than two different balances.
  2. Social media feeds. Highly available: better to show a slightly stale feed than no feed at all.
  3. Shopping carts. Many e-commerce systems choose availability and reconcile conflicts later (e.g., “merge carts”).

Watch out for: CAP is binary only during network partitions. The day-to-day reality is “PACELC” — even when networks are healthy, you trade latency for consistency. Pick the trade-off that matches your domain.

Fallacies of Distributed Computing

Tags: distributed-systemsarchitecturenetworking

The Law: “A set of eight false assumptions that new distributed system designers often make.”

In plain words: Anyone building a networked system tends to assume things that aren’t true. Knowing the eight fallacies up front saves years of debugging.

The eight fallacies (originally from Sun Microsystems):

  1. The network is reliable.
  2. Latency is zero.
  3. Bandwidth is infinite.
  4. The network is secure.
  5. Topology doesn’t change.
  6. There is one administrator.
  7. Transport cost is zero.
  8. The network is homogeneous.

Examples:

  1. The reliable network. A simple httpClient.get(url) works in dev. In prod, it sometimes times out, sometimes returns half a response, sometimes loops back as duplicate calls.
  2. Latency is zero. A perfectly fine in-memory loop becomes a disaster when each iteration crosses a network boundary.
  3. Topology doesn’t change. A microservice’s IP changes during deploys; clients with cached addresses break mysteriously.

Watch out for: Build retries, timeouts, and circuit breakers from day one. Test under simulated network failure (chaos engineering). Assume every fallacy is biting you somewhere right now.

Amdahl’s Law

Tags: performanceparallelismscalability

The Law: “The speedup from parallelization is limited by the fraction of work that cannot be parallelized.”

In plain words: Even if part of your program runs infinitely fast on infinite cores, the serial part still has to run at its old speed. That serial part sets the ceiling.

Examples:

  1. The 95% parallel job. Even if 95% of a job parallelizes perfectly, the maximum theoretical speedup is 20× — no matter how many cores you throw at it.
  2. The slow startup. A data pipeline parallelizes its work but spends 3 minutes loading config first. Adding workers doesn’t change the 3-minute floor.
  3. Build systems. Massively parallel builds are limited by the longest dependency chain — the “critical path.”

Watch out for: Profile to find the serial bottleneck before scaling out. Parallelism without measuring is expensive theatre.

Gustafson’s Law

Tags: performanceparallelismscalability

The Law: “It is possible to achieve significant speedup in parallel processing by increasing the problem size.”

In plain words: A counterpoint to Amdahl. If you keep the workload fixed, parallelism hits a ceiling. But if you grow the workload, more cores let you do more in the same wall-clock time.

Examples:

  1. Bigger simulations, same time. A weather model that used to predict 1 day in 1 hour now predicts 7 days in 1 hour with more processors.
  2. High-resolution rendering. Adding more GPUs doesn’t make a single 1080p frame render faster, but it lets you render 4K in the same time.
  3. Web search. Crawling more of the web in the same time is a Gustafson-style win.

Watch out for: Amdahl tells you when adding hardware won’t help. Gustafson tells you when growing the problem will. Knowing both makes your scaling story honest.

Metcalfe’s Law

Tags: networksgrowthbusiness

The Law: “The value of a network is proportional to the square of the number of users.”

In plain words: A network with 10 users has 45 possible connections; one with 100 users has 4,950. Each new user makes the whole network more valuable for everyone already there.

Examples:

  1. Telephones. One phone is useless. Every new phone increases the value of every existing phone.
  2. Social platforms. Why people stick with Facebook, LinkedIn, or WhatsApp long after they want to leave — their network is there.
  3. Developer ecosystems. A programming language with more libraries, more job postings, and more StackOverflow answers gets disproportionately more attractive than a slightly better language with fewer users.

Watch out for: Metcalfe’s Law is approximate, not exact. The real curve is somewhere between linear and quadratic depending on whether all connections are valuable. But the direction is always right: cross a critical mass and growth gets explosive.

Reed’s Law

Tags: networksgrowthbusiness

The Law: “The utility of large networks, particularly social networks, scales exponentially with the size of the network.”

In plain words: David Reed pointed out that Metcalfe (n²) underestimates network value when users can form groups. The number of possible subgroups grows as 2^n — explosively faster than n² — so platforms that enable group formation gain disproportionate value as they grow.

Examples:

  1. Slack channels. The value isn’t just one-to-one messaging; it’s that any subset of users can spin up a channel. Each new user multiplies group possibilities.
  2. Facebook groups, Discord servers, Reddit subreddits. What people stay for isn’t the platform itself but the niche communities only that platform’s scale could support.
  3. GitHub. Every repo is a “group.” The bigger GitHub gets, the more niches it can host — and each new niche makes the whole platform stickier.

Watch out for: Reed’s Law explains why it’s so hard to dethrone group-forming networks. If you’re building one, lean into group features early; the exponential value comes from people, not the platform.

Moore’s Law

Tags: hardwareperformanceforecasting

The Law: “The number of transistors on an integrated circuit doubles approximately every two years.”

In plain words: Gordon Moore’s 1965 observation became the heartbeat of the digital era — compute roughly doubled every couple of years for half a century. It’s not really a software law, but it shaped almost every assumption software engineers have made for decades.

Examples:

  1. The “wait two years” trick. Performance problems that were unaffordable in 2003 became background tasks by 2007 — without writing a single line of new code.
  2. The smartphone era. What was a supercomputer in 1995 lives in your pocket today. Software stacks that assumed today’s compute would have been laughable then.
  3. The slowing of Moore’s Law. Around the 2010s, single-core speeds plateaued. Free performance gains became less reliable, which is why parallelism, GPUs, and specialized chips matter so much now.

Watch out for: Don’t bet on Moore’s Law to bail out a slow system anymore. The free lunch is mostly over for sequential code. Pair this law with Wirth’s Law (next) for a sobering reality check.

Wirth’s Law

Tags: performanceculturehumor

The Law: “Software is getting slower more rapidly than hardware is becoming faster.”

In plain words: Niklaus Wirth’s wry observation: every time hardware gets a 2× speedup, software writers find a way to consume 3× more — through bigger frameworks, more abstraction layers, more features, more memory waste. The net experience for users barely improves.

Examples:

  1. The 2-second app. A simple text editor in 1990 launched instantly. A modern Electron-based one with vastly more compute available takes seconds to start.
  2. Web pages. A modern news article often weighs 5–10 MB and uses gigabytes of RAM, despite the actual content being a few kilobytes of text.
  3. Mobile apps. Newer phones, but apps still feel sluggish — because each release piles on more analytics, more frameworks, more features.

Watch out for: Treat performance as a feature with a budget. “Hardware will catch up” is a comfortable lie. Real users still wait — and they’ll switch to whatever feels faster.

Chapter 6 — Testing, Debugging & Bugs

“If debugging is the process of removing bugs, then programming must be the process of putting them in.”

Software has bugs. The five laws below describe the inevitability of bugs, the difficulty of finding them, and the strategies that have stood the test of time.

Murphy’s Law / Sod’s Law

Tags: testingreliabilityhumor

The Law: “Anything that can go wrong will go wrong.”

In plain words: If a failure is possible, given enough time and traffic, it will happen. Engineering is the practice of taking that seriously.

Examples:

  1. The “this will never happen” branch. Six months after the comment is written, that branch executes for the first time — in production, on Black Friday.
  2. Empty arrays and null users. “There will always be at least one item.” Until the day there isn’t, and a five-line crash trends on Twitter.
  3. Daylight saving time. The job that “always runs at 2 a.m.” runs twice — or not at all — twice a year.

Watch out for: Treat Murphy’s Law as a design principle, not a punchline. Defensive coding, idempotency, retries, and chaos testing are all about taking failure seriously before it happens.

Linus’s Law

Tags: testingbugsopen-source

The Law: “Given enough eyeballs, all bugs are shallow.”

In plain words: When many people read your code, even subtle bugs get spotted quickly. Open code is more likely to be correct over time.

Examples:

  1. Linux kernel. Tens of thousands of contributors review every change; bugs that survive the review process are rare and usually fixed quickly once observed.
  2. Pull-request culture. Even within a private company, requiring two reviewers catches a huge fraction of bugs before they ship.
  3. Bug bounty programs. External researchers paid to look for vulnerabilities consistently find ones internal teams missed.

Watch out for: “Many eyes” only works if those eyes are engaged. Drive-by reviews (“LGTM 🚀”) catch nothing. Reviews need attention, time, and disagreement.

Kernighan’s Law

Tags: testingdebuggingcraft

The Law: “Debugging is twice as hard as writing the code in the first place.”

In plain words: Writing clever code uses your full intelligence. Debugging it requires more than that — and you only have so much. So clever code you can’t debug is code you can’t maintain.

Examples:

  1. The one-line regex. A 90-character regex feels great to write. A year later, no one — including its author — can fix the bug it has.
  2. Metaprogramming. Code that writes code is powerful, but a stack trace inside it can take days to untangle.
  3. Heroic concurrency. A lock-free, multi-threaded data structure runs perfectly… until it doesn’t, and then nobody on the team can reason about why.

Watch out for: Always write code at less than your maximum cleverness. Save your top mental capacity for debugging.

Testing Pyramid

Tags: testingarchitecturepractices

The Law: “A project should have many fast unit tests, fewer integration tests, and only a small number of UI tests.”

In plain words: Most of your tests should be small, fast, and isolated. A smaller number should test that components work together. Only a few should drive the actual UI end-to-end.

Examples:

  1. A balanced suite. 800 unit tests in 30 seconds, 80 integration tests in 5 minutes, 10 UI tests in 15 minutes. Failures are almost always isolated to the lowest layer.
  2. An inverted pyramid (anti-pattern). A team relies on a giant suite of slow, flaky end-to-end tests. CI takes 90 minutes, fails randomly, and nobody trusts it.
  3. Pure unit tests miss reality. A team with only unit tests finds out at deploy time that two components were tested perfectly in isolation — and don’t talk to each other correctly.

Watch out for: The exact ratios are flexible. The principle isn’t: fast, narrow tests at the bottom; slow, broad tests on top — and never let the pyramid invert.

Pesticide Paradox

Tags: testingquality-assurancebugs

The Law: “Repeatedly running the same tests becomes less effective over time.”

In plain words: Bugs adapt. Tests that catch certain kinds of bugs become less useful once those bugs are gone — but new kinds of bugs slip through unchanged tests.

Examples:

  1. The plateau. A team has 100% test pass rates for months. Then a customer reports a bug — in a code path no test ever exercised.
  2. Stagnant test data. Tests with the same fake user always pass; the real bug only surfaces with internationalized names, accented characters, or 50,000-row datasets.
  3. Old security tests. Yesterday’s penetration tests don’t catch today’s exploit techniques.

Watch out for: Refresh your tests. Add new edge cases. Use property-based testing, fuzzing, and exploratory testing to find what your suite has stopped catching.

Chapter 7 — Software Evolution & Change

“Software is never finished, only abandoned.”

The five laws below describe the long arc of software in the world: how it has to keep changing to stay useful, how change ripples in unexpected ways, and why some technologies outlive their hype while others don’t.

Lehman’s Laws of Software Evolution

Tags: evolutionmaintenancearchitecture

The Law: “Software that reflects the real world must evolve, and that evolution has predictable limits.”

In plain words: Any program that is actually used will need to keep changing — because the world it models keeps changing. And as it grows, it gets harder to change without unintended consequences.

The original eight Lehman laws condensed:

  • Software in use must continue to change, or it becomes useless.
  • Complexity increases unless work is done to reduce it.
  • Evolution is a self-regulating process — there’s a natural rhythm.
  • Quality declines unless it’s actively maintained.

Examples:

  1. Tax software. Tax code changes every year, so every tax program ships annual updates. Stop, and the product dies.
  2. Browsers. The web standards keep shifting; a browser frozen at a version from five years ago can’t render half the modern web.
  3. The “stable” internal tool. A tool nobody touches gradually becomes incompatible with the OS, libraries, and services it depends on. “Stable” became “abandoned.”

Watch out for: Plan maintenance into your roadmap. Software that isn’t actively maintained is silently rotting — even if its source code never changes.

Sturgeon’s Law

Tags: qualityculturehumor

The Law: “90% of everything is crap.”

In plain words: Most of anything — books, code, movies, frameworks, conference talks — is mediocre at best. The rare 10% is what stands out and gets remembered.

Examples:

  1. Open source on GitHub. Tens of millions of repos exist; only a tiny fraction are well-maintained, useful, and documented.
  2. Stack Overflow answers. Some are gold. Most are decent. A long tail are wrong, outdated, or copy-pasted.
  3. Internal documentation. A few wiki pages save lives every week; most are stale or never read.

Watch out for: Don’t be discouraged by mediocrity around you — it’s normal. Do be discerning about what to depend on. And aim for the 10%, knowing it takes more work.

Law of Unintended Consequences

Tags: change-managementriskarchitecture

The Law: “Whenever you change a complex system, expect surprise.”

In plain words: Big systems are tangled. A change in one place can produce strange, unrelated-seeming effects somewhere else.

Examples:

  1. The harmless config change. Bumping a timeout from 3 s to 5 s causes thread-pool exhaustion under peak load — a totally unexpected bottleneck.
  2. The new feature toggle. Turning on a feature for “10% of users” doubles database load because the underlying query was unindexed for the new code path.
  3. A “small” UX tweak. Renaming a button drops conversion 20% because users who skim were trained to look for the old word.

Watch out for: Monitor before, during, and after every change. Roll out gradually. Have a rollback plan. Accept that every change to a complex system is, partly, an experiment.

The Hype Cycle & Amara’s Law

Tags: technologyforecastingculture

The Law: “We tend to overestimate the effect of a technology in the short run and underestimate the impact in the long run.”

In plain words: New technologies follow a roughly predictable curve: hype peak → disillusionment → quiet maturity → real impact. People pay attention only to the first two.

Examples:

  1. The internet, 1999. Sky-high expectations crashed in the dot-com bust — yet 25 years later, the internet has reshaped almost every industry on earth.
  2. Cryptocurrencies. The peak hype gave way to a crash and crypto winter; quiet, real infrastructure work continued underneath.
  3. AI. Multiple “AI winters” came and went. The current generation is reshaping software development; whether near-term hype is justified is debated, but the long-run impact is enormous.

Watch out for: Don’t bet your company on a peak-of-hype technology, and don’t dismiss something just because the hype died. Look at what’s quietly being adopted year after year.

The Lindy Effect

Tags: technologyforecastinglongevity

The Law: “The longer something has been in use, the more likely it is to continue being used.”

In plain words: Technologies that have already lasted a long time tend to last even longer. New things have not been tested against time yet.

Examples:

  1. Unix. Born in the early 1970s. Still everywhere — and likely will be in 2050.
  2. SQL. Five decades old. Beats almost every “next-gen” data tech in longevity, by a lot.
  3. Email and HTTP. Critics have predicted their death for 30 years. Both are still load-bearing for the entire economy.

Watch out for: Lindy isn’t a guarantee — it’s a base rate. When in doubt between a hot new framework and a 30-year-old tool, the boring choice often pays off. Use the new thing for the parts where it really wins; let Lindy hold up the rest.

Atwood’s Law

Tags: culturelanguage-designhumor

The Law: “Any application that can be written in JavaScript will eventually be written in JavaScript.”

In plain words: Coined by Jeff Atwood (co-founder of Stack Overflow) in 2007. It started as a half-joke; it’s aged into a near-prophecy. JavaScript has crept from the browser into servers (Node), desktop apps (Electron), mobile (React Native), embedded devices, and even databases.

Examples:

  1. VS Code. A full-featured IDE built with Electron — JavaScript and a browser engine in disguise.
  2. Slack, Discord, Spotify desktop apps. All Electron. All using JavaScript runtimes that the original ECMAScript spec authors never imagined.
  3. Server-side JavaScript. Node.js routinely powers high-traffic backends that two decades ago would have been Java, C++, or Python only.

Watch out for: Atwood’s Law isn’t an endorsement of JavaScript so much as a comment on ubiquity. The “lingua franca” effect is real — pick your tools partly based on the size of the available labor pool and the ecosystem.

Stroustrup’s Law

Tags: culturelanguage-designhumor

The Law: “There are only two kinds of languages: the ones people complain about and the ones nobody uses.”

In plain words: Bjarne Stroustrup, creator of C++, observed that any language used at scale is going to attract criticism. Popularity exposes flaws and gathers complaints; obscurity protects pristine designs but doesn’t get anything done.

Examples:

  1. JavaScript, Java, PHP, C++. All endlessly criticized. All run trillions of dollars of business.
  2. Beautiful niche languages. Languages with elegant designs but tiny communities are less complained about — but you also can’t hire for them.
  3. Internal frameworks. A framework only your team uses seems amazing — until two more teams adopt it and it sprouts the same edges every public framework has.

Watch out for: Don’t confuse “people complain about it” with “it’s bad.” Often the complaining is itself a sign of widespread, valuable adoption. Conversely, don’t romanticize an obscure language just because it has no detractors.

Wadler’s Law

Tags: culturelanguage-designhumor

The Law: “In any language design discussion, the time spent debating a feature is roughly proportional to 2^(its depth in the stack: pragmatics → semantics → syntax).”

In plain words: Philip Wadler observed (with tongue in cheek) that the most superficial issues — punctuation, brace style, identifier rules — get the most heated debate, while the deep, important questions of meaning and use get comparatively little attention.

Examples:

  1. Tabs vs. spaces. A holy war that has consumed thousands of engineering hours, while the actual semantics of the language often pass without comment.
  2. The naming committee. API naming arguments take three weeks; the actual API contract takes one afternoon.
  3. Rust’s question mark, Python’s walrus operator. Tiny syntactic additions trigger oceans of online discussion.

Watch out for: When a design discussion gets stuck on syntax, gently redirect it. Ask: “Have we settled the semantics yet?” If not, the syntax conversation is premature anyway.

Naur’s “Programming as Theory Building”

Tags: evolutionknowledge-managementphilosophy

The Law: “The real value of a program lies in the engineers’ shared theory of it, not in the source code.”

In plain words: Peter Naur (of BNF fame) argued in 1985 that the source code is just an artifact — the real knowledge is the mental model the team has built about why the code works the way it does. Lose the people, and you lose the system, even if the code remains.

Examples:

  1. The doomed handover. A team is laid off; their replacements inherit the codebase but not the theory. Within months, every change has unexpected side effects.
  2. The senior engineer who “just knows.” Their tacit knowledge (“don’t touch that batch job before noon, the trade engine isn’t ready”) is invisible in any document — and irreplaceable when they leave.
  3. Successful refactors. Real understanding lets a team safely cut deep into the code. Without it, every refactor is a coin flip.

Watch out for: Invest in people-level knowledge transfer: pair programming, design docs, walk-throughs, recorded sessions. Code is necessary but never sufficient. (Pair this with Bus Factor.)

Cargo Cult Programming

Tags: cultureanti-patternmental-model

The Law: “Imitating the form of working code without understanding its substance produces non-working — but earnest — code.”

In plain words: Named after WWII-era Pacific island rituals where people built fake airstrips hoping cargo planes would land. In software, it’s when you copy patterns, configs, or commands you saw work elsewhere — without understanding why they work — and are surprised when your version doesn’t.

Examples:

  1. Copy-pasted Stack Overflow. A snippet works in production for a year. Then someone changes a line and the whole thing breaks; nobody on the team knows what the original code actually did.
  2. Reproducing FAANG architecture at 50 users. Adopting Kubernetes, microservices, and event sourcing because “Netflix does it” — without the scale that justified those choices.
  3. The “magic” deploy script. Each project copies the deploy script from the last one, stripping or adding lines blindly. Eventually it contains four lines nobody understands.

Watch out for: Whenever you adopt something — a pattern, a config, a tool — make sure at least one person on the team can explain why. If nobody can, you’re flying a fake airplane.

Chapter 8 — Cognitive Biases & Mental Models

“The chief enemy of good decisions is the lack of sufficient perspectives on a problem.”

The last chapter is the most personal. Nine laws and mental models that shape how you think — about problems, evidence, and your own confidence. They apply far beyond code, but they’re indispensable in any technical career.

Dunning-Kruger Effect

Tags: cognitive-biaslearningself-awareness

The Law: “The less you know about something, the more confident you tend to be.”

In plain words: Beginners often dramatically overestimate their skill, because they lack the knowledge to see how much they don’t know. Real experts, paradoxically, are often less confident — they can see the edges of their knowledge.

Examples:

  1. The week-one Kubernetes evangelist. Someone who has just discovered K8s declares it the answer to all infrastructure problems. The veterans have seen the dragons.
  2. The first-year coder rewriting “legacy.” Convinced they can rebuild the entire system in a weekend. Two months later, they discover why each weird detail exists.
  3. The senior engineer asking “dumb” questions. They’ve earned the humility to ask, because they’ve been bitten by hidden complexity before.

Watch out for: When you feel certain, ask: “What evidence would change my mind?” The harder it is to answer, the more likely you’re in Dunning-Kruger territory.

Hanlon’s Razor

Tags: cognitive-biasmental-modelculture

The Law: “Never attribute to malice that which is adequately explained by stupidity or carelessness.”

In plain words: When something annoying happens — a bad email, a broken deploy, a missed handoff — assume oversight, not evil intent. Most of the time, you’ll be right.

Examples:

  1. The angry-sounding email. A short reply feels rude. Usually the sender was just tired or in a meeting, not attacking you.
  2. The breaking change. A teammate didn’t bump the version number. They forgot. They didn’t sabotage you.
  3. A vendor’s bad API. It’s almost certainly under-resourced or under-tested, not part of a conspiracy against your team.

Watch out for: Hanlon’s Razor is a first assumption, not a final one. Patterns of “carelessness” that conveniently benefit one party can be malice in disguise. Start kind; verify.

Occam’s Razor

Tags: cognitive-biasmental-modeldebugging

The Law: “The simplest explanation is often the most accurate one.”

In plain words: When a problem has many possible causes, start with the simplest, most likely one before reaching for exotic theories.

Examples:

  1. “It’s not the network.” It usually is the network. Or DNS. Check the simple stuff first.
  2. “There’s a cosmic-ray bit flip!” No, you wrote = instead of ==. Look at your diff.
  3. “Customer environment is corrupted.” Usually not. Usually their input file has a Windows line ending you didn’t account for.

Watch out for: Occam’s Razor is a guide, not a guarantee. Sometimes the rare cause is the right one. The trick is checking simple causes first so you don’t waste days on elaborate theories.

Sunk Cost Fallacy

Tags: cognitive-biasdecision-makingproject-management

The Law: “Sticking with a choice because you’ve invested time or energy in it, even when walking away helps you.”

In plain words: Past investment shouldn’t matter for future decisions. The money/time you already spent is gone whether you continue or not.

Examples:

  1. The doomed rewrite. Eighteen months in, the team knows the rewrite won’t work. But “we’ve invested too much to stop now” — and they spend another year confirming it.
  2. The bad library choice. A library you adopted last quarter is hurting you, but switching feels like admitting failure. The right move is to switch anyway.
  3. The struggling employee. Months of coaching haven’t worked. Continuing because “we’ve already invested in them” hurts both the team and the person.

Watch out for: Ask: “If I were starting fresh today, knowing what I know now, would I make this choice?” If the answer is no, the past is irrelevant.

The Map Is Not the Territory

Tags: mental-modelarchitecturemodeling

The Law: “Our representations of reality are not the same as reality itself.”

In plain words: Diagrams, models, mental abstractions — these are useful, but they are not the system itself. Reality always has more detail than the map.

Examples:

  1. The architecture diagram. A clean, boxes-and-arrows diagram hides the messy, undocumented call paths actually running in production.
  2. The “happy path.” A test plan focuses on the intended user journey, but real users do unintended things — and that’s where the bugs live.
  3. The personas vs. real customers. Carefully crafted personas can blind a team to the actual variety of people using the product.

Watch out for: Update your maps regularly. When the map and the territory disagree, the territory wins.

Confirmation Bias

Tags: cognitive-biasdecision-makingevidence

The Law: “A tendency to favor information that supports our existing beliefs or ideas.”

In plain words: Once you have a theory, you unconsciously look for evidence that supports it and dismiss evidence that doesn’t.

Examples:

  1. The wrong root cause. You’re sure it’s a cache problem. You look at logs that confirm it. Hours later, you realize the cache was fine — it was a bad config.
  2. The favorite framework. You believe Framework X is best. You read articles praising it; criticisms feel “biased.” You don’t notice you’re doing the exact thing you’re accusing critics of.
  3. The post-hire honeymoon. You hired this person; now everything they do looks great — until reality forces you to see the gaps.

Watch out for: Try the opposite test: “If my theory were wrong, what would I see?” Look for that explicitly. It’s uncomfortable on purpose.

First Principles Thinking

Tags: mental-modelproblem-solvingdesign

The Law: “Breaking a complex problem into its most basic blocks and then building up from there.”

In plain words: Instead of reasoning by analogy (“we did it this way last time”), break the problem down to what must be true, then rebuild a solution from those facts.

Examples:

  1. Rocket costs. SpaceX famously asked: “What is the actual material cost of a rocket?” Far less than the price tag, leading to reusable rockets.
  2. Database choice. Instead of “we always use Postgres,” ask: “What guarantees does this workload need? What read/write patterns does it have?” Sometimes the answer is still Postgres — but now for the right reasons.
  3. API design. Rather than copying yesterday’s REST conventions, ask: “Who calls this? What do they actually need? In what failure modes?”

Watch out for: First-principles thinking is expensive. Use it for the important decisions; for the small ones, copying a sensible pattern is usually fine.

Inversion

Tags: mental-modelproblem-solvingdesign

The Law: “Solving a problem by considering the opposite outcome and working backward from it.”

In plain words: Instead of asking “How do I succeed?”, ask “How would I fail?” Then avoid those things. Sometimes it’s much easier than figuring out success directly.

Examples:

  1. Designing a great API. Ask: “What would make this API miserable to use?” Avoid those things, and you’ve probably built a good one.
  2. Reliability planning. Ask: “What are all the ways this service could go down?” Each answer becomes an alert, a test, or a defensive control.
  3. Hiring. “What would make this hire a disaster?” sometimes surfaces clearer red flags than “what would make this hire amazing?”

Watch out for: Inversion isn’t about pessimism. It’s about completeness. Use it alongside positive vision, not as a replacement for it.

Cunningham’s Law

Tags: culturecommunityhumor

The Law: “The best way to get the correct answer on the Internet is not to ask a question, it’s to post the wrong answer.”

In plain words: People are far more motivated to correct a confident mistake than to answer a polite question.

Examples:

  1. Stack Overflow. A bold but slightly wrong answer often draws a flood of corrections, edits, and superior alternatives within hours.
  2. Internal slack. Saying “I’m pretty sure the bug is in module X” often produces five teammates explaining it’s actually in module Y, complete with line numbers.
  3. Documentation review. Drafting wrong-on-purpose docs and asking “is this right?” gets faster, sharper feedback than asking “can someone please write this?”

Watch out for: Use this power for good. Don’t post genuinely misleading content into the public internet just to fish for replies — but in collaborative settings, being willing to be wrong out loud is one of the most powerful learning techniques there is.

Curse of Knowledge

Tags: cognitive-biascommunicationdocumentation

The Law: “Once you know something, it becomes nearly impossible to imagine not knowing it.”

In plain words: Experts forget what it was like to be a beginner. That’s why most documentation, onboarding guides, and APIs are confusing — the writers can’t see the gaps anymore.

Examples:

  1. The “obvious” README. “Just clone the repo and run make” — leaving out the fact that you need three environment variables, two services running locally, and a very specific compiler version.
  2. The architecture diagram from hell. Perfectly clear to the team that drew it; opaque to anyone newer than 6 months.
  3. The expert teacher problem. A senior engineer explains a concept by jumping straight into the advanced case, leaving the junior engineer convinced they’ll never understand.

Watch out for: Write docs with a real beginner. Pair-onboard new hires and let them edit the guide as they go. Whatever they got stuck on is your blind spot.

Survivorship Bias

Tags: cognitive-biasdecision-makingevidence

The Law: “Drawing conclusions from only the cases that survived, while ignoring those that didn’t.”

In plain words: When you study only the success stories, you miss the lessons of all the projects, companies, and patterns that failed using the same approach. The trail of dead is invisible — and just as informative as the survivors.

Examples:

  1. “Netflix uses microservices.” Yes — and so did dozens of startups that died trying to. Copying the surviving giant is a classic survivorship-bias trap.
  2. “Successful founders dropped out of college.” A handful did. Far more dropouts vanished without a trace. Looking only at the famous handful gives you a wildly skewed picture.
  3. “This pattern works at scale.” Sure, in the codebase you can see. The dead codebases that crashed and burned using the same pattern aren’t on the conference stage.

Watch out for: Always ask: “Where are the failures?” Look for post-mortems and case studies of things that didn’t work. Their lessons are usually more useful than the highlight reel.

Planning Fallacy

Tags: cognitive-biasestimationproject-management

The Law: “People systematically underestimate the time, cost, and risk of future tasks, even when they know past tasks went over.”

In plain words: A close cousin of Hofstadter’s Law, identified by Kahneman and Tversky. We picture the best-case path through a project, not the average — let alone the worst — and we estimate based on that picture.

Examples:

  1. The “I’ll be done by Friday” estimate. Even after missing every “by Friday” estimate this year, the engineer’s gut still says “by Friday.”
  2. Mega-projects. Famously, large infrastructure projects (subways, airports, ERP rollouts) overrun budgets by an average of about 30–80%. Software is no exception.
  3. Side projects. Almost every developer has a half-finished side project that was supposed to be “a weekend’s work.”

Watch out for: Use reference-class forecasting: instead of estimating from a clean mental picture, look at how long similar projects actually took, and use that as your baseline. Add Hofstadter’s buffer for good measure.

Chapter 9 — UX & Human Factors

“The user is not a logical being. The user is a tired human who would rather be doing almost anything else.”

Software ultimately exists to be used by humans. The five laws below come mostly from psychology and HCI research, but every backend engineer benefits from knowing them too — your APIs, error messages, logs, and developer tools all have humans on the other end.

Miller’s Law (The Magical Number 7 ± 2)

Tags: uxcognitive-loaddesign

The Law: “The number of objects an average person can hold in working memory is about seven, plus or minus two.”

In plain words: George Miller’s 1956 paper observed that working memory is sharply limited. Cram more than ~7 items into a menu, a navigation bar, or a single screen, and people start to make mistakes — or just give up.

Examples:

  1. Phone numbers. 7 digits (in many countries) by no accident — it’s right at the edge of what people can hold.
  2. Navigation menus. Sites with 4–7 top-level menu items feel clean. Sites with 15 feel like an explosion.
  3. API parameters. A function with 12 positional arguments is a usability disaster. Group related arguments into objects, or you’ll permanently overload the caller.

Watch out for: Miller’s number is an approximation, not a hard rule — and modern research suggests the limit is actually closer to 4 chunks for active manipulation. Either way, the moral holds: keep choices, options, and screens fewer than your gut wants.

Fitts’s Law

Tags: uxdesigninteraction

The Law: “The time to acquire a target is a function of the distance to and size of the target.”

In plain words: Big things that are close are easy to click. Small things that are far away are hard. This sounds obvious — and yet UIs ignore it constantly.

Examples:

  1. Mac menu bar. It sits at the very top edge of the screen, which is effectively infinite-sized (you can’t overshoot it). Macs feel snappier partly because of this.
  2. The tiny “X” in the corner. Closing a dialog with an 8×8 px button in a corner is genuinely harder than closing it with a big “Done” in the middle.
  3. Mobile thumb zones. Buttons in the bottom third of a phone screen are easier to hit one-handed than buttons in the top corners.

Watch out for: Make the target proportional to its importance and frequency. Critical actions deserve big, central, easy-to-hit areas; destructive actions (“Delete forever”) deserve to be slightly harder to hit.

Hick’s Law

Tags: uxcognitive-loaddesign

The Law: “The time it takes to make a decision increases logarithmically with the number of options.”

In plain words: More choices = slower decisions. Twelve menu items is more than twice as slow as six. Beyond a point, users freeze entirely.

Examples:

  1. The infinite settings panel. A “preferences” screen with 80 toggles helps no one. Most users never visit it; the few who do can’t find what they want.
  2. Streaming services. “Browse paralysis” — the more titles on the home page, the less likely you are to watch one. Smart platforms use curation and recommendations to fight Hick’s Law.
  3. Form design. A 25-field form has lower completion rates than the same data spread across a multi-step wizard, because each step looks like a manageable decision.

Watch out for: Reduce, group, default. The best products either ask fewer questions, group related questions sensibly, or pick smart defaults so you don’t have to decide at all.

Jakob’s Law

Tags: uxdesignconvention

The Law: “Users spend most of their time on other sites, and they prefer your site to work the same way.”

In plain words: Coined by usability researcher Jakob Nielsen. People form mental models from the aggregate of all the apps and websites they use. Your product is competing with that learned vocabulary, not standing alone.

Examples:

  1. Hamburger menus, search icons, cart icons. Users have learned what these mean. Replacing them with novel icons creates friction without reward.
  2. Login flows. “Email + password,” “Sign in with Google,” “Forgot password?” — wherever you stray from this pattern, you’re paying a usability tax.
  3. Keyboard shortcuts. Cmd/Ctrl + C/V/Z. Don’t reinvent them; users will hit them whether your app accepts them or not.

Watch out for: Innovate where it differentiates you. Conform where users have already learned a pattern. Save your “different” budget for parts of the product that genuinely benefit from being unique.

Doherty Threshold

Tags: uxperformanceproductivity

The Law: “Productivity soars when a computer and its users interact at a pace that ensures neither has to wait — typically a response time below ~400 ms.”

In plain words: When response time drops below roughly 400 ms, something magical happens: users stop “waiting” for the computer and just keep going. They get into flow. Cross the threshold and per-task time can roughly halve.

Examples:

  1. Snappy autocomplete. Type-ahead that responds in 50 ms feels invisible. Type-ahead at 800 ms feels broken.
  2. Hot reload. Save a file, see the change in your app instantly. Compare to the bad old days of restarting the server every time — productivity isn’t 2× higher, it’s transformed.
  3. Loading spinners. A spinner for 1.5 seconds reminds users they’re waiting. The same operation, finished in 300 ms with no spinner at all, feels effortless.

Watch out for: Performance is a UX feature, not a backend tweak. Below 400 ms is the goal for any interactive operation. Above that, consider optimistic UI updates — show the result immediately, then reconcile with the server in the background.

Appendix A — Index of Laws by Tag

A quick way to find related ideas. Many laws appear under more than one tag.

architecture — Conway’s Law, Premature Optimization, Hyrum’s Law, Gall’s Law, Leaky Abstractions, Tesler’s Law, Second-System Effect, Zawinski’s Law, Postel’s Law, End-to-End Principle, Principle of Least Privilege, GIGO, CAP Theorem, Fallacies of Distributed Computing, Lehman’s Laws, Unintended Consequences, Map Is Not the Territory, Wheeler’s Law

teams / organization — Conway’s Law, Brooks’s Law, Dunbar’s Number, Ringelmann Effect, Price’s Law, Putt’s Law, Peter Principle, Bus Factor, Dilbert Principle, Joy’s Law

code-quality / craft — Boy Scout Rule, YAGNI, Broken Windows, Technical Debt, DRY, KISS, SOLID, Law of Demeter, Principle of Least Astonishment, Chesterton’s Fence, Rule of Three, Wheeler’s Law, Greenspun’s Tenth Rule, Separation of Concerns, Composition over Inheritance, Convention over Configuration, Fail Fast, Worse Is Better, Kernighan’s Law, Eagleson’s Law

design / simplicity — YAGNI, KISS, SOLID, Law of Demeter, Principle of Least Astonishment, Premature Optimization, Gall’s Law, Leaky Abstractions, Tesler’s Law, First Principles Thinking, Inversion, Worse Is Better, Convention over Configuration, Composition over Inheritance, Separation of Concerns

testing / debugging / bugs — Murphy’s Law, Linus’s Law, Kernighan’s Law, Testing Pyramid, Pesticide Paradox, Occam’s Razor, Fail Fast, GIGO

distributed-systems / performance — CAP Theorem, Fallacies of Distributed Computing, Amdahl’s Law, Gustafson’s Law, Metcalfe’s Law, Reed’s Law, Moore’s Law, Wirth’s Law, End-to-End Principle, Doherty Threshold

productivity / project-management — Brooks’s Law, Parkinson’s Law, Parkinson’s Law of Triviality, Ninety-Ninety Rule, Hofstadter’s Law, Pareto Principle, Sunk Cost Fallacy, Eagleson’s Law, Stein’s Law, Planning Fallacy

metrics / measurement — Goodhart’s Law, Gilb’s Law, Pareto Principle

evolution / maintenance — Boy Scout Rule, Broken Windows, Technical Debt, Lehman’s Laws, Sturgeon’s Law, Lindy Effect, Hype Cycle / Amara’s Law, Unintended Consequences, Stein’s Law, Naur’s Theory Building, Atwood’s Law

cognitive-bias / mental-model — Dunning-Kruger, Hanlon’s Razor, Occam’s Razor, Sunk Cost Fallacy, Map Is Not the Territory, Confirmation Bias, First Principles Thinking, Inversion, Curse of Knowledge, Survivorship Bias, Planning Fallacy, Cargo Cult Programming, Stein’s Law, Chesterton’s Fence

apis / compatibility — Hyrum’s Law, Postel’s Law, Principle of Least Astonishment, End-to-End Principle

networks / scaling — Metcalfe’s Law, Reed’s Law, Dunbar’s Number, Lindy Effect, Hype Cycle, Moore’s Law

security — Principle of Least Privilege, GIGO, Fail Fast

ux / human-factors — Miller’s Law, Fitts’s Law, Hick’s Law, Jakob’s Law, Doherty Threshold, Curse of Knowledge, Tesler’s Law, Principle of Least Astonishment

language-design — Greenspun’s Tenth Rule, Atwood’s Law, Stroustrup’s Law, Wadler’s Law

culture / humor — Putt’s Law, Dilbert Principle, Sturgeon’s Law, Cunningham’s Law, Zawinski’s Law, Murphy’s Law, Hanlon’s Razor, Atwood’s Law, Stroustrup’s Law, Wadler’s Law, Greenspun’s Tenth Rule, Cargo Cult Programming, Eagleson’s Law, Worse Is Better

Appendix B — One-Page Cheat Sheet

A condensed list you can keep on a sticky note next to your monitor.

#LawOne-line takeaway
1Conway’s LawYour software will look like your org chart.
2Brooks’s LawAdding people to a late project makes it later.
3Dunbar’s NumberBeyond ~150 people, structure beats trust.
4Ringelmann EffectBigger teams loaf. Assign work to a person.
5Price’s LawA few people do most of the work.
6Putt’s LawTech know-how and management rarely live together.
7Peter PrinciplePeople rise to their level of incompetence.
8Bus FactorIf one person leaving kills the project, fix that.
9Dilbert PrincipleSometimes “promotion” means “out of the way.”
10Joy’s LawThe smartest people work for someone else — stay humble.
11Parkinson’s LawWork expands to the time you give it.
12BikesheddingTrivial decisions soak up the most debate.
1390-90 RuleThe last 10% takes another 90% of the time.
14Hofstadter’s LawAlways longer than you think — even with buffers.
15Goodhart’s LawA metric used as a target stops being useful.
16Gilb’s LawSome measurement beats no measurement.
17Pareto / 80-20A small slice causes most of the effect.
18Eagleson’s LawYour six-month-old code was written by a stranger.
19Stein’s LawIf it can’t continue, it won’t.
20Boy Scout RuleLeave code cleaner than you found it.
21YAGNIDon’t build what you don’t need now.
22Broken WindowsDon’t tolerate visible decay.
23Technical DebtTrack shortcuts, repay them on purpose.
24DRYEach fact should live in one place.
25KISSSimple beats clever.
26SOLIDFive rules for object-oriented sanity.
27Law of DemeterTalk to friends, not strangers.
28Least AstonishmentDon’t surprise the next reader.
29Chesterton’s FenceUnderstand a thing before you remove it.
30Rule of ThreeRefactor on the third repetition, not the first.
31Wheeler’s LawIndirection solves everything except too much indirection.
32Greenspun’s TenthBig systems re-invent Lisp, badly.
33Separation of ConcernsOne module, one responsibility.
34Composition over InheritanceBuild with parts, not deep family trees.
35Convention over ConfigurationSmart defaults, opt-in overrides.
36Fail FastCrash loudly instead of corrupting silently.
37Worse Is BetterShippable beats elegant.
38Premature OptimizationProfile first. Optimize the hot 3%.
39Hyrum’s LawEvery observable behavior gets depended on.
40Gall’s LawBig working systems grew from small ones.
41Leaky AbstractionsAbstractions break — learn the layer below.
42Tesler’s LawComplexity moves; it doesn’t disappear.
43Second-System Effectv2 over-engineers. Resist the temptation.
44Zawinski’s LawEvery program drifts toward “and email.”
45Postel’s LawStrict in output, lenient in input.
46End-to-End PrincipleSmarts at the endpoints, not in the middle.
47Least PrivilegeGive just enough access — and no more.
48GIGOGarbage in, garbage out.
49CAP TheoremPick consistency or availability under partition.
50Fallacies of Distributed ComputingThe network is not your friend.
51Amdahl’s LawSerial work caps your parallel speedup.
52Gustafson’s LawBigger problems benefit from more cores.
53Metcalfe’s LawNetwork value grows ~ n².
54Reed’s LawGroup-forming networks grow ~ 2ⁿ.
55Moore’s LawCompute roughly doubles every two years (slowing).
56Wirth’s LawSoftware gets slower faster than hardware speeds up.
57Murphy’s LawIf it can break, plan for the day it does.
58Linus’s LawMany serious eyes find bugs fast.
59Kernighan’s LawDon’t write code so clever you can’t debug it.
60Testing PyramidMany fast tests, few slow ones.
61Pesticide ParadoxRefresh your tests; bugs adapt.
62Lehman’s LawsUsed software must change, or die.
63Sturgeon’s Law90% of everything is mediocre.
64Unintended ConsequencesEvery change to a complex system is an experiment.
65Hype / Amara’s LawOverestimated short-term, underestimated long-term.
66Lindy EffectThe old has earned the right to last.
67Atwood’s LawWhatever can be JavaScript, eventually is.
68Stroustrup’s LawPopular = complained about.
69Wadler’s LawSyntax debates dominate semantics debates.
70Naur’s Theory BuildingReal value lives in shared understanding, not code.
71Cargo Cult ProgrammingDon’t copy patterns you can’t explain.
72Dunning-KrugerBeginners feel sure; experts feel humble.
73Hanlon’s RazorAssume oversight, not malice.
74Occam’s RazorCheck the simple cause first.
75Sunk Cost FallacyWhat you spent doesn’t decide what to do next.
76Map ≠ TerritoryThe model is not the system.
77Confirmation BiasLook for evidence that you’re wrong.
78First PrinciplesReason from facts, not analogies.
79InversionPlan how to fail; then avoid it.
80Cunningham’s LawA wrong answer summons the right one.
81Curse of KnowledgeExperts forget what beginners don’t know.
82Survivorship BiasThe dead don’t appear in the data.
83Planning FallacyWe chronically underestimate. Use real history.
84Miller’s Law (7±2)Working memory is small. So is your menu.
85Fitts’s LawBig, close targets are easy; small, far ones aren’t.
86Hick’s LawMore choices = slower decisions.
87Jakob’s LawConform to the patterns users already know.
88Doherty ThresholdUnder 400 ms, productivity transforms.

Closing Thought

These laws aren’t a checklist; they’re a vocabulary. The next time a project feels stuck, scan the chapters and ask: which law am I living through right now? Naming it is half the cure.

“In theory, theory and practice are the same. In practice, they are not.”

Build well, ship often, and stay curious.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>