{"author":"Dr. Milan Milanović","count":56,"description":"A collection of principles and patterns that shape software systems, teams, and decisions.","generated":"2026-07-11T12:44:02Z","laws":[{"description":"Organizations design systems that mirror their own communication structure.","examples":"A company had separate departments for frontend, backend, and database. The software they built had a three-tier architecture, with each tier independently designed by its respective department. Integration between tiers was painful because the teams had misaligned goals.\n\nAmazon famously organized \"two-pizza teams\", each owning a specific service. Conway's Law suggests that's why Amazon's architecture is service-oriented, with clear API contracts between services.\n","experience":"senior","further_reading":[{"description":"Melvin Conway's original 1968 paper","title":"How Do Committees Invent?","url":"https://www.melconway.com/Home/Committees_Paper.html"},{"description":"Martin Fowler's explanation of Conway's Law","title":"Conway's Law","url":"https://martinfowler.com/bliki/ConwaysLaw.html"},{"description":"The original Spotify Model blog post","title":"Spotify Engineering Culture","url":"https://engineering.atspotify.com/2014/3/spotify-engineering-culture-part-1"},{"description":"Modern application of Conway's Law to organizational design","title":"Team Topologies","url":"https://amzn.to/4jgRZ6V"}],"group":"Teams","image":"/images/laws/conways-law.png","origins":"**Melvin Conway** introduced the idea in his 1967 paper \"How Do Committees Invent?\" After Harvard Business Review rejected it for lacking formal proof, Datamation published it in 1968.\n\nFred Brooks later named it \"Conway's Law\" in *The Mythical Man-Month*, which established the concept as foundational in software engineering.\n","overview":"Conway's Law states that **software systems reflect the communication structure of the organization that builds them**. A company with separate frontend, backend, and database departments will likely produce a three-tier architecture. Small, distributed teams tend to produce modular service architectures, while large, collocated teams tend to build monoliths.\n\nTo mitigate this, teams can use the **Inverse Conway Maneuver**: intentionally structuring the organization to match the desired software architecture.\n","related":["brooks-law","galls-law","law-of-leaky-abstractions","hyrums-law"],"slug":"conways-law","takeaways":["The architecture of software systems often mirrors the organization's org chart or team structure.","If your company is organized in silos, you might end up with siloed software modules that don't communicate well, reflecting those barriers.","To achieve a desired software architecture (e.g., microservices), you might need to restructure teams accordingly, because teams build software aligned with their communication paths.","When starting a project, realize that how you split teams or departments will likely lead to software boundaries at the same places."],"title":"Conway's Law","url":"https://lawsofsoftwareengineering.com/laws/conways-law/"},{"description":"Premature optimization is the root of all evil.","examples":"A developer writes a low-level C routine with complex bit-twiddling to squeeze out speed, spending two days on it, only to find that the function is called once at startup, taking 0.001% of runtime. The effort was wasted, and the code is now more complex to understand. Meanwhile, another part of the program (such as a sorting function on a large dataset) was the real bottleneck, but remained unoptimized because time was spent on the wrong thing.\n\nAnother example is prematurely choosing a complex data structure for theoretical efficiency (say, a custom tree for log(N) lookups) when the simpler approach (like a linear search) would have been acceptable for the data sizes involved. \n\nIn contrast, following Knuth's advice, you implement simply, measure, then find that 80% of time is spent in one loop, you optimize that loop or use a better algorithm there. This gives real improvements with minimal added complexity elsewhere.\n","experience":"junior","further_reading":[{"description":"Donald Knuth's original 1974 paper in Computing Surveys","title":"Structured Programming with go to Statements","url":"https://pic.plover.com/knuth-GOTO.pdf"},{"description":"Steve McConnell's comprehensive guide to software construction","title":"Code Complete","url":"https://amzn.to/4b6YVBx"},{"description":"Overview of optimization techniques and when to apply them","title":"Program Optimization - Wikipedia","url":"https://en.wikipedia.org/wiki/Program_optimization"}],"group":"Planning","image":"/images/laws/premature-optimization.png","origins":"Donald Knuth, a legendary computer scientist, made this statement in his 1974 paper \"Structured Programming with Go To Statements\" published in ACM Computing Surveys.\n\nThe full quote provides important context: \"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.\"\n\nHe didn't literally mean all evil, but the quote caught on because it resonates with developers who have seen codebases twisted by needless optimizations. \n\nOver time, this quote became almost a proverb in software engineering. It's taught to juniors: first make it work, then make it right, then (if needed) make it fast.\n","overview":"Knuth's Optimization Principle captures a fundamental trade-off in software engineering: performance improvements often increase complexity. Applying that trade-off before understanding where performance actually matters leads to unreadable systems.\n\nEarly in development, your focus should be on a clear design. If you optimize too soon, you might introduce bugs or inflexibility, all to speed up parts of the code that may not even be bottlenecks. It's often cited that 20% of the code may consume 80% of the execution time (a Pareto-like notion). Optimizing anything outside that critical 20% is wasted effort and adds risk. The principle advises writing simple code, then profiling and improving only the parts that truly need it.\n","related":["yagni","hofstadters-law","galls-law","kernighans-law","amdahls-law"],"slug":"premature-optimization","takeaways":["Most code doesn't run in performance-critical hotspots, so obsessing over micro-optimizations everywhere wastes time and makes code harder to read and maintain.","According to Knuth, we should forget about small efficiencies about 97% of the time, and focus on clean design and correct functionality.","Optimized code is often more complex or less readable. If done prematurely, you incur this cost even when it's unnecessary.","Get it working correctly first, then make it fast, then make it pretty."],"title":"Premature Optimization (Knuth's Optimization Principle)","url":"https://lawsofsoftwareengineering.com/laws/premature-optimization/"},{"description":"With a sufficient number of API users, all observable behaviors of your system will be depended on by somebody.","examples":"**Microsoft Windows** had undocumented behaviors and bugs that many third-party applications relied on. When Microsoft fixed or changed those behaviors in new versions, those applications broke. Microsoft often had to revert or maintain quirky behavior to ensure compatibility.\n\nA **library** might state in the docs that a function returns an unordered list, but it currently returns a sorted list. Some users start depending on it being sorted. If the library later changes to truly unordered, those users' code will break. The law is especially relevant in API versioning: even minor changes can be breaking changes from someone's perspective.\n","experience":"senior","further_reading":[{"description":"The official explanation of Hyrum's Law","title":"Hyrum's Law Official Site","url":"https://www.hyrumslaw.com/"},{"description":"Discusses Hyrum's Law in the context of large-scale systems","title":"Software Engineering at Google","url":"https://abseil.io/resources/swe-book/html/ch01.html#hyrumapostrophes_law"},{"description":"Comic illustrating the problem","title":"Hyrum's Law on xkcd","url":"https://xkcd.com/1172/"}],"group":"Architecture","image":"/images/laws/hyrums-law.png","origins":"The law is named after **Hyrum Wright**, a software engineer who articulated this observation while at Google around 2011-2012. Hyrum noticed that even changes to core Google libraries that should have been invisible would often break some project somewhere, because that project relied on an undocumented behavior.\n\nHis colleague, Titus Winters, coined the term \"Hyrum's Law\" in recognition of it (in Software Engineering at Google).\n","overview":"Hyrum's Law describes a phenomenon where the boundary between a software's documented interface and its implementation details gets blurred in practice. No matter what you promise in an API contract, if people use your system enough, they will depend on behaviors you never officially supported.\n\nOver time, the implementation becomes the interface. Every observable trait, performance characteristic, or error code might be assumed by someone. This drastically limits freedom to change the system, as even internal changes can break users who wrote code around the old behavior.\n","related":["law-of-leaky-abstractions"],"slug":"hyrums-law","takeaways":["As the user count grows, everything your system does becomes a dependency point. Even unintended side effects or bugs can become 'features' that someone's workflow depends on.","Hyrum's Law warns maintainers that any change can break something for someone. Consumers may have integrated your API in ways you didn't expect, including relying on timing, error messages, formatting, etc.","The actual contract of your software isn't just the official API/spec; it's the exact behavior as observed in the wild. The contract can even be something informal, such as the UI that your users are used to."],"title":"Hyrum's Law","url":"https://lawsofsoftwareengineering.com/laws/hyrums-law/"},{"description":"Leave the code better than you found it.","examples":"You're working on an old module to add a new feature. The code works, but you notice a couple of things: there's a function `processData()` that has more than 200 lines, and there are some `//TODO` comments and commented-out code blocks. Following the rule, you split `processData()` into smaller, better-named functions to improve readability and delete those commented-out sections that are no longer needed.\n\nOn a larger scale, Google's engineers often say \"If you touch it, you own it\". This means that when you modify code, you take ownership of its quality, leading to fixing even minor issues as they arise during unrelated tasks. Over the lifespan of a product, thousands of such small clean-ups occur, preventing major problems.\n","experience":"junior","further_reading":[{"description":"Robert C. Martin's influential book on writing clean code","title":"Clean Code: A Handbook of Agile Software Craftsmanship","url":"https://amzn.to/3LjRFYI"},{"description":"Uncle Bob's essay in 97 Things Every Programmer Should Know","title":"The Boy Scout Rule","url":"https://www.oreilly.com/library/view/97-things-every/9780596809515/ch08.html"},{"description":"Martin Fowler's guide to incremental code improvement","title":"Refactoring: Improving the Design of Existing Code","url":"https://martinfowler.com/books/refactoring.html"},{"description":"Steve McConnell's comprehensive guide to software construction","title":"Code Complete","url":"https://amzn.to/3N57T8t"}],"group":"Quality","image":"/images/laws/boy-scout-rule.png","origins":"The mantra \"leave the campsite cleaner than you found it\" comes from the Boy Scouts of America and Scouting organizations worldwide. \n\nIn the domain of software development, the Boy Scout Rule was popularized by Robert C. Martin (Uncle Bob) in his book \"Clean Code: A Handbook of Agile Software Craftsmanship\" (2008).\n\nUncle Bob adapted this simple wisdom to software development, recognizing that large refactoring projects rarely happen but continuous small improvements can transform a codebase over time.\n","overview":"The Boy Scout Rule basically means: leave the code better than you found it. In practice, it's not about doing big-bang rewrites or achieving perfection in one go. Instead, it's about constant and incremental improvements.\n\nWhenever a developer encounters a piece of code, whether adding a new feature or hunting down a bug, they take the opportunity to polish something nearby. For example, if there's a confusing function name, you rename it clearly. If you notice some duplicated code, you refactor it into a single helper. If a test case is missing for a critical method, you add it. \n\nThese are often small changes that might take only a few extra minutes, but they compound over time.\n","related":["broken-windows-theory","yagni","technical-debt"],"slug":"boy-scout-rule","takeaways":["Don’t leave bad things rot in a project. This means take a moment to refactor or fix at least one small thing in the area you’re working on. It can include anything from variable names to simplifying logic.","A cleaner codebase is easier to read, work with, and extend. This improves project maintainability and reduces technical debt.","When every developer follows this rule, it creates a culture of ownership in the code. Teams collectively feel responsible for code quality."],"title":"The Boy Scout Rule","url":"https://lawsofsoftwareengineering.com/laws/boy-scout-rule/"},{"description":"Don't add functionality until it is necessary.","examples":"You're building a feature with specific behavior. You think \"maybe in the future someone will want to toggle this on/off, so I'll add a configuration flag now.\" YAGNI challenges that. Unless there's a current requirement for configurability, implement only expected behavior, nothing more.\n\nYou're working on a library function that currently does one thing. You realize it might be useful more generally, so you might add parameters or abstraction tiers. YAGNI says implement it for the original task.\n\nYour app needs JSON export? Implement simple JSON, not a full serialization library supporting XML, YAML, etc. \n\nTeams that adopt YAGNI are often comfortable refactoring because they trust that when the feature set grows, they'll have more information about real use cases, leading to better abstractions.\n","experience":"junior","further_reading":[{"description":"Clear explanation with practical examples","title":"YAGNI on Martin Fowler's website","url":"https://martinfowler.com/bliki/Yagni.html"},{"description":"Ron Jeffries, Ann Anderson, Chet Hendrickson","title":"Extreme Programming Installed","url":"https://amzn.to/4siycbq"},{"description":"Original XP community discussion","title":"You Aren't Gonna Need It on C2 Wiki","url":"http://wiki.c2.com/?YouArentGonnaNeedIt"}],"group":"Design","image":"/images/laws/yagni.png","origins":"YAGNI was part of the Extreme Programming (XP) paradigm in the late 1990s. It was promoted by Ron Jeffries, one of XP's founders, who wrote: \"Always implement things when you actually need them, not when you just foresee that you need them.\"\n\nThe slogan was adopted in XP literature, such as Extreme Programming Installed (2001).\n","overview":"YAGNI captures a core philosophy of agile development: don't write code for features that haven't been requested or aren't immediately needed. \n\nIf you're implementing Module A and think \"in the future we might need Module B to do X, so I'll code some hooks for that now,\" YAGNI advises against it because that future feature may never come or may change drastically.\n\nThis principle directly fights over-engineering. To apply YAGNI successfully, teams rely on confidence in refactoring. You defer a feature only if you trust you can add it later at low cost. \n\nAgile methods provide that safety net via good test coverage, refactoring tools, and continuous integration. YAGNI pushes the problem of complexity to when it's actually needed.\n","related":["kiss-principle","dry-principle","premature-optimization"],"slug":"yagni","takeaways":["YAGNI is here to remind developers to focus on current tasks rather than implementing features that aren’t needed now.","Anticipating future needs often leads to over-engineering, and this adds complexity and maintenance issues.","YAGNI encourages iterative development. You implement minimal solutions and refine or extend them when needed."],"title":"YAGNI (You Aren't Gonna Need It)","url":"https://lawsofsoftwareengineering.com/laws/yagni/"},{"description":"Adding manpower to a late software project makes it later.","examples":"A project is one month behind schedule, so management adds 3 new developers to a 5-person team. Over the next few weeks, progress slows. The original developers spend much of their time explaining the design and code to newcomers, and merging their work causes integration headaches. The project slips further, now two months late.\n\nA complex bug required deep knowledge of the system. Adding more people didn't help because only the original dev understood it, and more debuggers only made things worse. Scaling a software team isn't linear. After a point, more members yield less and less output per person.\n","experience":"mid","further_reading":[{"description":"Fred Brooks's classic book on software engineering","title":"The Mythical Man-Month","url":"https://amzn.to/4peJbjC"},{"description":"Wikipedia article on Brooks's Law","title":"Brooks's Law - Wikipedia","url":"https://en.wikipedia.org/wiki/Brooks%27s_law"},{"description":"Fred Brooks's essay on essential vs accidental complexity","title":"No Silver Bullet","url":"https://en.wikipedia.org/wiki/No_Silver_Bullet"}],"group":"Teams","image":"/images/laws/brooks-law.png","origins":"**Frederick P. Brooks Jr.**, who managed the IBM OS/360 project, formulated this law based on painful experience. His book *The Mythical Man-Month* (1975) explores why software projects fail and where management assumptions break down.\n\nThe book famously challenged the notion that \"man-months\" are interchangeable. Brooks demonstrated through real-world examples why the assumption that 12 programmers can do in one month what one programmer does in 12 months fails in software development.\n","overview":"Brooks's Law challenges the belief that a software development effort is perfectly divisible among people. In reality, adding a person to a project incurs training costs and increases the number of communication paths. This can outweigh that person's contribution for a while.\n\nIf a project is already late, adding new developers can cause further delays as they learn the system and may introduce new bugs. Brooks illustrated this with the analogy: \"You cannot get a baby in one month by impregnating nine women.\" The law doesn't say adding people never helps, but as a response to lateness, it's usually counterproductive.\n","related":["conways-law","second-system-effect","law-of-unintended-consequences"],"slug":"brooks-law","takeaways":["Simply throwing more developers at a project that's running behind schedule usually slows it down further initially.","New people take time to get up to speed, consuming existing team members' time for training and coordination, which reduces overall productivity.","Instead of hoping manpower will solve slippage, adjust the scope or timeline. Be wary of 'just hire more coders' as a solution to lateness."],"title":"Brooks's Law","url":"https://lawsofsoftwareengineering.com/laws/brooks-law/"},{"description":"A complex system that works is invariably found to have evolved from a simple system that worked.","examples":"**Facebook** started as a simple website for Harvard students. It was essentially a basic user profile system that worked at that small scale, then expanded gradually, adding features and handling more users. If Mark Zuckerberg had tried to build today's Facebook from scratch in 2004, it would almost certainly have collapsed under its own complexity.\n\nIn the era of microservices, a common piece of advice influenced by Gall's Law is: don't start with microservices. Start with a monolith (a simpler architecture) that works. As it grows, identify pieces to split off into separate services. Those pieces have the benefit of prior existence, you know their requirements from the monolith, and thus are more likely to work once isolated.\n","experience":"senior","further_reading":[{"description":"John Gall","title":"The Systems Bible","url":"https://amzn.to/4svZT0K"},{"description":"Fred Brooks","title":"The Mythical Man-Month","url":"https://amzn.to/4b4GU72"},{"description":"Martin Fowler","title":"Monolith First","url":"https://martinfowler.com/bliki/MonolithFirst.html"},{"description":"Donella Meadows' primer on systems thinking and complexity","title":"Thinking in Systems","url":"https://amzn.to/4qgVSvH"}],"group":"Architecture","image":"/images/laws/galls-law.png","origins":"**John Gall**, an American pediatrician with a sideline in systems theory, published *Systemantics: How Systems Work and Especially How They Fail* in 1975. 30 publishers initially rejected the book before it became a cult classic.\n\nThe third edition (2002) of the book is named *The Systems Bible*.\n","overview":"John Gall observed that **successful complex systems start as successful simple systems**. If you attempt to create a complex system from the beginning, it usually doesn't work because there are too many unknowns you haven't validated.\n\nInstead, start with a simple architecture and learn from real-world usage. Add features or complexity incrementally, ensuring each change still works. When you start with a small, functional core, you can validate assumptions early. Every new capability added incrementally is tested against reality, forcing the system to adapt.\n","related":["conways-law","brooks-law","law-of-leaky-abstractions","hofstadters-law"],"slug":"galls-law","takeaways":["Don't build a complex system from scratch. Instead, make a simple version that works, then iterate and add complexity. This approach serves as a launching pad for experimentation and innovation.","Successful large systems often grow organically. A fully designed-from-scratch complex system usually fails because you can't foresee all interactions.","This law argues for creating a Minimum Viable Product (MVP), a simple working core, and then growing it, rather than a big-bang approach.","Systems that grow tend to adapt and handle complexity better because they've been tested and refined at each stage. An overly complex initial design can break when something unexpected happens."],"title":"Gall's Law","url":"https://lawsofsoftwareengineering.com/laws/galls-law/"},{"description":"All non-trivial abstractions, to some degree, are leaky.","examples":"A good example is **memory management in high-level languages**. Languages like Java and Python abstract away manual memory allocation thanks to garbage collection. Yet leaks still happen (objects not being freed due to lingering references), or you encounter the abstraction's limits (such as GC pauses affecting performance). Suddenly, the developer needs to know how garbage collection works internally, and the abstraction of \"infinite memory\" has leaked.\n\nWeb developers often treat an HTTP request as something fast, abstracting away the network. However, when latency spikes or packets drop, the network's reality leaks into your application.\n","experience":"mid","further_reading":[{"description":"Joel Spolsky's original blog post","title":"The Law of Leaky Abstractions","url":"https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/"},{"description":"Fallacies of Distributed Systems","title":"A Note on Distributed Computing","url":"https://scholar.harvard.edu/waldo/publications/note-distributed-computing"},{"description":"Gregor Kiczales' foundational paper on open implementations and abstraction leakage","title":"Towards a New Model of Abstraction in Software Engineering","url":"https://web.archive.org/web/20110604013045/http://www2.parc.com/csl/groups/sda/publications/papers/Kiczales-IMSA92/for-web.pdf"}],"group":"Architecture","image":"/images/laws/leaky-abstractions.png","origins":"Joel Spolsky introduced this law in a 2002 blog post. He gave examples such as TCP (which abstracts reliable connections over IP, but on a bad network the abstraction leaks, causing timeouts) or the virtual memory abstraction.\n\nThe concept resonates with many earlier thoughts in computing, essentially a restatement of \"there's no free lunch\" with abstractions.\n","overview":"This law observes that in complex systems, the abstractions we create, meant to hide complexity, *inevitably fail in some scenarios*, revealing the underlying complexity to the programmer.\n\nFor example, consider an ORM (object-relational mapper) that lets you treat database entries as objects. Most of the time it works, but occasionally you hit a case where performance is terrible and you have to think about the SQL queries being generated. The abstraction \"leaks\" details of the database. \n\nThe law isn't saying abstractions are bad. They are essential. But it reminds us that **one must be prepared for when they break**.\n","related":["hyrums-law","galls-law"],"slug":"law-of-leaky-abstractions","takeaways":["No matter how well-designed, abstractions (libraries, frameworks, etc.) have edge cases that depend on internal details.","Developers should understand that using a high-level tool doesn't absolve them from knowing what's happening underneath, at least at a basic level.","\"Leaky\" means you might encounter performance issues, bugs, or behavior that force you to consider the underlying system (e.g., networking, OS) on which the abstraction sits.","When creating abstractions, strive to minimize leakage and document the cases in which it might break."],"title":"The Law of Leaky Abstractions","url":"https://lawsofsoftwareengineering.com/laws/law-of-leaky-abstractions/"},{"description":"Every application has an inherent amount of irreducible complexity that can only be shifted, not eliminated.","examples":"A classic example is **scheduling meetings**, which is inherently complex (finding a common time). A tool like Calendly hides that complexity from the user (the software handles it), whereas an email chain to schedule a meeting places that complexity on the user to figure out.\n\nIn system architecture, imagine designing a database vs. putting logic in application code. Sometimes pushing logic into the DB (such as stored procedures) can simplify app code but add complexity to the DB layer, or vice versa. Complexity isn't gone, just relocated.\n\nIn the end, the law reminds us that no design is without complexity. It's all about smartly allocating complexity to the right place.\n","experience":"senior","further_reading":[{"description":"Farnam Street on the conservation of complexity","title":"Why Life Can't Be Simpler","url":"https://fs.blog/why-life-cant-be-simpler/"},{"description":"Deep dive into Tesler's Law and its implications","title":"Law of Conservation of Complexity","url":"https://humanist.co/blog/law-of-conservation-of-complexity/"},{"description":"Why chasing simplicity isn't always the answer","title":"Simplicity is Overrated","url":"https://marvelapp.com/blog/simplicity-is-overrated/"},{"description":"Wikipedia article on Tesler's Law","title":"Law of Conservation of Complexity (Wikipedia)","url":"https://en.wikipedia.org/wiki/Law_of_conservation_of_complexity"}],"group":"Architecture","image":"/images/laws/tesler-law.png","origins":"**Larry Tesler**, who worked on Apple Lisa and early GUI concepts, formulated this principle in the 1980s. He observed that you can't make everything simple without someone handling complexity. It's a fundamental trade-off in design.\n","overview":"Tesler's Law, also known as the Law of Conservation of Complexity, states that for any system, there is a certain amount of complexity that cannot be removed; it's inherent to the problem. The key is **who deals with it**.\n\nIf you design software that's very simple for the user, it likely means the software is doing a lot of complex work under the hood. If you make the software very simple internally, it might dump complexity on the user (e.g., requiring many manual steps). \n\nTesler's Law encourages designers to **move complexity away from the user experience** whenever possible.\n","related":["hyrums-law","occams-razor"],"slug":"teslers-law","takeaways":["Good design often requires that developers absorb most of the complexity (through smart defaults, algorithms, etc.) so that the user's interaction is simpler.","If your UI requires the user to manage many settings or steps, you've conserved complexity in the wrong place (on the user side). Often, it's better to design the product to manage that complexity internally.","Good design often hides complexity without eliminating it by handling it internally."],"title":"Tesler's Law (Conservation of Complexity)","url":"https://lawsofsoftwareengineering.com/laws/teslers-law/"},{"description":"A distributed system can guarantee only two of: consistency, availability, and partition tolerance.","examples":"The **Domain Name System (DNS)** is designed as AP (Available and Partition-tolerant). If some name servers are partitioned, they still reply (availability), even if their information might be slightly outdated until zones sync up.\n\n**MongoDB** is a CP (Consistent and Partition-Tolerant) database, blocking writes during a partition so all replicas stay in sync. **Cassandra** is an AP (Available and Partition-Tolerant) database, serving queries even if replicas briefly disagree.\n","experience":"senior","further_reading":[{"description":"Eric Brewer's reflection on CAP, twelve years later","title":"Brewer's CAP Theorem","url":"https://www.infoq.com/articles/cap-twelve-years-later-how-the-rules-have-changed/"},{"description":"Brewer's 2012 IEEE paper revisiting and refining the CAP theorem","title":"CAP Twelve Years Later: How the 'Rules' Have Changed","url":"https://sites.cs.ucsb.edu/~rich/class/cs293b-cloud/papers/brewer-cap.pdf"},{"description":"The formal proof of the CAP theorem","title":"Gilbert \u0026 Lynch 2002 Paper","url":"https://groups.csail.mit.edu/tds/papers/Gilbert/Brewer2.pdf"},{"description":"Martin Kleppmann's comprehensive guide covering CAP and distributed systems","title":"Designing Data-Intensive Applications","url":"https://amzn.to/4pVAwU5"},{"description":"Martin Kleppmann's 2015 paper arguing the theorem's definitions are ambiguous","title":"A Critique of the CAP Theorem","url":"https://www.cl.cam.ac.uk/research/dtg/archived/files/publications/public/mk428/cap-critique.pdf"}],"group":"Architecture","image":"/images/laws/CAP-theorem.png","origins":"Eric Brewer created the theorem in 2000 in the context of web services, and it was later formalized by Gilbert and Lynch in 2002. Brewer observed that designers of large-scale systems faced three concerns: keeping data consistent across nodes, keeping the service up, and handling network unreliability.\n\nThe formal proof showed that in a distributed system with shared data, you **must sacrifice either consistency or availability when a network partition occurs**. CAP became a guiding principle in the NoSQL movement and distributed database design in the 2000s.\n","overview":"The CAP theorem states that a distributed system cannot simultaneously provide all three guarantees: **Consistency** (all nodes see the same data), **Availability** (every request receives a response), and **Partition Tolerance** (the system operates despite network failures).\n\nSince network partitions are unavoidable in practice, systems must be partition-tolerant. This means choosing between consistency and availability when designing distributed architectures. The CAP theorem is a useful starting point, though it is a simplification that doesn't cover all aspects of the design space.\n","related":["fallacies-of-distributed-computing"],"slug":"cap-theorem","takeaways":["A distributed system can only guarantee two out of three things at once: Consistency, Availability, and Partition Tolerance. When the network is healthy you can have all three, but the moment a partition happens, you have to give one up.","When a network split occurs, you face a choice: stay consistent (every node agrees, but some requests may fail) or stay available (every request gets an answer, but the data might be slightly out of date). You can't fully have both.","Real databases pick a side. MongoDB leans toward consistency, blocking writes during a partition so all replicas stay in sync. Cassandra leans toward availability, keeping the lights on and serving queries even if replicas briefly disagree."],"title":"CAP Theorem","url":"https://lawsofsoftwareengineering.com/laws/cap-theorem/"},{"description":"Small, successful systems tend to be followed by overengineered, bloated replacements.","examples":"A startup builds a minimal web service that's very successful. For version 2, the team plans a complete rewrite with microservice architecture, tons of configuration options, plug-in frameworks, and features users never asked for. The project explodes in complexity and misses deadlines.\n\n**Netscape Navigator** in the 1990s decided to rewrite their browser after initial success, leading to the Mozilla Suite. The rewrite took many years, during which Internet Explorer caught up. The new suite was considered overly complicated, and Netscape lost its lead.\n","experience":"senior","further_reading":[{"description":"Fred Brooks' classic book on software engineering","title":"The Mythical Man-Month","url":"https://amzn.to/4b4GU72"},{"description":"Wikipedia article on the Second-system effect","title":"Second-system effect - Wikipedia","url":"https://en.wikipedia.org/wiki/Second-system_effect"},{"description":"Joel Spolsky on the Netscape rewrite disaster","title":"Things You Should Never Do, Part I","url":"https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/"}],"group":"Architecture","image":"/images/laws/second-system-effect.jpeg","origins":"Fred Brooks coined the term in 1975 in *The Mythical Man-Month*. He observed it in practice at IBM, where successful small systems (such as simplistic tape-based OS) were followed by OSes that tried to do far more and ran late or failed.\n\nThe phrase \"second-system syndrome\" appears in an essay of the same name in the book.\n","overview":"A small, elegant system is built and works well. A second version is initiated, and the designers, freed from the constraints of the first project, try to build something much bigger and more complex. They add enhancements, address all edge cases, and incorporate wishlist features. The result is often an overly complex, behind-schedule system.\n\nBrooks noted this with IBM's OS/360: simpler earlier systems were followed by a second system that became very complex. The syndrome is an exercise in hubris. The team doesn't realize how much harder the bigger scope will be. \n\nThe second-system effect warns engineers to be suspicious of grand redesigns that promise to include everything.\n","related":["yagni","galls-law","brooks-law"],"slug":"second-system-effect","takeaways":["The first system is kept lean by constraints or inexperience. When designing its successor, there's a tendency to incorporate all the extras initially left out, leading to feature bloat.","Overconfidence plays a role. Having succeeded once, the team feels they can tackle much more, underestimating complexity.","The second-system effect often results in over-engineering with more modules, generality, and features than necessary, hurting performance and maintainability."],"title":"Second-System Effect","url":"https://lawsofsoftwareengineering.com/laws/second-system-effect/"},{"description":"A set of eight false assumptions that new distributed system designers often make.","examples":"A developer building a distributed caching system assumes \"network latency is zero.\" They design the cache to fetch data from a remote node for every lookup. In practice, it thrashes with high latency and poor performance.\n\nA system assumes \"the network is secure\" and sends sensitive data unencrypted or doesn't validate inputs from other services. This leads to breaches if the network is compromised. Not planning for changing topology has broken systems when machines are added or removed unexpectedly.\n","experience":"senior","further_reading":[{"description":"Wikipedia article on the eight fallacies","title":"Fallacies of Distributed Computing - Wikipedia","url":"https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing"},{"description":"Arnon Rotem-Gal-Oz's detailed explanation of each fallacy","title":"Fallacies of Distributed Computing Explained","url":"https://www.rgoarchitects.com/Files/fallacies.pdf"},{"description":"James Gosling's page on the fallacies","title":"The Eight Fallacies of Distributed Computing","url":"https://nighthacks.com/jag/res/Fallacies.html"},{"description":"Martin Kleppmann's book addressing all eight fallacies in depth","title":"Designing Data-Intensive Applications","url":"https://amzn.to/4pVAwU5"},{"description":"Vaidehi Joshi's accessible explanation of each fallacy","title":"Foraging for the Fallacies of Distributed Computing","url":"https://medium.com/baseds/foraging-for-the-fallacies-of-distributed-computing-part-1-1b35c3b85b53"}],"group":"Architecture","image":"/images/laws/fallacies-of-distributed-computing.png","origins":"Credited primarily to **L. Peter Deutsch** (with others like James Gosling adding to the list) around 1994 at Sun Microsystems. Initially there were seven fallacies; an eighth (\"the network is homogeneous\") was added by Gosling later.\n\nDeutsch observed that many engineers, especially those used to local computing, would subconsciously assume the network just works. Formalizing these assumptions as a list helped teams remember to address each one.\n","overview":"The Eight Fallacies serve as a checklist of what not to assume. They all spring from treating a distributed system like a local one. Developers might write code as if calling a remote service is just like calling a local function, ignoring latency and failure.\n\nThese mistaken assumptions lead to serious issues: unhandled errors when the network breaks, poor performance due to ignoring latency, security breaches from failing to authenticate remote calls. \n\nBy calling them \"fallacies,\" creators sought to instill the mindset that the network will fail and behave non-ideally, so your system must be designed to tolerate that.\n","related":["cap-theorem","murphys-law"],"slug":"fallacies-of-distributed-computing","takeaways":["Networks drop messages, introduce delays, have finite throughput, and can be insecure. Properly built distributed systems must account for these with retries, timeouts, security measures, and dynamic discovery.","The fallacies often manifest in subtle bugs. Assuming latency is zero might lead to chatty remote calls that work fine locally but become painfully slow over a network.","Taking these fallacies into account leads to defensive design: using caches (bandwidth/latency aren't perfect), building redundancy (networks aren't reliable), and handling dynamic membership (topology changes)."],"title":"Fallacies of Distributed Computing","url":"https://lawsofsoftwareengineering.com/laws/fallacies-of-distributed-computing/"},{"description":"Whenever you change a complex system, expect surprise.","examples":"Enabling a new logging feature to help with debugging might fill the disk and crash the system, a perverse result relative to the goal of stability.\n\nA social network changes its algorithm to boost user engagement, but as an unintended consequence, it amplifies outrage or misinformation. A bug fix in one part of the code unexpectedly causes a regression in another module that depended on the original bug behavior (overlap with Hyrum's Law).\n","experience":"senior","further_reading":[{"description":"Wikipedia article on unintended consequences","title":"Unintended consequences - Wikipedia","url":"https://en.wikipedia.org/wiki/Unintended_consequences"},{"description":"Robert K. Merton's original 1936 paper","title":"The Unanticipated Consequences of Purposive Social Action","url":"https://www.jstor.org/stable/2084615"},{"description":"Popular economics blog and book series exploring unintended consequences","title":"Freakonomics","url":"https://freakonomics.com/"}],"group":"Architecture","image":"/images/laws/law-of-unintended-consequences.png","origins":"Sociologist **Robert K. Merton** popularized the term in the 20th century, though the concept dates back further. In a computing context, it's more of a borrowed concept than a specific person's law.\n\nMerton identified five sources of unanticipated consequences: ignorance, error, immediate interest, basic values, and self-defeating prophecy.\n","overview":"The Law of Unintended Consequences states that outcomes are not entirely predictable. Systems have complex interdependencies and human factors that can cause surprises.\n\nAdding a new feature might unexpectedly degrade performance due to its interaction with an unrelated module. Simplifying a UI could lead to heavier backend load because users use the feature more often than expected. \n\nIt reminds engineers that systems are complex and our mental models are incomplete. When implementing changes, anticipate that \"unknown unknowns\" will crop up.\n","related":["hyrums-law","galls-law"],"slug":"law-of-unintended-consequences","takeaways":["No matter how well you plan, any significant change in a complex system can produce results you cannot anticipate.","Consequences can be unexpected benefits (happy surprises), unexpected drawbacks (side effects that hinder), or perverse results (the action makes the original problem worse).","In software engineering, this often manifests as a fix or new feature introducing bugs or performance issues elsewhere."],"title":"Law of Unintended Consequences","url":"https://lawsofsoftwareengineering.com/laws/law-of-unintended-consequences/"},{"description":"Every program attempts to expand until it can read mail.","examples":"**Netscape Navigator** grew from a slim browser into Netscape Communicator, an expansive suite with browser, email, news, and web editing. It became sluggish and over-complicated, paving the way for Firefox, which deliberately stripped down to just a fast browser. Firefox itself later became heavier with plugins and themes.\n\n**Slack** set out to \"kill email\" but integrated voice calls, video meetings, file sharing, bots, and app plugins. It now wants to be a one-stop workplace hub, far beyond simple messaging. \n\n**GitHub** started hosting code, then expanded to issue tracking, wikis, project boards, discussions, CI pipelines, and package registries.\n","experience":"senior","further_reading":[{"description":"Wikipedia section on Zawinski's Law","title":"Zawinski's Law - Wikipedia","url":"https://en.wikipedia.org/wiki/Jamie_Zawinski#Zawinski's_Law"},{"description":"Joel Spolsky's classic essay on software bloat and platformization","title":"Don't Let Architecture Astronauts Scare You","url":"https://www.joelonsoftware.com/2001/04/21/dont-let-architecture-astronauts-scare-you/"}],"group":"Architecture","image":"/images/laws/zawinski-law.png","origins":"**Jamie Zawinski** (known as jwz) formulated this law around 1995 during his time at Netscape. He was a key programmer on Netscape Navigator and later added the integrated Netscape Mail reader.\n\nHe described the browser's evolution as \"our contribution to the proof of the Law of Software Envelopment.\" Netscape started as a web browser but by version 2.0-3.0 had expanded to include an email client and news reader. \n\n\"Reading mail\" was the chosen example because in the mid-90s, you often had to exit your current application and launch a mail program separately.\n","overview":"Zawinski's Law is a humorous observation about software evolution stating that applications continually gain features until they do everything, even things completely outside their original scope. It highlights feature creep, the gradual expansion of scope in software development.\n\nAs an application attracts more users, it faces growing expectations to add more capabilities. A basic note-taking app might later incorporate chat or sharing. \n\nZawinski's point was about \"platformization\": once users live in an app for a significant part of their day, there is pressure for that app to become a platform that can do everything. Unchecked expansion can sabotage a product's original value. Adding features is easy, but adding only the right features and saying \"no\" to the rest is essential.\n","related":["second-system-effect","yagni"],"slug":"zawinskis-law","takeaways":["Feature creep is unavoidable. Over time, software tends to accumulate more features, leading to software bloat.","A lean, minimal application that gains popularity will continually add features until it becomes as complex as its competitors.","Programs expand because users (and product managers) keep asking for “just one more feature”. There is constant pressure to incorporate popular capabilities to keep users from leaving for other tools.","Each new feature increases complexity, which makes the product confusing for users. Developers should protect the tool’s focus and resist platform sprawl."],"title":"Zawinski's Law","url":"https://lawsofsoftwareengineering.com/laws/zawinskis-law/"},{"description":"There is a cognitive limit of about 150 stable relationships one person can maintain.","examples":"Many startups report that around the 150-employee mark, the culture shifts. You no longer know everyone's name, informal communication falters, and you start needing all-hands meetings and internal newsletters. That's Dunbar's number in action.\n\nThe **Linux kernel community** has thousands of contributors, but within it are maintainers and subsystem teams that are relatively small. Communication is structured into mailing lists by subsystem, so any given person communicates only with a small number of peers. \n\nAmazon's \"two-pizza teams\" (5-10 people) show that even within 150, effective working teams are smaller units.\n","experience":"senior","further_reading":[{"description":"Wikipedia article on Dunbar's number","title":"Dunbar's Number - Wikipedia","url":"https://en.wikipedia.org/wiki/Dunbar%27s_number"},{"description":"Robin Dunbar's book introducing the concept","title":"Grooming, Gossip, and the Evolution of Language","url":"https://www.amazon.com/Grooming-Gossip-Evolution-Language-Dunbar/dp/0674363361"}],"group":"Teams","image":"/images/laws/dunbar-number.png","origins":"**Robin Dunbar** introduced this number in a 1992 paper and popularized it in his book *Grooming, Gossip, and the Evolution of Language*. He found a correlation between primate neocortex size and social group size, predicting human size at ~150.\n\nExamples such as historical village sizes, military company units, and communal groups often hover around 100-200, lending credence to the figure.\n","overview":"Dunbar's Number means that an engineering department of 150 might function informally, but as it grows past that, you start needing more formal rules, communication channels, and management layers. Informal knowledge (\"I know who to talk to about X\") begins to fail, and teams feel impersonal.\n\nThe rule encourages designing sub-teams or \"teams of teams\" that are small enough to work together effectively. Dunbar also proposed smaller social layers: ~5 intimate relationships, ~15 trusted collaborators, ~50 close working relationships, and ~150 stable social connections. \n\nFor software teams, high-trust work happens in tiny groups, teams larger than ~10-15 lose cohesion, and the 150 limit applies to departments or communities, not day-to-day collaboration.\n","related":["conways-law","brooks-law"],"slug":"dunbars-number","takeaways":["Dunbar's number (~150) is the size of a community in which everyone knows each other's identities and roles. Beyond this, our brains struggle to track relationships.","In software organizations, teams larger than ~100-150 will require more hierarchy or splitting into subgroups to function effectively. Coordination overhead rises sharply.","Smaller limits exist for closer relationships. Effective working groups might be much smaller than 150, but 150 is an upper bound for a community feeling.","Strong collaboration happens in groups far below the 150 threshold. Small teams win."],"title":"Dunbar's Number","url":"https://lawsofsoftwareengineering.com/laws/dunbars-number/"},{"description":"Individual productivity decreases as group size increases.","examples":"In a brainstorming session with 3 people, each might contribute many ideas. In a session with 15 people, many participants will say nothing, assuming others will speak.\n\nIf 10 developers work on one module, merging code, resolving conflicts, and communicating design decisions can consume significant time. This effect motivates Amazon's \"Two Pizza Rule\" (a team feedable by two pizzas, roughly 5-8 people).\n","experience":"mid","further_reading":[{"description":"Wikipedia article on the Ringelmann effect","title":"Ringelmann Effect - Wikipedia","url":"https://en.wikipedia.org/wiki/Ringelmann_effect"},{"description":"The psychological phenomenon behind the effect","title":"Social Loafing - Wikipedia","url":"https://en.wikipedia.org/wiki/Social_loafing"},{"description":"Amazon's approach to keeping teams small and effective","title":"The Two Pizza Rule","url":"https://aws.amazon.com/executive-insights/content/amazon-two-pizza-team/"},{"description":"Malcolm Gladwell's book exploring how small changes can have big effects","title":"The Tipping Point","url":"https://amzn.to/4jfJ1Hb"},{"description":"Scholtes, Mavrodiev \u0026 Schweitzer (2016) - empirical study of team productivity and coordination in OSS projects","title":"From Aristotle to Ringelmann: A Large-Scale Analysis of Team Productivity and Coordination in Open Source Software Projects","url":"https://doi.org/10.1007/s10664-015-9406-4"}],"group":"Teams","image":"/images/laws/ringelmann-effect.png","origins":"Named after **Max Ringelmann**, a French agricultural engineer who observed it in physical tasks around 1913. He found that when people pulled on a rope together, each individual exerted less force than when pulling alone.\n\nThe phenomenon was later termed \"social loafing\" in psychology. It has been demonstrated in many group situations beyond rope pulling, from cognitive tasks to workplace productivity.\n","overview":"The Ringelmann Effect states that as more people work together, individual effort decreases. In software teams, productivity per person often declines in larger groups due to coordination overhead and some individuals contributing less when in a crowd.\n\nThis effect warns that adding team members can make each existing member less efficient. Along with Brooks's Law, it shows that teamwork doesn't scale linearly. Teams must be structured to mitigate this with clear roles and small, focused groups.\n","related":["brooks-law","dunbars-number","conways-law"],"slug":"ringelmann-effect","takeaways":["In large teams, some people put in less effort because they assume others will pick up the slack or because their contributions are less visible.","More people mean more communication, meetings, and alignment needed. Time spent coordinating increases, leaving less time for actual work.","There is a point at which adding people yields diminishing returns, or even negative returns per person. Small, focused teams often outperform poorly coordinated larger teams.","Smaller teams or individuals feel greater ownership and responsibility."],"title":"The Ringelmann Effect","url":"https://lawsofsoftwareengineering.com/laws/ringelmann-effect/"},{"description":"The square root of the total number of participants does 50% of the work.","examples":"Take an open-source project on GitHub with 30 contributors. Often, you'll see that maybe 5 contributors (roughly √30 ≈ 5) are responsible for about half the code commits or major features. The rest contribute smaller patches or documentation.\n\nA notable example is when Twitter cut staff after Musk bought it, yet the product kept running. Before the takeover, Twitter had roughly 7,500 employees, meaning √7,500 ≈ 87. Price's law suggests that when the new leadership decided to lay off almost 50% of staff, the platform could still operate if the core 80-100 people stayed. But this holds only if the proper people are selected. The law won't predict reliability, as layoffs strip redundancy in SRE, security, and moderation. Twitter even asked some laid-off workers to return, a signal that it missed critical skills.\n","experience":"senior","further_reading":[{"description":"Wikipedia article on Price's Law and its empirical challenges","title":"Price's Law - Wikipedia","url":"https://en.wikipedia.org/wiki/Price%27s_law"},{"description":"Biography of the scientist who discovered the law","title":"Derek J. de Solla Price - Wikipedia","url":"https://en.wikipedia.org/wiki/Derek_J._de_Solla_Price"}],"group":"Teams","image":"/images/laws/prices-law.png","origins":"**Derek de Solla Price**, a British physicist, historian of science, and information scientist, discovered this pattern while studying his peers in academia. He noticed that there were always a handful of people who dominated publications within a subject.\n\nHe introduced this concept in his 1963 book \"Little Science, Big Science\" as part of his broader research on scientific productivity and information dynamics. The law has since been generalized to various fields, though empirical data suggests it's more of a model than an absolute rule, as the related Lotka's law often fits better.\n","overview":"You probably noticed that most of the major work depends on just a few people in your organization, and that is not false. In software teams, it means a relatively small group of engineers will deliver a disproportionately large part of the value. This is similar to the Pareto principle (80/20 rule) but even more extreme for larger groups.\n\nPrice's Law suggests that simply hiring more developers won't necessarily scale output as expected. Beyond a point, many may contribute little or be working on peripheral tasks. It's an argument for focusing on quality when hiring: a single excellent engineer can outperform several average ones. However, we must be careful with this \"law\" as we don't want to make other people feel useless, as they may be doing essential tasks that are given less importance. \n\nIt highlights a risk: if those top √N contributors leave, you lose a large chunk of productivity, so retention and preventing burnout for them are critical.\n","related":["ringelmann-effect","brooks-law","dunbars-number"],"slug":"prices-law","takeaways":["A small fraction of people often contribute a significant fraction of the results. In a 100-person engineering org, about 10 people might produce half of the output.","As teams grow, productive output doesn't scale linearly. Adding more people increases total output, but many will make smaller contributions than the core group.","Knowing this helps in team planning and understanding why losing specific individuals has a significant impact on productivity.","It's wise to identify and retain the small group of people who are essential to the company's output."],"title":"Price's Law","url":"https://lawsofsoftwareengineering.com/laws/prices-law/"},{"description":"Those who understand technology don't manage it, and those who manage it don't understand it.","examples":"Think of a software manager who came from a sales or business background. They might push the team to add complex features at warp speed, failing to understand why quality or testing is needed. They \"manage what they do not understand.\" \n\nOn the other side, a brilliant sysadmin knows precisely how to optimize infrastructure but isn't involved in management decisions about budgeting or project direction. They \"understand what they do not manage.\"\n\nPerhaps the manager promises a client a feature by next week (not understanding the technical difficulty), and the engineering team is frustrated because the manager didn't realize what's involved. Many startups initially avoid this because founders often manage and deeply understand the tech, but as companies grow, specialization separates roles. One remedy is to have CTOs or tech leads act as a bridge, with one foot in management and one in technical detail.\n","experience":"senior","further_reading":[{"description":"The original satirical book by Archibald Putt","title":"Putt's Law and the Successful Technocrat - Amazon","url":"https://amzn.to/4aAuOm0"},{"description":"Herkert, Borenstein \u0026 Miller (2020) - examines how management decisions overriding technical expertise led to disaster","title":"The Boeing 737 MAX: Lessons for Engineering Ethics","url":"https://doi.org/10.1007/s11948-020-00252-y"}],"group":"Teams","image":"/images/laws/putts-law.png","origins":"Putt's Law was revealed in the satirical book \"Putt's Law and the Successful Technocrat\" (1981). The author used the pseudonym \"Archibald Putt.\"\n\nThe book offers a cynical but insightful look at the dynamics of technical organizations and how competence often gets inverted as people rise through hierarchies. It overlaps conceptually with the Peter Principle (people rise to their level of incompetence) and the Dilbert Principle (incompetent people end up in management).\n","overview":"Putt's Law explains a known concept: that the best engineers aren't in charge, and those in charge aren't deeply knowledgeable about the technology. While not universally true, this highlights a real challenge: managing technologists requires some understanding of their work. But managers often come from different backgrounds or have been away from the code for a long time.\n\nThe law's corollary states: \"Every technical hierarchy, in time, develops a competence inversion,\" meaning the people at the top know less about the work than those below. The gap creates dysfunction: managers set unrealistic deadlines because they don't understand technical subjects, while engineers build wrong solutions because they don't understand the business context. \n\nThe lesson is clear: technical leadership should maintain technical competence or risk mismanaging the technical work.\n","related":["peter-principle","dilbert-principle"],"slug":"putts-law","takeaways":["There is often a gap between deep technical understanding and management roles. Rarely does one person excel at both.","Technical experts often aren't in management, and managers usually don't understand the technical details.","This can lead to unrealistic expectations, such as when management sets unrealistic expectations because they don’t understand the domain and its complexity. At the same time, engineers are feeling misunderstood.","Successful organizations bridge this by training managers in tech basics or promoting technically savvy leaders."],"title":"Putt's Law","url":"https://lawsofsoftwareengineering.com/laws/putts-law/"},{"description":"In a hierarchy, every employee tends to rise to their level of incompetence.","examples":"In a development team, Alice is the best programmer. Management appoints her team manager since she's the most experienced. But she has no experience or desire for people management. As a result, the team struggles. She either micromanages or misses essential management tasks, all while coding less (her main strength). Alice has reached her \"level of incompetence\" and might remain in that role indefinitely.\n\nConsider a QA engineer fantastic at finding bugs who gets promoted to QA Lead, a role involving paperwork and strategy. If those aren't their strengths, the QA process might decline.\n\nMany tech organizations now use **individual contributor (IC) career tracks** to combat this, allowing great engineers to remain engineers with raises and titles rather than forcing them into management to advance. The principle also encourages rotations or acting in leadership roles to ensure competence before permanent assignments.\n","experience":"mid","further_reading":[{"description":"Overview of the Peter Principle and its implications","title":"The Peter Principle - Wikipedia","url":"https://en.wikipedia.org/wiki/Peter_principle"},{"description":"The original 1969 book by Laurence J. Peter","title":"The Peter Principle: Why Things Always Go Wrong - Amazon","url":"https://amzn.to/48XHHW7"}],"group":"Teams","image":"/images/laws/peter-principle.png","origins":"The Peter Principle was described in the book \"The Peter Principle\" by **Laurence J. Peter** in 1969. It was meant as a humorous piece of sociology and business insight.\n\nScott Adams' Dilbert Principle later riffed on it, cynically inverting the idea by suggesting companies promote incompetent people to get them out of the workflow. Both highlight absurdities in corporate culture.\n","overview":"The Peter Principle explains why organizations often end up with mediocre managers. A great engineer gets promoted to tech lead but struggles in the role, and now the company has lost a great engineer.\n\nFor a healthy organization, it's essential to mitigate this. Not every senior engineer should become a manager; some might advance as staff or principal engineers instead. New managers need training to be competent in their new role. \n\nThe Peter Principle warns that promotion systems can create mediocrity at higher levels if not designed carefully.\n","related":["dilbert-principle","putts-law"],"slug":"peter-principle","takeaways":["People get promoted based on success in their current role until they reach a position where they are no longer competent.","A great developer promoted to manager might perform poorly, losing a good developer and gaining a bad manager.","Organizations should offer dual career paths (technical vs. managerial) to prevent this stagnation."],"title":"Peter Principle","url":"https://lawsofsoftwareengineering.com/laws/peter-principle/"},{"description":"The minimum number of team members whose loss would put the project in serious trouble.","examples":"If a startup's only database expert is Alice, the bus factor for database knowledge is 1. If Alice quits, nobody else knows the backups, schema intricacies, or tuning.\n\nThe **Left-pad incident** reflects a bus factor of 1 for the broader ecosystem: a single maintainer pulled a tiny NPM package, and thousands of builds broke.\n","experience":"mid","further_reading":[{"description":"Overview of the Bus Factor concept and its implications","title":"Bus Factor - Wikipedia","url":"https://en.wikipedia.org/wiki/Bus_factor"},{"description":"A real-world example of bus factor risk in open source","title":"Left-pad incident - Wikipedia","url":"https://en.wikipedia.org/wiki/Npm_left-pad_incident"},{"description":"The original article describing how talent drains from dysfunctional organizations","title":"The Dead Sea Effect - Bruce F. Webster","url":"https://brucefwebster.com/2008/04/11/the-wetware-crisis-the-dead-sea-effect/"},{"description":"Michael McLay's 1994 mailing list post, one of the earliest references to the bus factor concept","title":"If Guido was hit by a bus?","url":"https://legacy.python.org/search/hypermail/python-1994q2/1040.html"},{"description":"Coplien \u0026 Harrison (2004) - patterns for building effective software organizations","title":"Organizational Patterns of Agile Software Development","url":"https://www.wiley.com/en-us/Organizational+Patterns+of+Agile+Software+Development-p-9780131467408"}],"group":"Teams","image":"/images/laws/bus-factor.png","origins":"The concept was popularized in the 1990s in discussions of project risk. The term is somewhat morbid, so some call it \"lottery factor\" (flipping the scenario to a positive reason someone leaves).\n\nIt's not attributed to a single person but emerged as slang in software teams. An early reference appears in patterns literature (1994 PLoP conference), discussing \"truck number\" in organizational patterns. The idea likely existed informally even earlier.\n","overview":"The Bus Factor highlights the human single point of failure in projects. In many software teams, one or two people might understand the legacy system, a crucial algorithm, or have all the deployment knowledge. If those people leave, others cannot easily pick up the work.\n\nThe concept encourages actively avoiding such dependency. Improving bus factor overlaps with knowledge management practices: pair programming, code reviews, documentation, mentorship, and rotating responsibilities.\n","related":["conways-law","brooks-law","dunbars-number"],"slug":"bus-factor","takeaways":["A bus factor of 1 means one person holds critical knowledge; if they disappear, the project is essentially “doomed” or stalled. A higher bus factor (e.g., 5) means the project could lose any one of five specific people before stopping work.","It's basically a measure of knowledge distribution and risk. A high bus factor is good (knowledge is shared among many), while a low is bad (single points of failure in expertise).","Teams should work to increase their bus factor by sharing knowledge, documenting critical systems, having code reviews, and rotating responsibilities. "],"title":"Bus Factor","url":"https://lawsofsoftwareengineering.com/laws/bus-factor/"},{"description":"Companies tend to promote incompetent employees to management to limit the damage they can do.","examples":"Many engineers share anecdotes that feel straight out of Dilbert. A mediocre programmer or failing project lead gets \"promoted\" to a management or architect role. Sometimes these moves are less about recognizing leadership talent and more about getting a problematic person away from critical work. The result is counterproductive: you now have an incompetent manager and one fewer developer.\n\nOn a positive note, awareness of the Dilbert Principle has made some organizations more careful. Modern tech companies increasingly offer **dual career tracks** (technical vs. managerial) to avoid forcing great engineers into management. \n\nWhen an underperforming employee can't succeed in engineering, good companies try coaching or reassignment, and if all else fails, let them go rather than make them the boss.\n","experience":"senior","further_reading":[{"description":"Overview of Scott Adams' satirical management theory","title":"The Dilbert Principle - Wikipedia","url":"https://en.wikipedia.org/wiki/Dilbert_principle"},{"description":"The original 1996 book by Scott Adams","title":"The Dilbert Principle - Amazon","url":"https://amzn.to/4jgz6kJ"},{"description":"Scott Adams (1996) - the satirical take on corporate dysfunction that popularized the principle","title":"A Cubicle's-Eye View of Bosses, Meetings, Management Fads and Other Workplace Afflictions","url":"https://www.amazon.com/Dilbert-Principle-Cubicles-Eye-Meetings-Management/dp/0887308589"}],"group":"Teams","image":"/images/laws/dilbert-principle.png","origins":"**Scott Adams** introduced the Dilbert Principle in his 1996 book \"The Dilbert Principle.\" As with much of Dilbert, the framing is exaggerated, but the underlying organizational critique proved uncomfortably familiar to many engineers.\n","overview":"The Dilbert Principle suggests that instead of addressing poor performance directly, companies often promote struggling employees into management roles where their impact is perceived as less immediately harmful. The satire resonates because it reflects a fundamental flaw: many organizations treat management as the default career path for engineers without considering what those employees actually want or are suited for.\n\nWhen promotion replaces accountability, management layers fill with people lacking either technical credibility or leadership ability. The result is bad decisions, wrong priorities, and loss of trust between engineers and leadership. \n","related":["peter-principle","putts-law","brooks-law"],"slug":"dilbert-principle","takeaways":["Organizations sometimes deal with underperformers by promoting them into management, removing them from hands-on work.","It reflects a cynical view that lower-level employees do real work while some managers add little value.","Technical excellence and people leadership require different skills. Failing at one does not qualify someone for the other."],"title":"Dilbert Principle","url":"https://lawsofsoftwareengineering.com/laws/dilbert-principle/"},{"description":"Work expands to fill the time available for its completion.","examples":"A developer should write a module and is told, \"Take as long as you need, maybe a month or two.\" In many cases, the developer will not rush to finish it, perhaps experimenting with multiple implementations or polishing noncritical items. The same task, if given a one-week deadline, might have been completed in a week.\n\nAgile teams sometimes apply Parkinson's Law by **time-boxing tasks**. The fixed, short time box encourages everyone to focus on completing tasks before the sprint ends. \n\nSimilarly, if a meeting is scheduled to last all day, it often will. If the same activity were given a two-hour window, participants would likely focus and complete it within that time.\n","experience":"junior","further_reading":[{"description":"Cyril Parkinson's original 1955 essay in The Economist","title":"Parkinson's Law (Original Essay)","url":"https://www.economist.com/news/1955/11/19/parkinsons-law"},{"description":"The expanded book version of Parkinson's observations on bureaucracy and time","title":"Parkinson's Law: The Book","url":"https://amzn.to/4jg0OOD"},{"description":"Overview of Parkinson's Law and its applications in management","title":"Parkinson's Law - Wikipedia","url":"https://en.wikipedia.org/wiki/Parkinson%27s_law"}],"group":"Planning","image":"/images/laws/parkinson-law.png","origins":"Parkinson's Law was first described in an essay by Cyril Parkinson, published in The Economist in 1955, which initially described how bureaucracies expand over time. The phrase has since entered the lexicon of project management.\n\nIt's not specific to software, but software teams often see it in action during projects. \n","overview":"This law shows a common problem with time management among developers. If a developer is given two weeks to complete a task that could be done in two days, the work will usually slow down, consuming most of that time. People might spend more time planning, bikeshedding minor details, or simply delaying the start of the work with the understanding that they have enough time.\n\nParkinson's Law is often used to warn that loose deadlines reduce productivity, so teams should set clear, realistic time limits. However, managers must use it judiciously, combining Parkinson's insight with realistic scheduling. If you compress timelines too much, you risk running into Hofstadter's Law, which reminds us that work often still takes longer than expected, even with buffers.\n","related":["hofstadters-law","brooks-law"],"slug":"parkinsons-law","takeaways":["If you give a task an overly long timeline, people tend to use all of it (or procrastinate until the last minute), so the task takes as long as the deadline allows.","Giving more time, teams often do polishing (gold-plating) or add minor improvements that aren't strictly necessary, just to use the whole time allotted for the task.","A bit stronger (but realistic) deadlines can counteract Parkinson's Law by having a sense of urgency (called deadline-driven development)."],"title":"Parkinson's Law","url":"https://lawsofsoftwareengineering.com/laws/parkinsons-law/"},{"description":"The first 90% of the code accounts for the first 90% of development time; the remaining 10% accounts for the other 90%.","examples":"A team develops a new app. In three months, the core features are done, and they hit \"90% of the functionality.\" Everyone expects to ship in one more month. Instead, integration testing reveals that multiple modules do not talk correctly, specific edge inputs crash the app, memory usage is too high. That final \"10%\" takes another three months.\n\nWhen implementing a new website, you get a basic version up quickly (login, basic pages). The last bits: cross-browser fixes, responsive design adjustments, accessibility improvements, writing tests, and performance improvements seem like 10% of the work, but they take as much time as the main coding.\n\nThe rule is an important reminder: **Do not celebrate too early!**\n","experience":"mid","further_reading":[{"description":"Jon Bentley's original column where the rule was popularized","title":"Programming Pearls - Bumper Sticker Computer Science","url":"https://moss.cs.iit.edu/cs100/Bentley_BumperSticker.pdf"},{"description":"Jon Bentley's classic book on programming wisdom and techniques","title":"Programming Pearls (Book)","url":"https://amzn.to/49bLHkn"},{"description":"Overview of the rule and its origins at Bell Labs","title":"Ninety-Ninety Rule - Wikipedia","url":"https://en.wikipedia.org/wiki/Ninety%E2%80%93ninety_rule"},{"description":"Practical strategies for recognizing and countering the ninety-ninety trap","title":"Identifying and Mitigating the Ninety-Ninety Rule in Software Development","url":"https://dev.to/ben/identifying-and-mitigating-the-ninety-ninety-rule-in-software-development-4ap3"}],"group":"Planning","image":"/images/laws/90-90-rule.png","origins":"Credited to Tom Cargill of Bell Labs, and popularized by Jon Bentley's September 1985 \"Bumper-Sticker Computer Science\" column in Communications of the ACM. It was originally called the \"Rule of Credibility\", a name which did not stick.\n\nIt became popular in programming circles and is frequently referenced in discussions of why software is usually delivered late or why \"90% done\" claims can be misleading.\n","overview":"This rule quantifies the extent to which projects get stuck in the final phase. Often, teams make good progress at the start, building core functionality, which leads to optimism. Then integration, corner cases, performance tuning, and bug fixing consume an unexpectedly large amount of time, often equal to or greater than what has already been spent.\n\nIn practical terms, this rule advises that the last bit of a project is not a small bit. You should plan for a significant effort in finishing, polishing, and delivering. \n\nIt is also related to Hofstadter's Law, as it is another way our estimates fall short. We do not realize how hard that last leg is.\n","related":["hofstadters-law","parkinsons-law","pareto-principle"],"slug":"ninety-ninety-rule","takeaways":["The final parts of a project (polishing, edge cases, integration, bug fixes) often take far more effort than anticipated, often as much as the initial development.","What looks like the “finishing touches” involves many tricky problems and unknowns.","Reaching a “mostly done” state can create optimism, but the rule warns that “almost done” often means only halfway in terms of time."],"title":"The Ninety-Ninety Rule","url":"https://lawsofsoftwareengineering.com/laws/ninety-ninety-rule/"},{"description":"It always takes longer than you expect, even when you take into account Hofstadter's Law.","examples":"Virtually every software project can serve as an example. A team plans a new feature expecting it to take one month. They factor in potential delays and say six weeks to be safe. It ends up taking three months, sometimes even six months later. Why? Integrating with an API was harder, a key developer got sick, or the first approach failed and had to be redone. **The unexpected became the norm**.\n\nA practical rule of thumb: if it takes 2 minutes, do it now. If it takes a few minutes, call it 1 hour. If it takes a few hours, call it 1 day. We are not working to prove speed, but to buy enough space to ship well.\n","experience":"junior","further_reading":[{"description":"Douglas Hofstadter's Pulitzer Prize-winning book where the law first appeared","title":"Gödel, Escher, Bach: An Eternal Golden Braid","url":"https://amzn.to/4jjKSLl"},{"description":"Fred Brooks' classic on software project management with similar insights on estimation","title":"The Mythical Man-Month","url":"https://amzn.to/49cAqQO"},{"description":"A statistical model explaining estimation failures","title":"Why Software Projects Take Longer Than You Think","url":"https://erikbern.com/2019/04/15/why-software-projects-take-longer-than-you-think-a-statistical-model.html"}],"group":"Planning","image":"/images/laws/hofstadter-law.png","origins":"Douglas Hofstadter created this law in 1979 in his book \"Gödel, Escher, Bach: An Eternal Golden Braid\". The book explores themes of recursion and self-reference, making this recursive law a fitting example.\n\nIn software engineering, Fred Brooks' observation \"everything takes longer than it takes\" from The Mythical Man-Month has a similar meaning. The law has become common among developers who've all experienced projects that overshoot schedules.\n","overview":"This recursive law captures the paradox of estimation. No matter how much experience we have, projects tend to run late. Even if you say, \"This might take 2x longer than I think,\" it might still take 3x. It highlights the inherent uncertainty in complex creative work, such as software development. There are often hidden tasks, unplanned integration issues, or requirement changes.\n\nIn practice, Hofstadter's Law explains why techniques like padding estimates, awareness of Parkinson's Law, and the use of historical data are essential, yet surprises still occur. \n\nIt pairs with Parkinson's Law as a caution: don't pad too much (Parkinson will waste time), but also don't be naive (Hofstadter will bite you with delays).\n","related":["parkinsons-law"],"slug":"hofstadters-law","takeaways":["Humans are generally bad at estimating how long tasks take, especially in complex projects. Even when we know we're bad at it, we still underestimate.","There are always unknowns and complexities that reveal themselves during implementation, extending the timeline.","Include contingency buffers in schedules, but even those buffers often get consumed.","Don't be overly optimistic in planning. Acknowledge that delays happen and factor that into timelines and expectations."],"title":"Hofstadter's Law","url":"https://lawsofsoftwareengineering.com/laws/hofstadters-law/"},{"description":"When a measure becomes a target, it ceases to be a good measure.","examples":"A software team was rewarded based on the lines of code written. Developers start writing verbose code and copying and pasting into multiple places (violating DRY) to increase the line count. The software becomes bloated while the metric looks great.\n\nAnother example: a QA team measured by the number of test cases executed favored running many easy tests rather than doing proper testing. They met objectives but missed critical bugs. \n\nSimilarly, when teams focus on **code coverage percentage** as a primary target, developers write trivial unit tests that do not assert meaningful behavior, while necessary integration tests are skipped.\n\nIn today's world we see something similar with AI tokens consumed per engineer (a practice sometimes called **tokenmaxxing**), where more tokens is considered better, and even become one of the goals that people need to fulfill for their performance reviews.\n","experience":"senior","further_reading":[{"description":"Deep dive into Goodhart's Law and its implications for organizations","title":"Goodhart's Law: How Measuring The Wrong Things Drive Immoral Behaviour","url":"https://coffeeandjunk.com/goodharts-campbells-law/"},{"description":"Overview of the law's origins and applications","title":"Goodhart's Law - Wikipedia","url":"https://en.wikipedia.org/wiki/Goodhart%27s_law"},{"description":"Jerry Muller's book on the unintended consequences of metric fixation","title":"The Tyranny of Metrics","url":"https://amzn.to/4ji7rzY"},{"description":"How platforms degrade quality once metrics replace user value as the goal","title":"Enshittification - Wikipedia","url":"https://en.wikipedia.org/wiki/Enshittification"}],"group":"Planning","image":"/images/laws/goodharts-law.png","origins":"Named after economist Charles Goodhart, who originally described this phenomenon in the context of monetary policy metrics. Marilyn Strathern later provided the commonly cited phrasing: \"When a measure becomes a target, it ceases to be a good measure.\"\n\nThis concept has been discussed extensively in education and business KPIs, and certainly applies to software engineering metrics where velocity, code coverage, and bug counts are often used as targets.\n","overview":"Goodhart's Law comes from economics and is very relevant to software teams. For instance, a manager might set a target that \"we must close 100 bug tickets this month.\" Developers, feeling pressure, might start closing tickets that are not truly resolved or splitting a single bug into multiple tickets to inflate numbers.\n\nThe metric (tickets closed) goes up, but software quality might not. Making the metric a goal distorts the process, so it loses its correlation with actual success. This is why experienced leaders use metrics as indicators rather than targets, and always consider the broader context.\n","related":["dilbert-principle","parkinsons-law"],"slug":"goodharts-law","takeaways":["If you set a particular metric as a goal (e.g., lines of code written, number of features closed), people will find ways to optimize for that metric.","Metrics are proxies for what you value (productivity, quality, etc.). Once they're targets, people meet the metric even if it undermines the original intent.","Metrics are useful for insight, but they must be used in context and balanced with qualitative judgment.","Combine multiple metrics to avoid a singular focus that can be gamed."],"title":"Goodhart's Law","url":"https://lawsofsoftwareengineering.com/laws/goodharts-law/"},{"description":"Anything you need to quantify can be measured in some way better than not measuring it.","examples":"Measuring **developer productivity** is notoriously hard (lines of code are poor proxies, story points can be inconsistent). However, you might use deployment frequency or change lead time (as in the DORA metrics for DevOps) as a proxy. They do not capture everything, but they give you actionable data. If deployment frequency decreases, something might be wrong with the pipeline.\n\nAnother example is **tracking Tech Debt**. No perfect measure of tech debt exists. But tracking things like code complexity scores, incident rates, and developer surveys gives you visibility you would not otherwise have. As Peter Drucker said: \"We cannot improve what we do not measure.\"\n","experience":"mid","further_reading":[{"description":"Overview of Tom Gilb's contributions to software engineering","title":"Tom Gilb - Wikipedia","url":"https://en.wikipedia.org/wiki/Tom_Gilb"},{"description":"Tom Gilb's book on quantified requirements and design","title":"Competitive Engineering","url":"https://amzn.to/49AqaT1"},{"description":"The four key metrics for measuring DevOps performance","title":"DORA Metrics","url":"https://dora.dev/guides/dora-metrics-four-keys/"}],"group":"Planning","image":"/images/laws/gilbs-law.png","origins":"Tom Gilb, a consultant and author on software engineering, formulated this law. It complements his other work on quantifying requirements and using metrics in planning, including Planguage and evolutionary project management.\n","overview":"Gilb's Law responds to the paralysis that Goodhart's Law can cause. This law asserts that even an approximate or indirect measurement is better than none. When something is essential (performance, customer satisfaction, code maintainability), you should attempt to measure it, because otherwise you have no objective feedback. \n\nGilb's Law is a good reply to the statement “this aspect is unmeasurable so we won't try.” For example, measuring “code quality” is difficult, but you can measure indicators such as cyclomatic complexity, lint warnings, or defect rates as partial indicators. More such indicators can paint the bigger picture.\n\nThose metrics won't be perfect, but Gilb's Law suggests that having them gives you some insight and a starting point for improvement, which is better than having no clue at all. \n","related":["goodharts-law","parkinsons-law"],"slug":"gilbs-law","takeaways":["It is better to have some data or metric on a phenomenon than to be completely blind, as long as you understand the metric's limitations.","In contrast to Goodhart's Law, which warns about misuse of metrics, Gilb's Law reminds us not to throw out metrics entirely.","Start with a basic measure and refine it over time. The act of measuring helps teams focus and identify trends.","Even an approximate or indirect measurement is better than none."],"title":"Gilb's Law","url":"https://lawsofsoftwareengineering.com/laws/gilbs-law/"},{"description":"Anything that can go wrong will go wrong.","examples":"If a web form field can accept text, someone will enter a 10,000-character string of weird symbols to see what happens, unless you've explicitly handled it. If memory can run out, it will be when multiple processes align just so. \n\nA famous real-world instance was during a live demo (who remembers the Windows 98 presentation by Bill Gates?), if something can glitch, it likely will.\n\nIn coding, consider a function that assumes an input file exists. Murphy's Law says that one day that file won't be there or will be corrupted, so your code should handle the file-not-found or bad-data scenario rather than crash. \n\nAnother typical case is that the server will crash on your only day off, because that's when it's most likely to cause trouble. Engineers thus build highly available systems and pager rotations to mitigate Murphy's Law.\n","experience":"junior","further_reading":[{"description":"History and variations of the famous adage","title":"Murphy's Law - Wikipedia","url":"https://en.wikipedia.org/wiki/Murphy%27s_law"},{"description":"Bill Gates' infamous BSOD during a Windows 98 presentation","title":"Windows 98 Crash During Live Demo","url":"https://www.youtube.com/watch?v=yeUyxjLhAxU"},{"description":"Programming practices to anticipate and handle errors","title":"Defensive Programming","url":"https://en.wikipedia.org/wiki/Defensive_programming"},{"description":"Root cause analysis of the CrowdStrike outage, a real-world example of Murphy's Law at scale","title":"CrowdStrike Channel File 291 RCA Exec Summary","url":"https://www.crowdstrike.com/falcon-content-update-remediation-and-guidance-hub/"}],"group":"Quality","image":"/images/laws/murphy-law.png","origins":"Attributed to Edward A. Murphy Jr., an engineer working on rocket sled experiments in 1949. It became popular in aerospace and then everywhere. In software, it's been around as long as bugs have, constantly reminding us that if there's one untested scenario, one user will find it.\n","overview":"In software, Murphy's Law is often used to explain bugs and production incidents: whatever can go wrong in code (a null pointer, a race condition, a network outage) eventually will manifest, especially in large user bases or at the worst possible time.\n\nIn practice, this law encourages developers to write more defensive code. This means checking for nulls, handling exceptions, validating inputs, and failing gracefully when errors occur. It also reminds DevOps teams to anticipate failures by implementing monitoring, enabling rollbacks, and maintaining contingency plans.\n","related":["confirmation-bias"],"slug":"murphys-law","takeaways":["If an error can happen, it will happen. Plan and code defensively with this in mind.","Add error handling, backups, and checks.","Edge cases will occur in production. Write tests for these kinds of scenarios."],"title":"Murphy's Law / Sod's Law","url":"https://lawsofsoftwareengineering.com/laws/murphys-law/"},{"description":"Be conservative in what you do, be liberal in what you accept from others.","examples":"In **web browsers**, HTML on websites is often malformed. Browsers, following Postel's spirit, perform extensive error correction and forgiving parsing. They'll still render the page even if a tag isn't closed correctly. If browsers were strict, half the web pages might not display.\n\nIn **APIs**, say your service expects a timestamp. If it receives a timestamp without a time zone, instead of rejecting, maybe you assume UTC or try to parse it anyway, being liberal in acceptance. But when your service returns data, you always include the time zone to be conservative and precise in output. \n\nAn **email client** that receives a slightly non-conforming email (missing a MIME boundary or incorrect newline encodings) will still attempt to show the email rather than throwing an error.\n","experience":"mid","further_reading":[{"description":"Overview of Postel's Law and its applications","title":"Robustness Principle - Wikipedia","url":"https://en.wikipedia.org/wiki/Robustness_principle"},{"description":"The TCP specification where Postel articulated the robustness principle","title":"RFC 761 - DoD Standard Transmission Control Protocol","url":"https://datatracker.ietf.org/doc/html/rfc761"},{"description":"A critical examination of when being too liberal causes problems","title":"The Harmful Consequences of Postel's Maxim","url":"https://datatracker.ietf.org/doc/html/draft-thomson-postel-was-wrong-00"},{"description":"Eric Allman's ACM Queue article on security implications of liberal acceptance","title":"The Robustness Principle Reconsidered","url":"https://queue.acm.org/detail.cfm?id=1999945"}],"group":"Quality","image":"/images/laws/postels-law.png","origins":"Jon Postel wrote this in the specification of TCP in 1980 (RFC 761): \"TCP implementations should follow a general principle of robustness: be conservative in what you send, be liberal in what you accept.\" It became known as Postel's Law or the Robustness Principle and influenced many protocol designs.\n\nThere's a modern reconsideration: the HTML5 spec codified much of the error handling that browsers already do, arguing that all that \"liberal acceptance\" should itself be standardized to avoid ambiguity.\n","overview":"This law says that if your server sends HTTP responses, it should format headers exactly per spec. But if your server receives an HTTP request with an uncommon header order or an unusual format, you should still process it rather than drop the connection, as long as you can interpret it safely. \n\nThis principle contributed to the Internet's resilience, meaning that different implementations can communicate because each side strives to be compatible.\n\nIn software in general, think of file readers: a robust one can open not-quite-perfect files (e.g., a tolerant XML parser might recover from a minor error), whereas a strict one might refuse. Postel's Law would encourage the former. However, it has caveats. Being too liberal can allow sloppy producers to proliferate, and in security contexts, accepting malformed input can be risky. Some argue that overly tolerant software can cause long-term interoperability problems because producers never fix their bugs if everyone tolerates them.\n","related":["hyrums-law","law-of-leaky-abstractions","fallacies-of-distributed-computing"],"slug":"postels-law","takeaways":["When your system emits data or interacts with the outside world, adhere closely to protocols and standards.","When receiving data, handle variations, minor errors, or deviations where possible. Don't crash or reject communication over minor issues.","In modern times, overly liberal acceptance can sometimes mask errors, so this law is occasionally tempered with security considerations."],"title":"Postel's Law","url":"https://lawsofsoftwareengineering.com/laws/postels-law/"},{"description":"Don't leave broken windows (bad designs, wrong decisions, or poor code) unrepaired.","examples":"Consider a codebase with a few obvious kludges, such as functions with `// TODO: fix this hack` comments that never get fixed. If newcomers see that, they may be more inclined to add their own hacks (\"this project is full of hacks anyway...\"). Or if there's a module with no tests (a \"broken window\" in a test-coverage sense), other modules might start losing tests too as discipline erodes.\n\nOn the opposite side, think of a project where maintainers aggressively fix style issues and simplify code whenever they spot a problem. By contributing to such a project, developers quickly learn to match that cleanliness. \n\nMany teams have turned projects around by paying off technical debt and cleaning up code. Once things are polished, they find fewer new bugs are introduced because everyone is more careful.\n","experience":"mid","further_reading":[{"description":"Jeff Atwood's discussion of applying this theory to software","title":"The Broken Window Theory - Coding Horror","url":"https://blog.codinghorror.com/the-broken-window-theory/"},{"description":"The original criminological theory","title":"Broken Windows Theory - Wikipedia","url":"https://en.wikipedia.org/wiki/Broken_windows_theory"},{"description":"The book that popularized this concept in software engineering","title":"The Pragmatic Programmer","url":"https://amzn.to/4qygIq6"},{"description":"Practical application of the theory in software development","title":"Joy of Programming: The Broken Window Theory","url":"https://opensourceforu.com/2011/05/joy-of-programming-broken-window-theory/"}],"group":"Quality","image":"/images/laws/broken-window-theory.png","origins":"The Broken Windows Theory comes from criminology (James Q. Wilson and George Kelling, 1982). In software, Andy Hunt and Dave Thomas applied it as a metaphor in The Pragmatic Programmer (1999). They argued for fixing minor problems promptly.\n\nJeff Atwood and others in blogs have also discussed this principle in the context of software project maintenance.\n","overview":"The Broken Windows Theory in software was popularized by the book The Pragmatic Programmer. In a city, a broken window left unfixed signals neglect and invites more vandalism. Similarly in code, an apparent bug or messy section left untreated can lead to more developers bypassing the process or introducing more mess.\n\nThe idea is that quality problems snowball if left unaddressed. For example, if a team routinely ignores failing tests or lets linters/errors slide during builds, developers get the message that it's okay to ship sloppy work. This accelerates code decay (also known as software entropy).\n\nConversely, if a team quickly fixes minor issues and maintains high standards, it creates a culture of quality.\n","related":["technical-debt","boy-scout-rule","galls-law"],"slug":"broken-windows-theory","takeaways":["If you let minor bugs and bad style slide, people assume quality doesn't matter, and they'll ship messier code.","A clean, well-maintained codebase encourages engineers to keep it clean, whereas a chaotic codebase encourages corner-cutting and further degradation.","Fix problems while they're small. Refactor destructive code, update outdated docs, to prevent a downward spiral of code health."],"title":"Broken Windows Theory","url":"https://lawsofsoftwareengineering.com/laws/broken-windows-theory/"},{"description":"Technical Debt is everything that slows us down when developing software.","examples":"A typical example is skipping automated tests. A team under deadline pressure releases a new feature without writing tests. The release is successful (debt incurred). But later, making changes becomes harder since every change risks unforeseen bugs because there's no safety net of tests (interest payments). Eventually they must stop adding features and fix the debt by adding the missing tests and refactoring.\n\nAnother example is a startup that wants to deliver a quick prototyping effort to onboard the first customer. Developers do rapid but messy coding, with hardcoded variables and copy-and-paste code. This approach is made with technical debt in mind. The endeavor helps the startup win a customer; however, the customer's codebase is now full of technical debt.\n\nIf they just continue to add to it, they will face bugs and slower performance due to the messy code (interest on debt). They realize this and therefore set up a \"rehab\" sprint to refactor the code, thereby resolving the most troublesome bits.\n","experience":"junior","further_reading":[{"description":"Ward Cunningham's video explaining the original debt metaphor (OOPSLA 1992)","title":"Debt Metaphor - Ward Cunningham","url":"https://www.youtube.com/watch?v=pqeJFYwnkjE"},{"description":"Martin Fowler's comprehensive blog post on technical debt","title":"Technical Debt - Martin Fowler","url":"https://martinfowler.com/bliki/TechnicalDebt.html"},{"description":"Overview of the concept and its management strategies","title":"Technical Debt - Wikipedia","url":"https://en.wikipedia.org/wiki/Technical_debt"},{"description":"Forsgren, Humble, and Kim's research on how technical debt impacts software delivery","title":"Accelerate","url":"https://amzn.to/48Xugp3"}],"group":"Quality","image":"/images/laws/technical-debt.png","origins":"The term \"Technical Debt\" was coined by Ward Cunningham (one of the authors of the Agile Manifesto) at the OOPSLA conference in 1992. He first used the financial metaphor while working on a finance application to explain to his boss why the team needed time to refactor code.\n\nWard compared developing software to borrowing money: it can be wise to take shortcuts (borrow) to achieve something sooner, provided you pay back the loan by cleaning up the code later.\n","overview":"Technical debt highlights a fundamental tension in software engineering: speed vs. quality. The term helps explain to both developers and non-technical stakeholders why seemingly \"done\" software still needs ongoing work. When you write clumsy code or postpone cleanup, you've essentially taken out a loan: you get short-term feature delivery, but the complexity you introduce is the interest you'll keep paying.\n\nProperly managing technical debt means being conscious of when you're adding a quick workaround or a \"temporary\" hack, and having a plan to revisit it. Teams often use tools to log technical debt items (like comments, issue tracker tickets, or dedicated debt backlogs). \n\nWhen managed, technical debt can be an effective tool; you intentionally take on a bit of messiness to get feedback or meet a deadline, then clean it up. But if ignored, debt becomes a problem.\n","related":["broken-windows-theory","hofstadters-law","boy-scout-rule"],"slug":"technical-debt","takeaways":["When we take a shortcut in code, we borrow time from the future. This gives an immediate benefit, but you owe principal (the work to fix) plus interest.","If technical debt is not repaid, it accrues interest. Each minute spent on dirty code, bugs, and workarounds due to a lack of refactoring is interest on the debt.","Not all technical debt is inherently bad. It is sometimes necessary, for instance, for market timing or prototyping. ","The way to pay down technical debt is to refactor code, add missing tests, and improve design."],"title":"Technical Debt","url":"https://lawsofsoftwareengineering.com/laws/technical-debt/"},{"description":"Given enough eyeballs, all bugs are shallow.","examples":"Consider the Apache HTTP Server, an open-source web server used by millions. Because its code is open and it has a vast user base, many developers have at some point debugged or improved it. If there's a security flaw or bug, odds are high that someone in the global community will discover it and report it. The infamous \"Log4Shell\" vulnerability in the Log4j library was identified and patched by the community.\n\nIn contrast, consider an enterprise software product that is proprietary with only a few clients. If a subtle bug appears, only the vendor's small team and a few client implementers are likely to notice it. It might take a long time to surface and debug because of limited \"eyeballs.\"\n","experience":"mid","further_reading":[{"description":"Eric S. Raymond's influential essay on open-source development","title":"The Cathedral and the Bazaar","url":"https://amzn.to/49cYD9Y"},{"description":"Overview of the law and its implications","title":"Linus's Law - Wikipedia","url":"https://en.wikipedia.org/wiki/Linus%27s_law"},{"description":"Analysis of the law in context of real-world vulnerabilities","title":"With Enough Eyeballs, All Bugs Are Shallow - TechCrunch","url":"https://techcrunch.com/2012/02/23/with-many-eyeballs-all-bugs-are-shallow/"},{"description":"Academic study on the impacts of member differences on open source peer review","title":"Revisiting Linus's Law: Benefits and Challenges of OSS Peer Review","url":"https://www.sciencedirect.com/science/article/abs/pii/S1071581915000087"},{"description":"IEEE study examining software maintenance and the many-eyes hypothesis","title":"An Empirical Study of Build Maintenance Effort - IEEE","url":"https://www.computer.org/csdl/magazine/mi/2012/01/mmi2012010072/13rRUzphDuy"},{"description":"Russ Cox's detailed timeline of the xz backdoor, a striking counterexample to many-eyes review","title":"Timeline of the xz open source attack","url":"https://research.swtch.com/xz-timeline"}],"group":"Quality","image":"/images/laws/linus-law.png","origins":"The law is named after Linus Torvalds, the creator of Linux, but Eric S. Raymond formulated it in the late 1990s. In \"The Cathedral and the Bazaar\", Raymond writes: \"Given enough eyeballs, all bugs are shallow\" and calls this Linus's Law in honor of Torvalds' open development approach.\n\nThe idea was inspired by the Linux community, where hundreds of developers worldwide were debugging the kernel simultaneously. The essay was first presented in 1997 and published as a book in 1999.\n","overview":"Linux's open development model, releasing code early and often to the public, results in rapid bug-finding. When many people use and review a piece of software, problems become apparent to someone. \n\nWhat is a perplexing bug to you might be trivial to another programmer who spots it. Or among thousands of users, one will stumble on the exact reproduction steps, and another might submit a fix.\n\nThis law shows the core of open-source: that transparency and collaboration lead to more robust, reliable software. \n\nHowever, it's not absolute. Coordination and quality control are still needed. But as a guiding principle, Linus's Law captures the self-correcting nature of a large developer ecosystem. \n\nThe \"many eyeballs\" principle is also why internal code reviews and pair programming can be effective.\n","related":["brooks-law","sturgeons-law","bus-factor"],"slug":"linuss-law","takeaways":["Linus's Law highlights the strength of peer review and community in software development. If a codebase is accessible to many developers, someone will eventually have the expertise to identify and fix a given bug.","The rule is often cited as a key advantage of open-source software. When source code is widely available, you accumulate a large pool of contributors.","Linus's Law assumes those eyeballs are indeed looking, i.e., an active community. Simply being open-source doesn't magically fix bugs."],"title":"Linus's Law","url":"https://lawsofsoftwareengineering.com/laws/linuss-law/"},{"description":"Debugging is twice as hard as writing the code in the first place.","examples":"Imagine a developer writing a function in a compressed style, chaining multiple operations in one line:\n\n\u003cpre\u003e\u003ccode class=\"language-csharp\"\u003epublic string GetUserDisplay(User u) =\u003e\n     u?.IsActive == true ? (u.Name ?? \"\").Trim() is var n \u0026\u0026 n.Length \u003e 0\n     ? n + (u.Role \u003e 0 ? $\" ({(Role)u.Role})\" : \"\") : \"Unknown\" : \"Inactive\";\u003c/code\u003e\u003c/pre\u003e\n\nThe proper, readable version:\n\n\u003cpre\u003e\u003ccode class=\"language-csharp\"\u003epublic string GetUserDisplay(User user)\n{\n    if (user is null || !user.IsActive)\n        return \"Inactive\";\n\n    var name = user.Name?.Trim();\n\n    if (string.IsNullOrEmpty(name))\n        return \"Unknown\";\n\n    if (user.Role \u003e 0)\n        return $\"{name} ({(Role)user.Role})\";\n\n    return name;\n}\u003c/code\u003e\u003c/pre\u003e\n\nThe clever version might have taken 30 minutes to write, but debugging took 3 hours. Had the code been written clearly, it would've taken 45 minutes to write, but only 30 minutes to debug later.\n","experience":"junior","further_reading":[{"description":"The classic 'K\u0026R' book co-authored by Brian Kernighan","title":"The C Programming Language","url":"https://amzn.to/3YLSFYy"},{"description":"Kernighan and Plauger's guide to writing clear code","title":"The Elements of Programming Style","url":"https://www.amazon.com/Elements-Programming-Style-2nd/dp/0070342075"},{"description":"Steve McConnell's comprehensive guide to software construction","title":"Code Complete","url":"https://amzn.to/4smkSmE"}],"group":"Quality","image":"/images/laws/kernighan-law.png","origins":"Brian Kernighan first expressed this idea in *The Elements of Programming Style* (1974, second edition 1978) with P.J. Plauger. Kernighan, famous for co-authoring \"The C Programming Language\" and \"The Elements of Programming Style,\" wrote about simplicity in the days of resource-constrained computing.\n","overview":"Kernighan's Law says that debugging requires understanding what the code *actually* does, which can be twice as hard as writing it. When coding, you operate with a specific mental model and full context. When debugging, you might be dealing with someone else's code or your own code after that context has faded.\n\nWriting \"clever\" or complex code is essentially setting a trap for your future self. A maintainable version is usually superior to an optimized version that is difficult to understand. As Kernighan implies, if you make your code too tricky, you've essentially outsmarted yourself.\n","related":["kiss-principle","premature-optimization"],"slug":"kernighans-law","takeaways":["Bug detection and removal is more complex than programming because debugging requires understanding both the code and why it doesn't work.","If you write code at the limit of your intelligence, you won't be able to understand or troubleshoot it later.","Simple code with good structure and documentation is easier to debug, saving time in the long run.","Even if your code runs successfully when you write it, it's fragile if it's too complex."],"title":"Kernighan's Law","url":"https://lawsofsoftwareengineering.com/laws/kernighans-law/"},{"description":"A project should have many fast unit tests, fewer integration tests, and only a small number of UI tests.","examples":"Consider a web e-commerce application. Following the test pyramid, the team writes extensive unit tests for functions such as price calculation, discount logic, and validation (hundreds of unit tests). They also write API integration tests verifying that order placement connects inventory, payment, and notification services correctly (a few dozen tests). Finally, they have a few end-to-end tests simulating user journeys like browsing, adding to cart, and checkout.\n\nBecause they have so many unit tests, if something in business logic breaks, it's caught before end-to-end tests run. This approach takes little time in CI and allows confident deployments.\n\nNow consider a team that did not follow the pyramid. They have few unit tests and instead rely on 50 end-to-end GUI tests that run nightly for hours. They often find failing tests, but it's hard to tell if it's genuine bugs or test flakiness. Developers get feedback with a day's delay. This is the *anti-pattern* the pyramid warns against.\n","experience":"junior","further_reading":[{"description":"Martin Fowler's comprehensive guide to the test pyramid","title":"The Practical Test Pyramid","url":"https://martinfowler.com/articles/practical-test-pyramid.html"},{"description":"Mike Cohn's book where the Test Pyramid was popularized","title":"Succeeding with Agile","url":"https://amzn.to/4pb7Q8v"},{"description":"Overview of test automation at different levels","title":"Test Pyramid - Wikipedia","url":"https://en.wikipedia.org/wiki/Test_automation#Testing_at_different_levels"},{"description":"Titus Winters, Tom Manshreck \u0026 Hyrum Wright on Google's testing philosophy and practices","title":"Software Engineering at Google, Chapter 11: Testing Overview","url":"https://abseil.io/resources/swe-book/html/ch11.html"}],"group":"Quality","image":"/images/laws/testing-pyramid.png","origins":"Mike Cohn is credited with popularizing the Test Pyramid. He described it in his book *Succeeding with Agile* and blog posts around 2009, coining the term and concept.\n\nThe idea builds on earlier testing theory (such as test levels in the ISTQB foundation or the general practice in TDD of writing many unit tests). Modern discussions sometimes add layers or modify terms, but the core principle remains: **test more at the unit level than at the UI level**.\n","overview":"The pyramid is a visual metaphor: the largest level (at the bottom) is unit tests, which are fast and the most numerous. The middle layer is integration tests, fewer in number. The top is UI/end-to-end tests, the least numerous. As you go up, tests become more expensive in time, effort, and fragility, so you want proportionally fewer of them.\n\nBy following the pyramid, most bugs are caught at the cheapest level. If the pyramid is inverted (lots of end-to-end tests, few unit tests), the test suite tends to be slow and fragile.\n","related":["lehmans-laws"],"slug":"testing-pyramid","takeaways":["Unit testing is where you start. Unit tests are run as separate functions and execute quickly. That means you can afford to write lots of unit tests.","After the unit tests, there must be an integration test layer. These verify the integration of modules. You will require fewer integration tests than unit tests.","End-to-end tests at the top simulate real-world user scenarios. They are essential but slow and expensive to maintain.","Organizing tests this way, you receive quick feedback (most tests are quick unit tests), and when your UI test fails, there’s a better chance it’s due to a real problem"],"title":"Testing Pyramid","url":"https://lawsofsoftwareengineering.com/laws/testing-pyramid/"},{"description":"Repeatedly running the same tests becomes less effective over time.","examples":"Let's consider a mobile app where, in the first release, testers wrote extensive tests for the login and user profile features, finding and getting ten bugs fixed in those areas. In the subsequent releases, those test cases all pass (no new bugs in login or profile, great). Meanwhile, the app has added a messaging feature, but the test suite didn't add many cases for it. However, within a couple of releases, complaints started trickling in regarding the messaging functionality crashing. Unfortunately, the test suite failed to identify these because it was not updated to test messaging, which is predominantly centered on login and profile.\n\nThis is the pesticide paradox, which states that as testing became green (no defects remained in the code tested), new defects began to emerge, thereby requiring new tests. However, after the group includes their messaging tests, they begin to uncover these issues before they become releases. This process continues until those tests no longer find new issues, and the pattern repeats with the following features that emerge.\n","experience":"mid","further_reading":[{"description":"Boris Beizer's comprehensive book on testing techniques","title":"Software Testing Techniques","url":"https://amzn.to/3Yg3jH4"},{"description":"Official ISTQB syllabus covering the seven principles of testing","title":"ISTQB Foundation Level Syllabus","url":"https://www.istqb.org/certifications/certified-tester-foundation-level"},{"description":"Practical wisdom on software testing by Kaner, Bach, and Pettichord","title":"Lessons Learned in Software Testing","url":"https://amzn.to/3YNqIzD"}],"group":"Quality","image":"/images/laws/pesticide-paradox.png","origins":"The concept was articulated by Dr. Boris Beizer, a software testing expert, and became widely known as one of the \"seven principles of testing\" in ISTQB (International Software Testing Qualifications Board) materials.\n\nBeizer stated something to the effect of: every method of testing will yield a pesticide paradox, bugs adapt to tests, leaving more subtle bugs behind. \n","overview":"The \"Pesticide Paradox\" analogy comes from agriculture. When the same pesticide is used repeatedly, pests develop resistance to it. \n\nIn software, the first runs of a new test suite might find many bugs. Those bugs get fixed. If you keep running the same tests without changes, you won't find more bugs there. The software has become \"immune\" to those specific tests.\n\nThe testing process cannot be stagnant. Test cases must be maintained regularly. After every release cycle, testers should assess which bugs made it to production and enhance the test suite accordingly. \n\nThis paradox also argues for exploratory testing, where testers approach the application in new ways each iteration, uncovering problems a static regression suite would miss. The paradox doesn't mean regression testing is useless, as old tests catch regressions. But to catch *new* bugs, you must design *new* tests.\n","related":["lehmans-laws","testing-pyramid"],"slug":"pesticide-paradox","takeaways":["Over time, an outdated test suite will identify fewer bugs. The tests are still helpful, but no longer effective at detecting new defects.","This paradox illustrates the need to infuse new test data continuously. It is essential for testers not to become complacent with their test scripts, thinking that these alone will be sufficient in the future.","By periodically creating new tests (by altering existing ones), you effectively “refresh the pesticide,” thereby providing an opportunity to catch new bugs. This involves extending tests for new functionality, trying new input combinations, or perhaps just investigating new boundary cases."],"title":"Pesticide Paradox","url":"https://lawsofsoftwareengineering.com/laws/pesticide-paradox/"},{"description":"Software that reflects the real world must evolve, and that evolution has predictable limits.","examples":"Consider a big **enterprise resource planning (ERP) system** deployed in 2000. Over 25 years, updates included new business rules, integrations with new technologies, and UI refreshes. According to Law 1 (Continuing Change), this was necessary. If they hadn't continued updating, the system would no longer meet business needs. The company observes that adding functionality in 2025 takes longer than it did in 2005, reflecting Laws 2 and 7. Periodically, cleanup projects (refactoring) were needed, but output per year stabilized (Laws 4 and 5).\n\nThe **Linux kernel** provides another example. It has undergone continuous change, adapting to new hardware and requirements. If it stopped adapting, it would become irrelevant. Its functionality has grown massively, and complexity has increased, requiring subsystem maintainers. \n\nThe \"conservation of familiarity\" is seen in how changes are managed: big rewrites are rare, and maintainers enforce a pace the community can keep up with.\n","experience":"senior","further_reading":[{"description":"Lehman \u0026 Belady's original 1980 paper on software evolution","title":"Programs, Life Cycles, and Laws of Software Evolution","url":"https://ieeexplore.ieee.org/document/1456074"},{"description":"Lehman et al. 1997 update on the laws with additional research","title":"Laws of Software Evolution - The Nineties View","url":"https://ieeexplore.ieee.org/document/637156"},{"description":"Overview of how Lehman's Laws evolved over time","title":"The Evolution of the Laws of Software Evolution","url":"https://link.springer.com/chapter/10.1007/978-3-540-75381-0_1"}],"group":"Quality","image":"/images/laws/lehman-laws.png","origins":"Lehman's early laws were formulated in 1974, based on his study of various software, including IBM's OS/360. Lehman and Belady observed version histories, growth metrics, and other data, leading to the initial three laws.\n\nOver the years, Lehman refined the laws through the 1980s and 1990s as more projects provided data. Initially there were 3 laws (1974), then 5, and eventually 8 laws by the 1990s.\n","overview":"Lehman's Laws describe an unavoidable reality of long-lived software systems that operate in the real world. Such systems, business software, operating systems, and platforms, must continuously change to remain useful. That change is neither optional nor free.\n\nAs software evolves, complexity accumulates. Each change slightly increases internal disorder unless effort is spent counteracting it. Over time, this complexity reduces development speed, increases risk, and raises the cost of further change. Teams feel this as \"everything taking longer than it used to.\" \n\nOrganizations face hard limits: knowledge, coordination, and familiarity constrain how much change can be absorbed in a single release. Adding people does not remove these limits; it often reinforces them.\n","related":["brooks-law","conways-law","technical-debt"],"slug":"lehmans-laws","takeaways":["The first law, Continuing Change, states that if a system isn't continuously updated to meet new needs, it becomes less satisfactory to use. In practice, this means that successful software is never truly “finished”; to remain useful, it undergoes ongoing enhancements (or else users abandon it for something that keeps up).","Over time, changes accumulate, making the system more complex (Law 2). Unless developers invest in refactoring or restructuring (i.e., paying down technical debt), the system's internal complexity will increase, slowing further development.","Even if users demand more, a development organization can only do so much in a given time. They can't exponentially accelerate delivery forever. Factors such as team knowledge (familiarity) and process overhead limit it.","The perceived quality of the system will decline (perhaps due to rising user expectations, environmental changes, or the accumulation of minor issues). "],"title":"Lehman's Laws of Software Evolution","url":"https://lawsofsoftwareengineering.com/laws/lehmans-laws/"},{"description":"90% of everything is crap.","examples":"Consider an app with 100 features. User analytics might show that users heavily use 10 of these and the rest not at all, which is exactly what Sturgeon's Law predicts: 90% of this stuff doesn't provide significant value.\n\nAnother example is an organization may have many project ideas to develop each quarter. According to Sturgeon's Law, most of these ideas wouldn't amount to anything, but a few could be game-changers. \n\nIn the area of code reviews, a significant amount of code has been written that is neither elegant nor required. This supports the hypothesis that less code is high-quality.\n","experience":"junior","further_reading":[{"description":"Overview of the law and its origins","title":"Sturgeon's Law - Wikipedia","url":"https://en.wikipedia.org/wiki/Sturgeon%27s_law"},{"description":"Reddit discussion illustrating Sturgeon's Law in the WordPress plugin ecosystem","title":"Over 50% of plugins in the WordPress repository haven't been updated in 2+ years","url":"https://www.reddit.com/r/Wordpress/comments/1n0lnas/over_50_of_plugins_in_the_wordpress_repository/"}],"group":"Quality","image":"/images/laws/sturgeon-law.png","origins":"Theodore Sturgeon, a science fiction author, coined this phrase in 1957, responding to criticism that \"90% of science fiction is crap.\" His response: \"90% of everything is crap.\"\n\nIt was first published as \"Sturgeon's Revelation\" in a 1957 issue of Venture magazine.\n","overview":"In the tech sphere, Sturgeon's Law implies that most code or features are not necessary. Perhaps 90% of experiments or features don't pan out, and only 10% drive real value. \n\nAs an engineer, not every line of code you write is gold; as a product manager, many features don't delight users.\n\nIt pairs with the idea of the 10x engineer not as someone who writes 10x more code, but as someone who identifies the 10% of work that delivers 10x value. The risk isn't the lower quality of the 90%, it's the pretense that it isn't. When a team considers all work to have the same value, it introduces more complexity and slows down. \n\nIn practice, Sturgeon's Law encourages continuous refinement, assumes there's a lot of \"noise,\" and focuses on finding the \"signal.\"\n","related":["goodharts-law","galls-law"],"slug":"sturgeons-law","takeaways":["It’s like an extreme form of the Pareto Principle (80/20 rule). The bulk of what’s being put out just isn’t good, and the good stuff is the exception","In software, there are often many features or code paths that add very little value, and the critical challenge is to find a way to maximize the high-impact 10%.","Most new concepts or technologies fail to deliver, while the exceptional ones stand out."],"title":"Sturgeon's Law","url":"https://lawsofsoftwareengineering.com/laws/sturgeons-law/"},{"description":"The speedup from parallelization is limited by the fraction of work that cannot be parallelized.","examples":"Adding application servers doesn't help if all requests hit a single database instance. One database becomes the limit.\n\nAnother example is breaking a monolith into microservices won't improve performance if all requests ultimately serialize through a shared dependency, such as an authentication or billing service. \n","experience":"senior","further_reading":[{"description":"Gene Amdahl's original 1967 paper","title":"Validity of the Single Processor Approach to Achieving Large Scale Computing Capabilities","url":"https://dl.acm.org/doi/10.1145/1465482.1465560"},{"description":"Overview of the law with visual examples","title":"Amdahl's Law - Wikipedia","url":"https://en.wikipedia.org/wiki/Amdahl%27s_law"},{"description":"Fred Brooks' classic on software engineering and scaling","title":"The Mythical Man-Month","url":"https://amzn.to/3MUjDL7"}],"group":"Scale","image":"/images/laws/amdahl-law.png","origins":"Gene Amdahl, a computer architect known for his work on IBM mainframes, introduced the law in 1967 at the AFIPS Spring Joint Computer Conference.\n\nIt was originally framed around processor performance but has since proven universally applicable to systems and organizations.\n","overview":"As you add CPU cores, only the parallelizable fraction of your code speeds up. The sequential fraction remains unchanged and eventually dominates total execution time. If \"s\" is the sequential fraction, the maximum speedup with infinite parallel resources is 1/s. So if 10% is sequential, maximum speedup is 10x. If 50% is sequential, maximum speedup is only 2x.\n\nThis applies beyond hardware. If your system has a database that can't be parallelized, adding application servers hits a wall. The same holds for organizations: if one person or committee handles all architectural decisions, adding engineers increases coordination costs without increasing throughput.\n","related":["gustafsons-law","metcalfes-law"],"slug":"amdahls-law","takeaways":["Sequential work sets the ceiling, and no amount of parallelism can overcome it.","Scaling exposes bottlenecks. More resources make limits visible, not disappear.","Fix before you scale: reduce sequential paths first. Parallelism comes second.","It applies to people, too. Decision bottlenecks can dominate at the team scale."],"title":"Amdahl's Law","url":"https://lawsofsoftwareengineering.com/laws/amdahls-law/"},{"description":"It is possible to achieve significant speedup in parallel processing by increasing the problem size.","examples":"In high-performance computing, climate modeling or molecular simulations routinely increase model resolution when more processors are available. A weather simulation on 1000 CPUs won't just finish 1000x faster; instead, they run a far more detailed global model in the same time, yielding a better forecast.\n\nIn big data processing, if analyzing 1 million records takes an hour on one machine, a 10-machine cluster might analyze 10 million records in an hour instead of finishing in 6 minutes. \n\nModern distributed systems like MapReduce and Spark encourage splitting datasets into more partitions as nodes increase, keeping all processors busy.\n","experience":"senior","further_reading":[{"description":"John L. Gustafson's original 1988 paper","title":"Reevaluating Amdahl's Law","url":"https://dl.acm.org/doi/10.1145/42411.42415"},{"description":"Overview of the law and its relationship to Amdahl's Law","title":"Gustafson's Law - Wikipedia","url":"https://en.wikipedia.org/wiki/Gustafson%27s_law"}],"group":"Scale","image":"/images/laws/gustafson-law.png","origins":"Gustafson's Law was formulated by computer scientist John L. Gustafson (with Edwin Barsis) in 1988, in a paper titled \"Reevaluating Amdahl's Law.\" Gustafson was working at Sandia National Laboratories on high-performance computing.\n\nAt that time, Amdahl's 1967 result cast doubt on massively parallel supercomputers. Gustafson observed that this held only if workload was kept constant. His 1988 argument demonstrated that by increasing problem size, a 1024-processor system could achieve near-1024x speedup on suitably scaled tasks.\n","overview":"Gustafson's Law is a principle in parallel computing that offers an optimistic view of scalability. Where Amdahl's Law assumes a fixed problem size and concludes that speedup is limited by serial work, Gustafson's Law changes the perspective.\n\nIt observes that when more processors are available, developers tend to increase the problem size to use that extra power. If you have a cluster twice as powerful, you might process twice as much data in the same time. \n\nThe parallel portion of work grows with N processors while the serial portion remains about the same, leading to \"scaled speedup\" that can be almost linear. \n\nGustafson's insight is that developers naturally use more computing power by asking bigger questions.\n","related":["amdahls-law","metcalfes-law"],"slug":"gustafsons-law","takeaways":["As computing resources grow, you can compute more problems in a given time, rather than solving the same issues faster.","It opposes the pessimism of Amdahl's Law by assuming the size of the problem to be solved will increase proportionally with computing power, so that parallel processors remain busy.","Practically, Gustafson’s Law promotes the use of more resources in computation to achieve more in terms of the scope of tasks, rather than obtaining diminishing returns.","Software should be designed to scale out: as more cores or machines are added, the problem size grows and the extra capacity does useful work."],"title":"Gustafson's Law","url":"https://lawsofsoftwareengineering.com/laws/gustafsons-law/"},{"description":"The value of a network is proportional to the square of the number of users.","examples":"In social media, early Facebook had low utility if only a few friends were members. But as everyone you know joined, it became hugely valuable. The same holds for WhatsApp or WeChat: each new user can open chats with many others.\n\nMetcalfe’s Law can also work in reverse. If users start leaving a social network, the value drops faster than linearly. Each departure reduces the potential connections for all who remain, creating a “death spiral” where declining value accelerates further departures.\n","experience":"senior","further_reading":[{"description":"Analysis of the law's applications and limitations","title":"Metcalfe's Law: more misunderstood than wrong?","url":"https://blog.simeonov.com/2006/07/26/metcalfes-law-more-misunderstood-than-wrong/"},{"description":"Overview of the law and its history","title":"Metcalfe's Law - Wikipedia","url":"https://en.wikipedia.org/wiki/Metcalfe%27s_law"},{"description":"George Gilder's original Forbes ASAP article","title":"Metcalfe's Law and Legacy","url":"https://www.discovery.org/a/41/"},{"description":"Zhang, Liu \u0026 Xu (2015) - empirical validation of Metcalfe's Law using real social network data","title":"Tencent and Facebook Data Validate Metcalfe's Law","url":"https://doi.org/10.1007/s11390-015-1518-1"}],"group":"Scale","image":"/images/laws/metcalfe-law.png","origins":"Metcalfe's Law is named after Robert Metcalfe, who proposed the concept around 1980 while discussing Ethernet and network adoption. In 1983, he presented the idea to 3Com, arguing that network value grows as the square of compatible communicating devices.\n\nThe term \"Metcalfe's Law\" was popularized in a 1993 Forbes magazine article by George Gilder, who used Metcalfe's diagram to explain the rise of the Internet.\n","overview":"Metcalfe’s Law is an observation about communications networks that has been generalized to many technology ecosystems. It says that the value of a network is proportional to the square of the number of connected users. With 5 nodes, up to 10 pairwise connections are possible; with 12 nodes, 66.\n\nNetwork effects feed on themselves, a rich-get-richer phenomenon. Initially, adding one user might not change much. But later, adding the 10-millionth user potentially enables millions of new interactions. This creates winner-takes-all dynamics in tech. However, Metcalfe’s Law is a simplified model, as not every user connects with every other, and incremental value can diminish.\n","related":["amdahls-law","gustafsons-law"],"slug":"metcalfes-law","takeaways":["If you double the number of users, the potential connections roughly quadruple.","This law highlights the importance of network effects: each new user adds value to existing users by creating new opportunities for interaction. A product or platform becomes exponentially more useful as its user base grows.","This law helps explain why social media and messaging platforms can grow explosively in value once a tipping point is reached."],"title":"Metcalfe's Law","url":"https://lawsofsoftwareengineering.com/laws/metcalfes-law/"},{"description":"Every piece of knowledge must have a single, unambiguous, authoritative representation.","examples":"An application has a database connection URL in five different source files. If the database host changes, you'd have to edit all five places. The DRY approach keeps that URL in a single configuration variable that all modules read.\n\nIf two parts of an app both format dates the same way, create a single `formatDate()` utility function and call it from both places. Now if the date format needs to change, there's precisely one function to modify. \n\nLarge codebases benefit from DRY through shared libraries. If multiple applications need the same security logic, create a shared library instead of copying code across applications.\n","experience":"junior","further_reading":[{"description":"The original source of the DRY principle by Hunt and Thomas","title":"The Pragmatic Programmer, 20th Anniversary Edition","url":"https://amzn.to/4piJutH"},{"description":"Overview of the principle and related concepts","title":"DRY - Wikipedia","url":"https://en.wikipedia.org/wiki/Don%27t_repeat_yourself"},{"description":"Steve McConnell's guide covering code duplication and abstraction","title":"Code Complete","url":"https://amzn.to/3N57T8t"}],"group":"Design","image":"/images/laws/dry.png","origins":"The term \"DRY\" was coined in 1999 by Andy Hunt and Dave Thomas in their book The Pragmatic Programmer. They defined it as: \"Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.\"\n\nEven earlier, avoiding code duplication was part of structured programming and the Unix philosophy. In Extreme Programming, a similar idea was known as \"Once and Only Once.\" Hunt and Thomas gave it a catchy name and expanded its scope beyond just code to all information.\n","overview":"The idea of DRY is simple: each fact or piece of logic in your system should be expressed once and only once. If you find the same code, formula, or rule in multiple modules, you're violating DRY. Such repetition creates hidden maintenance cost. When the business rule changes, you must hunt down every duplicate instance.\n\nBy following DRY, developers strive for a single, unique implementation of any given behavior. This often means abstracting common code into a function or class, or consolidating configuration into a single file. \n\nDRY also applies to database schemas, tests, and documentation. \n\nHowever, remember that DRY is about duplicated intent, not just similar-looking code. Two pieces of code can look identical but serve different purposes in an application.\n","related":["solid-principles","law-of-demeter"],"slug":"dry-principle","takeaways":["The DRY principle is about avoiding duplication of knowledge in code. If the same idea or logic is in multiple places, it's a signal to refactor.","When requirements change, you should update logic in only one place. Repeated code increases the risk of inconsistencies and bugs (you might fix a bug in one copy and forget about the others).","Be careful to apply DRY wisely. It’s about knowledge repetition, not just duplication. Sometimes two pieces of code look alike but do different jobs; merging them could over-complicate things."],"title":"DRY (Don't Repeat Yourself)","url":"https://lawsofsoftwareengineering.com/laws/dry-principle/"},{"description":"Designs and systems should be as simple as possible.","examples":"A web application needs to generate reports. A KISS approach would use a simple script or existing library to query the database and output a CSV. A non-KISS approach would design a complete plug-in architecture \"just in case\" you need it more generically later. If requirements are small, the latter is overkill.\n\nWhen writing a function to parse a file, a KISS implementation uses simple logic: open the file, read line by line, split fields, handle errors. A complex approach might implement a fully generic parser-combinator framework. Unless you truly need that generality, the simpler approach will be easier to get right and maintain.\n\nMany experienced engineers advise: \"First make it work, then make it right, then make it fast (if needed).\"\n","experience":"junior","further_reading":[{"description":"John Ousterhout's book on managing complexity in software","title":"A Philosophy of Software Design","url":"https://amzn.to/3N1uR0f"},{"description":"Overview of the principle and its origins","title":"KISS Principle - Wikipedia","url":"https://en.wikipedia.org/wiki/KISS_principle"},{"description":"Steve McConnell's practical handbook emphasizing simplicity in code","title":"Code Complete","url":"https://amzn.to/3N57T8t"}],"group":"Design","image":"/images/laws/kiss.png","origins":"The phrase \"Keep It Simple, Stupid\" came from the U.S. military. It's attributed to Kelly Johnson, a lead engineer at Lockheed's Skunk Works in the 1960s. Johnson challenged his team: design an aircraft that could be repaired with basic tools by an average mechanic in the field.\n\nInfluential programmers such as Edsger Dijkstra and C.A.R. Hoare often discussed complexity. Hoare said, “There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.” \n\nThe KISS principle has since become a cornerstone of software engineering best practices.\n  \n","overview":"The KISS principle is a reminder that simplicity should be a key goal. If you can solve a problem with a 50-line script versus a complex 500-line solution, KISS favors the 50-line solution because each line of code has the potential to cause an error.\n\nWhy is simplicity so important? Software has to be understood by humans. A simple design is much easier to maintain: new team members can get up to speed faster, bugs are easier to localize, and modifications cause fewer ripple effects. \n\nThe KISS principle encourages developers to resist \"clever\" code that does too much at once, and to avoid architecting solutions that address future problems at the cost of current complexity.\n","related":["yagni","principle-of-least-astonishment","galls-law"],"slug":"kiss-principle","takeaways":["KISS primarily refers to avoiding complexity in solution designs. A solution that satisfies the requirement and is simple in design is better than a complex one.","Simple code is easier and faster to understand and debug. It’s even easier to understand and fix if you’re your own future self. Smarter code may look impressive at first, but it often masks problems.","The code solution should be as simple as possible. Anything that adds complexity unnecessarily is counter to the KISS Principle."],"title":"KISS (Keep It Simple, Stupid)","url":"https://lawsofsoftwareengineering.com/laws/kiss-principle/"},{"description":"Five main guidelines that enhance software design, making code more maintainable and scalable.","examples":"For the **Single Responsibility Principle**, consider a web application managing user accounts. An anti-SRP design might have a single `UserManager` class handling validation, database operations, sending emails, and logging. A better design separates these into `UserValidator`, `UserRepository`, `EmailService`, and a `UserRegistrationService` that orchestrates them. Each class has one focus, and if the email format changes, you only touch `EmailService`.\n\nFor the **Dependency Inversion Principle**, imagine a `NotificationService` that sends alerts. Without DIP, it directly uses `EmailSender` or `SMSSender`. With DIP, you define an `INotificationChannel` interface, and all senders implement it. The service depends only on the abstraction, making it easy to add new channels or swap in test doubles.\n","experience":"mid","further_reading":[{"description":"Robert C. Martin's foundational paper on OO design principles","title":"Design Principles and Design Patterns","url":"https://web.archive.org/web/20150906155800/http://www.objectmentor.com/resources/articles/Principles_and_Patterns.pdf"},{"description":"Uncle Bob's comprehensive book introducing SOLID principles","title":"Agile Software Development: Principles, Patterns, and Practices","url":"https://amzn.to/497oH7H"},{"description":"Robert C. Martin's guide to software architecture and design","title":"Clean Architecture","url":"https://amzn.to/4jeeN7k"},{"description":"Overview of all five principles with examples","title":"SOLID - Wikipedia","url":"https://en.wikipedia.org/wiki/SOLID"},{"description":"The Gang of Four's classic on OO patterns that complement SOLID","title":"Design Patterns: Elements of Reusable Object-Oriented Software","url":"https://amzn.to/3LnM5o6"}],"group":"Design","image":"/images/laws/solid.png","origins":"The five SOLID principles emerged over the years and were collected and popularized by Robert C. Martin (Uncle Bob). The acronym SOLID was coined around 2004 by Michael Feathers, who noticed the initial letters spelled out a catchy word.\n\nUncle Bob described SRP, OCP, LSP, ISP, and DIP in various articles from the late 1990s and early 2000s, including his \"Principles of Object-Oriented Design\" papers and his 2002 book Agile Software Development: Principles, Patterns, and Practices. These principles drew from earlier thinkers: OCP from Bertrand Meyer (1988), LSP from Barbara Liskov (1987), ISP from work at Xerox PARC, and DIP and SRP were Martin's formulations inspired by layering and cohesion practices.\n","overview":"The SOLID principles are five high-level guidelines for object-oriented design: **Single Responsibility** (one concern per class), **Open/Closed** (open for extension, closed for modification), **Liskov Substitution** (subclasses must be substitutable for their parent), **Interface Segregation** (no forced dependency on unused interfaces), and **Dependency Inversion** (depend on abstractions, not concretions).\n\nWhen applied together, these principles produce systems that are modular, extensible, and robust under change. Code becomes easier to test, refactor, and extend without breaking existing functionality.\n","related":["law-of-demeter","hyrums-law","law-of-leaky-abstractions","dry-principle","kiss-principle","yagni"],"slug":"solid-principles","takeaways":["Following SOLID leads to software that is easier to extend, test, and refactor without breaking existing functionality. Each principle addresses a different aspect of good OO design.","A class with a single responsibility (SRP) that depends on well-defined interfaces (ISP, DIP) and uses inheritance appropriately (LSP) and polymorphism for extensions (OCP) will likely be easy to maintain.","Changes to one part of the system won’t cascade into breakages elsewhere, because the code is loosely coupled and well-encapsulated.","SOLID does not guarantee a perfect design, but it provides proven guidelines for object-oriented programming."],"title":"SOLID Principles","url":"https://lawsofsoftwareengineering.com/laws/solid-principles/"},{"description":"An object should only interact with its immediate friends, not strangers.","examples":"Consider a `Presenter` object with a reference to a UI View containing a `TextField`. Without LoD, the presenter might do `view.getTextField().setText(\"Hello\")`. LoD encourages View to provide `setUserMessage(String)`, internally calling `textField.setText`. The Presenter doesn't need to know there's a TextField specifically. If later the View uses a Label instead, the Presenter code doesn't change.\n\nYou can identify violations by counting dots: `a.getB().getC().doSomething()` has two dots, one too many. A single dot `a.doSomething()` or at most `a.getB().doSomething()` is preferable. \n\nBy adhering to LoD, each component remains more self-contained, and systems become a network of \"friends\" rather than a tangle of strangers reaching through each other.\n","experience":"mid","further_reading":[{"description":"Original paper by Lieberherr, Holland, and Riel","title":"Object-Oriented Programming: An Objective Sense of Style","url":"https://www2.ccs.neu.edu/research/demeter/papers/law-of-demeter/oopsla88-law-of-demeter.pdf"},{"description":"Overview of the principle with examples","title":"Law of Demeter - Wikipedia","url":"https://en.wikipedia.org/wiki/Law_of_Demeter"},{"description":"Introduction paper by David Bock with the famous Paperboy example","title":"The Paperboy, The Wallet, and The Law Of Demeter","url":"https://www2.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf"},{"description":"The Gang of Four book with patterns that enforce loose coupling","title":"Design Patterns: Elements of Reusable Object-Oriented Software","url":"https://amzn.to/3LnM5o6"}],"group":"Design","image":"/images/laws/law-of-demeter.png","origins":"The Law of Demeter was first described around 1987 by Ian Holland and colleagues at Northeastern University as part of the Demeter Project on adaptive and aspect-oriented software development. It's named after the project, which itself was named after the Greek goddess of agriculture, signifying a \"growing\" approach to software.\n\nThe researchers, including Karl Lieberherr, sought ways to make software more maintainable and developed this style rule. They summarized it with the motto \"Only talk to your friends.\"\n","overview":"The Law of Demeter, also known as \"don't talk to strangers\" or the \"principle of least knowledge,\" was formulated to minimize the knowledge that any given object has about the overall system structure. \n\nIn practice, if object A has a reference to object B, and B has a reference to C, A should not call methods on C through B (like `a.b.getC().doSomething()`). A can talk to B, and B can talk to C, but A shouldn't directly get involved with C.\n\nThis fosters loose coupling. If you break LoD, your code assumes the structure extends beyond its immediate neighbors. For example, if `OrderProcessor` does `order.getCustomer().getAddress().getZipCode()`, it knows that an Order has a Customer with an Address. If Customer is changed to have multiple addresses, OrderProcessor breaks. If instead Order had a method `getShippingZip()` that internally navigates its customer/address, OrderProcessor could call that and be oblivious to structural changes. \n\nLoD aligns with information hiding: each object hides its internals and only exposes necessary interfaces.\n","related":["solid-principles","law-of-leaky-abstractions","hyrums-law","kiss-principle"],"slug":"law-of-demeter","takeaways":["An object should only call methods of: itself, its direct components, its function parameters, or objects it creates. It should not navigate through one object to reach another (“don’t talk to strangers”).","If object A only calls B (its immediate friend) and doesn’t reach into B’s internals (like C), then changes to C or removal of C don’t affect A. Each class knows as little as possible about others, reducing the impact of changes","It often leads to adding wrapper methods or delegations. While that might increase the number of methods, it results in cleaner interactions. "],"title":"Law of Demeter","url":"https://lawsofsoftwareengineering.com/laws/law-of-demeter/"},{"description":"Software and interfaces should behave in a way that least surprises users and other developers.","examples":"In software APIs, POLA means designing functions and behaviors that meet standard expectations. If you have a method `deleteFile()`, one would expect it to remove the file. It should not secretly archive it or throw an error if the file doesn't exist. \n\nIf your method works similarly to a well-known one in another library, keep naming and behavior aligned. A `toString()` method should return human-readable text, not a binary blob.\n\nPOLA also covers error handling and defaults. Sensible defaults cause the least surprise. For developers, code surprises are equally problematic. If a function `parseDate(str)` internally modifies a global date format setting, that's surprising. \n\nFollowing standard naming conventions matters: a variable named `isReady` should be boolean, a function named `compute` should return something rather than modify global state. \n\nA delighted user or developer uses something and it \"just works\" as expected.\n","experience":"mid","further_reading":[{"description":"Eric S. Raymond's book including the Rule of Least Surprise","title":"The Art of Unix Programming","url":"https://amzn.to/4q4uTTY"},{"description":"Joshua Bloch's talk on API design principles","title":"How to Design a Good API and Why it Matters","url":"https://www.youtube.com/watch?v=aAb7hSCtvGw"},{"description":"Overview of the principle with history and examples","title":"Principle of Least Astonishment - Wikipedia","url":"https://en.wikipedia.org/wiki/Principle_of_least_astonishment"}],"group":"Design","image":"/images/laws/principle-of-least-astonishment.png","origins":"The concept of least astonishment has roots in early human-computer interaction. An early mention appears in PL/I programming language documentation around 1967, complaining that certain behaviors violated the \"law of least astonishment.\"\n\nThe principle was explicitly stated in a 1972 publication on programming language design, recommending that language constructs behave as their syntax suggests and follow widely accepted conventions. \n\nSince then, it has been emphasized across various domains. In the Unix community, Eric Raymond's Art of Unix Programming references it as the \"Rule of Least Surprise.\"\n","overview":"The Principle of Least Astonishment (POLA) is a general design principle in user interface design, software API design, coding, and documentation. The idea is simple: don't surprise the user. \n\nThe system should behave in a way that matches the user's mental model of how it ought to work. Violating this principle doesn't necessarily break functionality, but it breaks trust and ease of use.\n\nIn coding, this principle states that your code should behave as the developer expects when name, type, and context are taken into account. We should choose defaults and behaviors that match standard conventions and avoid “surprise” side effects.\n","related":["hyrums-law","kiss-principle","postels-law","law-of-demeter"],"slug":"principle-of-least-astonishment","takeaways":["Design decisions should align with user expectations. When someone uses a component (a UI element, API, etc.), its behavior should not be surprising or counterintuitive.","Following platform norms or standard conventions yields the least astonishment.","In practice, it improves usability and developer experience. Users can predict how to interact with the software, and developers can predict how to use an API by analogy with similar ones. Surprises often lead to mistakes."],"title":"Principle of Least Astonishment","url":"https://lawsofsoftwareengineering.com/laws/principle-of-least-astonishment/"},{"description":"The less you know about something, the more confident you tend to be.","examples":"New developers often give confident, precise estimates, while experienced developers give ranges (the famous \"it depends\" answer). The juniors aren't wrong to be convinced; they simply don't yet know what they don't know (unknown-unknowns).\n\nPeak enthusiasm for a new technology often comes from those who have used it least. Those with deep experience are more measured. \n\nWe should also note that *Impostor syndrome* reflects miscalibration in the opposite direction. Skilled individuals underestimate their competence because they are deeply aware of complexity and edge cases.\n","experience":"junior","further_reading":[{"description":"Comprehensive overview of the cognitive bias and its research","title":"Dunning-Kruger Effect - Wikipedia","url":"https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect"},{"description":"The original study by Kruger and Dunning in the Journal of Personality and Social Psychology","title":"Unskilled and Unaware of It - Original 1999 Paper","url":"https://psycnet.apa.org/doi/10.1037/0022-3514.77.6.1121"},{"description":"David Dunning's accessible article in Pacific Standard explaining the effect","title":"We Are All Confident Idiots - David Dunning","url":"https://psmag.com/social-justice/confident-idiots-92793"},{"description":"Daniel Kahneman's seminal book on cognitive biases and decision-making","title":"Thinking, Fast and Slow","url":"https://amzn.to/48WboH0"}],"group":"Decisions","image":"/images/laws/dunning-kruger-effect.png","origins":"The effect was described by psychologists **David Dunning** and **Justin Kruger** in a 1999 study at Cornell University. Their experiments showed that people with low performance consistently overestimated their ability on logic, grammar, and humor tests, while high performers underestimated their ability.\n\nThe proposed mechanism is simple: the skills required to perform well are often the same skills needed to assess performance accurately.\n","overview":"The Dunning-Kruger Effect explains a gap between confidence and competence. When people know little about a domain, they lack the awareness required to judge their own ability. As a result, they overestimate how well they understand the problem.\n\nAs learning progresses, people discover the depth and complexity of the domain. \n\nAwareness of unknowns grows faster than capability, leading to a drop in confidence, often called the \"valley of despair.\" Only after experience does confidence rise again, now with fundamental understanding.\n","related":["brooks-law","hanlons-razor"],"slug":"dunning-kruger-effect","takeaways":["Confidence without context is unreliable. Early confidence often signals ignorance, not mastery.","Awareness grows faster than skill. Learning initially reduces confidence, only to rebuild it.","Real experts speak in ranges, trade-offs, and probabilities, not with confidence about every topic."],"title":"Dunning-Kruger Effect","url":"https://lawsofsoftwareengineering.com/laws/dunning-kruger-effect/"},{"description":"Never attribute to malice that which is adequately explained by stupidity or carelessness.","examples":"A customer reports that your software \"deleted all my data!\" It's easy to panic and think a disgruntled employee planted a logic bomb. But Hanlon's Razor would have you first check for a mundane bug, perhaps a boundary condition in a delete function that wipes more than intended. Indeed, you find a bug where, when a user's account name was empty, the cleanup script deleted all records. No malice, just a bug.\n\nIn security, consider a sudden spike in server traffic. Before screaming \"it's a DDoS attack!\", check first if it's a misconfigured client spamming or a known pattern. Most weird behaviors in systems are due to mistakes, not malicious intent.\n","experience":"junior","further_reading":[{"description":"Overview of the principle and its origins","title":"Hanlon's Razor - Wikipedia","url":"https://en.wikipedia.org/wiki/Hanlon%27s_razor"},{"description":"How Etsy applies blameless culture in incident response","title":"Blameless Postmortems - Etsy","url":"https://www.etsy.com/codeascraft/blameless-postmortems/"},{"description":"Sidney Dekker's book on human factors in system failures","title":"The Field Guide to Understanding Human Error","url":"https://amzn.to/3LbyIas"}],"group":"Decisions","image":"/images/laws/hanlons-razor.png","origins":"**Robert J. Hanlon** submitted this principle to a 1980 compilation of Murphy's Law variations. It echoes similar statements by Napoleon and Goethe about not attributing malice where incompetence can explain it.\n","overview":"Hanlon's Razor advises against assuming bad faith when an outcome may be due to human error or ignorance. If a commit introduces a security hole, it's probably a mistake, not intentional sabotage. So one responds with help and fixes, not with blame.\n\nThis doesn't mean ignoring the possibility of malice when truly warranted (security does consider malicious actors). But for day-to-day development and operations, Hanlon's Razor keeps you grounded: the build failed likely due to a misconfiguration, not because someone deliberately broke it.\n","related":["occams-razor","goodharts-law","postels-law"],"slug":"hanlons-razor","takeaways":["When something goes wrong, it's likely not malicious but rather an error or misunderstanding.","Don't jump to “the system is hacked” or “someone intentionally broke this.” First, consider simpler explanations (e.g., a configuration file was missed or a typographical error).","If a colleague's code is problematic, it's probably not sabotage. It may be due to being rushed or unaware of something. Try to approach with questions, not accusations."],"title":"Hanlon's Razor","url":"https://lawsofsoftwareengineering.com/laws/hanlons-razor/"},{"description":"The simplest explanation is often the most accurate one.","examples":"A classic example of applying Occam's Razor while debugging is that of the broken build. Let's assume that your build system has failed. A complex thinker might think that there is some subtle regression in the compiler code, or maybe some dependency is damaged. An Occam's Razor thinker would start with simpler explanations: a typo, a missing semicolon, or a misconfiguration.\n\nA saying often attributed to Einstein goes, \"Everything should be made as simple as possible, but not simpler,\" which best applies to this law in engineering.\n","experience":"junior","further_reading":[{"description":"Elliott Sober's comprehensive analysis of parsimony in science","title":"Ockham's Razors: A User's Manual","url":"https://amzn.to/4jfnRZX"},{"description":"Peter Lipton's exploration of explanatory reasoning and simplicity","title":"Inference to the Best Explanation","url":"https://www.routledge.com/Inference-to-the-Best-Explanation/Lipton/p/book/9780415242028"},{"description":"In-depth philosophical analysis of Occam's Razor and parsimony principles","title":"Simplicity (Stanford Encyclopedia of Philosophy)","url":"https://plato.stanford.edu/entries/simplicity/"},{"description":"Fred Brooks on accidental vs essential complexity in software","title":"No Silver Bullet","url":"https://en.wikipedia.org/wiki/No_Silver_Bullet"}],"group":"Decisions","image":"/images/laws/occams-razor.png","origins":"Occam's Razor dates back to William of Ockham, a philosopher from 14th-century England. His original version in Latin, \"Pluralitas non est ponenda sine necessitate,\" can be translated to \"plurality should not be posited without necessity,\" or \"Don't multiply entities or assumptions beyond what's required.\"\n\nOver time, Occam's Razor has evolved as a cornerstone of scientific methodology and logical reasoning.\n","overview":"Occam's Razor is a problem-solving principle that reminds us that when we have multiple possible solutions, the simplest one is preferred. \n\nIn software, this principle supports the KISS (\"Keep It Simple, Stupid\") approach. When we decide to keep our implementations simple, we reduce the risk of further complications.\n\nFor example, if a software architecture can achieve its goals with a monolith and one database, there is no need to split it into five microservices and two databases. These extra components would only introduce complexity and potential integration and coordination issues, but no benefits. \n\nThis is a reminder to avoid the temptation of over-engineering and keep things simple.\n","related":["kiss-principle","yagni","galls-law"],"slug":"occams-razor","takeaways":["Simple code is easier to understand, maintain, and debug, whereas complex code has more potential points of failure. Remove or avoid unnecessary moving parts in system architecture.","When debugging, start with the simplest explanation before jumping into complex theories.","Adding more features to the app can only complicate a product without adding real value. Occam’s Razor reminds us that less is more in many cases."],"title":"Occam's Razor","url":"https://lawsofsoftwareengineering.com/laws/occams-razor/"},{"description":"Sticking with a choice because you've invested time or energy in it, even when walking away helps you.","examples":"Consider a company that spent two years building a custom in-house CMS, only to find it's buggy and team productivity is low. An objective analysis might show it's better to adopt an off-the-shelf CMS. Yet the engineering leadership hesitates: \"We invested two years in this; abandoning it means that time was wasted!\" If they persist solely for that reason, they fall for the sunk cost fallacy.\n\nA positive example is Google, known for periodically killing off underperforming products (the [Google Graveyard](https://killedbygoogle.com/)). This practice means companies don't need to move forward with bad decisions once it's clear an initiative isn't working.\n\nTeams that conduct pre-mortems or use agile sprints to reassess work frequently are better at avoiding sunk-cost traps.\n","experience":"mid","further_reading":[{"description":"Arkes \u0026 Blumer's 1985 foundational paper on sunk cost psychology","title":"The Psychology of Sunk Cost","url":"https://www.sciencedirect.com/science/article/abs/pii/0749597885900494"},{"description":"Comprehensive overview with examples from behavioral science perspective","title":"The Sunk Cost Fallacy","url":"https://thedecisionlab.com/biases/the-sunk-cost-fallacy"},{"description":"Daniel Kahneman's seminal book covering cognitive biases including sunk costs","title":"Thinking, Fast and Slow","url":"https://amzn.to/4sfXfMr"}],"group":"Decisions","image":"/images/laws/sunk-cost-fallacy.png","origins":"The concept of sunk costs comes from economics. The term \"sunk cost fallacy\" was popularized by behavioral economists and psychologists in the late 20th century. Nobel laureates Daniel Kahneman and Amos Tversky studied this and related decision biases in the 1970s.\n\nBehavioral economist Richard Thaler officially coined the term \"sunk cost fallacy\" around 1980.\n","overview":"The sunk cost fallacy is a cognitive bias that challenges our decision-making. Humans irrationally value what they've already invested, whether money, time, or effort, even when those investments can't be recovered. \n\nIn software development, teams often continue working on a feature or product without making progress simply because \"we have come this far.\"\n\nUnderstanding this fallacy allows engineers and managers to make more rational choices: past costs should be ignored when deciding the future. Instead, consider current facts and future benefits. \n\nIf a rewrite or switch to a third-party solution will clearly save time and money from this point forward, do that, regardless of how much was sunk into the old approach. \n\nOvercoming sunk-cost bias is tough because it requires admitting past efforts were in vain, but in technology it's crucial to learn to let go when evidence demands.\n","related":["occams-razor","technical-debt","second-system-effect"],"slug":"sunk-cost-fallacy","takeaways":["Don't stay stuck based on past investments. The fact that 'we've invested a year already' is not an excuse to continue if it's clearly not working.","Healthy engineering organizations pivot or stop projects that no longer make sense. Continuing a bad project just because of sunk costs usually leads to greater loss.","Use clear measures and decision points: 'If we don't meet target X by end of quarter, we'll re-evaluate or discontinue.'","Teams should feel safe admitting a project isn't working without fear of blame."],"title":"Sunk Cost Fallacy","url":"https://lawsofsoftwareengineering.com/laws/sunk-cost-fallacy/"},{"description":"Our representations of reality are not the same as reality itself.","examples":"Consider designing a microservice system where Service A communicates with Services B and C via Kafka topics. The diagram assumed \"the network is reliable\" or \"latency is negligible,\" but in cloud infrastructure reality, those assumptions fall apart. The team updates the design to include retry mechanisms or schema validation.\n\nIn performance modeling, an engineer might model a database handling 10,000 queries per second based on specs. In production, due to specific query patterns and data distribution, it only achieves 5,000 qps. The model didn't account for query plan edge cases. \n\nThe Agile methodology itself embodies \"map vs territory\" thinking: instead of detailed 2-year plans, Agile uses short iterations with continuous feedback from reality to correct its maps.\n","experience":"mid","further_reading":[{"description":"Alfred Korzybski's foundational work on general semantics","title":"Science and Sanity","url":"https://www.holybooks.com/wp-content/uploads/Science-and-Sanity.pdf"},{"description":"Gregory Bateson's collected essays on anthropology, psychiatry, and epistemology","title":"Steps to an Ecology of Mind","url":"https://www.press.uchicago.edu/ucp/books/book/chicago/S/bo3620295.html"}],"group":"Decisions","image":"/images/laws/map-is-not-territory.png","origins":"The phrase was popularized in \"Science and Sanity\" (1933) by Alfred Korzybski, a Polish-American scholar. Korzybski highlighted how our language and knowledge mislead us into believing our constructs actually represent reality.\n","overview":"\"The Map Is Not the Territory\" is a mental model originating from general semantics. It encapsulates the idea that our perceptions or conceptual models of things are not the things themselves. \n\nIn software, we constantly create \"maps\": requirements documents map user needs, architecture diagrams map how components should interact, and our mental understanding of a codebase is a personal map of how we think the code works.\n\nThese maps are useful and necessary. Without them, we couldn't plan or reason about complex systems. However, problems arise when we forget the map's limits.\n\nA typical example is overconfidence in initial design: a team designs a system on paper, but when coding begins, they discover modules cannot communicate due to latency issues not captured in their assumptions.\n\nAs statistician George Box said, \"All models are wrong, but some are useful.\"\n","related":["goodharts-law","galls-law","law-of-leaky-abstractions"],"slug":"map-is-not-the-territory","takeaways":["Design docs, UML diagrams, and architecture schematics are abstractions. Don't confuse the blueprint with the actual running software.","When implementing a system, expect that unforeseen factors will emerge that weren’t captured in the initial designs. Be prepared to adapt the plan as you discover new “terrain” during development and testing.","Models and designs are valuable for guiding development, but always be willing to question assumptions when evidence from the real system contradicts them."],"title":"The Map Is Not the Territory","url":"https://lawsofsoftwareengineering.com/laws/map-is-not-the-territory/"},{"description":"A tendency to favor information that supports our existing beliefs or ideas.","examples":"In code reviews, a reviewer who trusts a colleague's skills might skim over potential issues, assuming the code is probably fine. Or the opposite: a reviewer expecting sloppy code from a junior developer might find \"issues\" that aren't really important.\n\nConfirmation bias also affects testing. A developer may write unit tests that assert the code works on typical inputs (happy path), but might not try edge cases that could break it. Teams combat this through code reviews with fresh eyes, writing tests specifically aimed at breaking their own code, and post-mortems asking \"What went wrong and why didn't we see it?\"\n\nBy checking for confirmation bias, engineers can become better at solving problems with an open and critical mind.\n","experience":"mid","further_reading":[{"description":"Raymond Nickerson's comprehensive 1998 review of confirmation bias research","title":"Confirmation Bias: A Ubiquitous Phenomenon in Many Guises","url":"https://journals.sagepub.com/doi/10.1037/1089-2680.2.2.175"},{"description":"Peter Wason's 1960 foundational paper on the rule discovery task","title":"On the Failure to Eliminate Hypotheses in a Conceptual Task","url":"https://www.tandfonline.com/doi/abs/10.1080/17470216008416717"},{"description":"Daniel Kahneman's exploration of cognitive biases including confirmation bias","title":"Thinking, Fast and Slow","url":"https://amzn.to/48WboH0"}],"group":"Decisions","image":"/images/laws/confirmation-bias.png","origins":"One of the first to identify confirmation bias was Peter Cathcart Wason, an English cognitive psychologist. In 1960, he conducted a famous experiment (Wason's rule discovery task) where participants had to guess a rule for a sequence of numbers. He found people tended to test sequences that would confirm their initial thoughts rather than those that could prove them wrong.\n\nWason coined the term \"confirmation bias\" to explain this phenomenon. Since then, countless studies have confirmed the existence of confirmation bias in human reasoning.\n","overview":"We all like to be right. Confirmation bias is our mind's way of cheating to feel right more often. Psychologically, once we form an opinion, we subconsciously filter information, noticing bits that support our view and ignoring those that contradict it.\n\nIn software, a typical scenario is debugging. A developer convinced that module A caused a production issue will comb through module A's code intensively. If module B (assumed to be fine) is also throwing errors, they might not even look there, missing the real cause. Awareness of this bias leads to asking \"What am I missing? Maybe there is another explanation?\" and encouraging environments where beliefs are constructively questioned.\n","related":["dunning-kruger-effect","hanlons-razor","goodharts-law"],"slug":"confirmation-bias","takeaways":["When reviewing code or debugging, notice if you're only looking for evidence that supports your initial hunch.","Challenge yourself when actively thinking about problems. If you have an opinion about an issue, try to ask, “What would I expect to see if I’m wrong?” In this, we can counteract our natural bias only to confirm.","Regarding team decision-making (for example, tech stacks and/or design decisions), seek input from people with differing opinions. Bias confirmation can be overcome by looking into alternative solutions. For example, if the whole team “feels” that technology X is the superior choice, assign someone to look into the opposing view on technology X.","Base decision-making on objective criteria (facts, not opinions). Automated tests, performance criteria, and experimentation (A/B tests) can provide truths regardless of human bias."],"title":"Confirmation Bias","url":"https://lawsofsoftwareengineering.com/laws/confirmation-bias/"},{"description":"We tend to overestimate the effect of a technology in the short run and underestimate the impact in the long run.","examples":"AI saw its first big hype wave in the 1960s-70s, when people assumed general AI was just around the corner. When grand promises didn't materialize, an \"AI winter\" set in and many abandoned AI as theoretical. But over decades, steady progress continued, and today AI techniques are transforming industries from healthcare to generative AI in software.\n\nMicroservices architecture was hyped as the cure for all scaling issues. Many teams hit the trough of disillusionment when they encountered complexity of managing hundreds of services. Now, a more balanced use of microservices is emerging, delivering benefits in the right situations.\n","experience":"mid","further_reading":[{"description":"Gartner's official explanation of the Hype Cycle methodology","title":"Gartner Hype Cycle","url":"https://www.gartner.com/en/research/methodologies/gartner-hype-cycle"},{"description":"The organization Roy Amara led, focused on futures thinking and foresight","title":"Institute for the Future","url":"https://www.iftf.org/"}],"group":"Decisions","image":"/images/laws/gartner-cycle.png","origins":"Amara's Law is named after Roy Amara, an American researcher and futurist who was president of the Institute for the Future. Amara was an American scientist who began his career as a Navy electronics technician during World War II.\n\nIn 1995, the Gartner Hype Cycle framework was introduced by Gartner analyst Jackie Fenn, who noticed a recurring pattern in the maturity of emerging technologies and created a visual graph to describe it.\n","overview":"This law describes the familiar boom-and-bust hype cycle in tech. Gartner's Hype Cycle captures the pattern: a new technology triggers inflated expectations, hits a trough of disillusionment when reality falls short, then gradually climbs a slope of enlightenment toward productive mainstream adoption.\n\nIn software engineering, many buzzword technologies are initially promoted as game-changers but decline when they cannot deliver promised results. However, after that reality check, some quietly mature and find real usability. The lesson is to have healthy skepticism during hype, but keep an open mind for long-term adoption.\n","related":["goodharts-law","galls-law","second-system-effect"],"slug":"hype-cycle-amaras-law","takeaways":["Early on, people overestimate what tech can do in the near term, leading to unrealistic expectations.","In the longer run, the same technology’s true potential emerges, often greater than initially imagined. Amara’s Law reminds us that we tend to underestimate the long-term impact of a significant innovation.","For developers and tech leaders, this means not getting swept up in the hype cycle. Be patient and evaluate new tools by their proven value, not just the buzz.","Treat innovation as a limited budget. Good teams use stable, proven tech for most needs and adopt a hyped new technology only when it truly addresses a real problem."],"title":"The Hype Cycle \u0026 Amara's Law","url":"https://lawsofsoftwareengineering.com/laws/hype-cycle-amaras-law/"},{"description":"The longer something has been in use, the more likely it is to continue being used.","examples":"COBOL is a language from 1959, over 60 years old, yet it still runs a large amount of the world's finance and government infrastructure. Some estimates suggest 70-80% of all global financial transactions rely on COBOL code in banking systems and mainframes.\n\nMany JavaScript frameworks like AngularJS, Ember.js, and Knockout.js emerged and fell out of favor over the past decade. Yet the underlying language and browser APIs have been around for over 25 years and will continue. \n\nIf choosing between learning a cutting-edge framework and SQL, the Lindy approach suggests SQL (from the 1970s) is still highly relevant today and will remain so. \n","experience":"mid","further_reading":[{"description":"Nassim Nicholas Taleb's book that popularized the Lindy Effect concept","title":"Antifragile: Things That Gain from Disorder","url":"https://amzn.to/4bc1Ust"},{"description":"Taleb's essay exploring the Lindy Effect in depth","title":"An Expert Called Lindy","url":"https://medium.com/incerto/an-expert-called-lindy-fdb30f146eaf"}],"group":"Decisions","image":"/images/laws/the-lindy-effect.jpg","origins":"The term was coined in 1964 by journalist Albert Goldman, named after Lindy's Delicatessen in New York City, a famous hangout for entertainers. Comedians there observed that a Broadway show's longevity predicted its future run length: if a show had lasted X weeks, it could be expected to run another X weeks.\n\nNassim Nicholas Taleb brought it to a broad audience in his books \"The Black Swan\" (2007) and \"Antifragile\" (2012), giving it the name \"Lindy Effect\" to describe the aging of non-perishable things like books, ideas, technologies, or traditions.\n","overview":"The Lindy Effect turns our intuition about aging on its head. For living creatures, older means less life expectancy. But in technology, it's often the opposite: the longer something has been in use, the more likely it is to continue being used. \n\nTime acts as a filter. Anything irrelevant, flawed, or fragile tends to disappear, while what remains after many years is usually high-quality and valuable.\n\nThis principle serves as a reality check against shiny object syndrome. The majority of so-called \"innovations\" have little to no relevance to contemporary ideas; rather, they reinvent ideas of the past. Truly fundamental ideas in software (algorithms, data structures, protocols, paradigms) change slowly. \n\nApplying Lindy's law means favoring things that have \"stood the test of time\" and learning languages like Python, Java, or C, as well as algorithms, rather than over-focusing on the hottest new framework.\n","related":["hyrums-law","postels-law","hype-cycle-amaras-law"],"slug":"lindy-effect","takeaways":["The Lindy Effect states that if something (a technology, tool, concept) has persisted for a long time, it will likely continue for much longer.","For developers, Lindy’s law is a reminder to invest in timeless skills and proven fundamentals (algorithms, core languages, design principles) rather than chasing every new framework that might be obsolete in a few years.","Use the Lindy Effect when evaluating technology. Things that have been around for some time stick around longer in the future (i.e., choose boring technology)."],"title":"The Lindy Effect","url":"https://lawsofsoftwareengineering.com/laws/lindy-effect/"},{"description":"Breaking a complex problem into its most basic blocks and then building up from there.","examples":"Before SpaceX, launching rockets was costly because industry practice used expensive materials and discarded rockets after one use. Elon Musk applied first-principles thinking: What is a rocket made of? Mainly aluminum, titanium, copper, and carbon fiber. Raw material costs were a fraction of finished rocket prices. From that insight, SpaceX decided to build rockets from scratch and make them reusable.\n\nIn software, consider a company paying licensing fees for a proprietary analytics platform. An engineer challenged this by examining what the platform actually does: ingest data, run statistical computations, generate reports. These could be implemented using open-source software and custom programming. A proof-of-concept in Python showed 90% of the solution at a fraction of the cost.\n","experience":"mid","further_reading":[{"description":"Farnam Street's comprehensive guide to first principles thinking","title":"First Principles: The Building Blocks of True Knowledge","url":"https://fs.blog/first-principles/"},{"description":"Stanford Encyclopedia of Philosophy on Aristotle's foundational logic","title":"Posterior Analytics - Aristotle","url":"https://plato.stanford.edu/entries/aristotle-logic/"},{"description":"Classic book on mathematical problem-solving and heuristics","title":"How to Solve It - George Pólya","url":"https://amzn.to/4b9q3Qo"}],"group":"Decisions","image":"/images/laws/first-principles-thinking.png","origins":"The term \"first principles\" has roots in classical philosophy. Aristotle referred to first principles as foundational propositions that cannot be deduced from anything else, the bedrock of knowledge. René Descartes emphasized starting from fundamental truths (\"I think, therefore I am\").\n\nIn modern times, first-principles thinking gained fame through Elon Musk, who credits it for SpaceX and Tesla innovations. Instead of thinking \"rockets are expensive,\" he broke down raw material costs and realized building in-house was viable.\n","overview":"First-principles thinking solves problems by questioning existing solutions rather than blindly copying them. Instead of \"We'll do X because that other project did X,\" ask: \"What are we really trying to accomplish? What are constraints versus assumptions?\" This approach is good for incremental improvements but essential for fundamental changes.\n\nIn software design, first principles challenge how current systems work: \"If we started from scratch today, how would we build this?\" This thinking led to microservices (questioning the monolith) and serverless computing (questioning server management). The drawback is that it is mentally intensive and not always necessary. Many problems are well-solved by known patterns.\n","related":["occams-razor","kiss-principle","galls-law"],"slug":"first-principles-thinking","takeaways":["Do not accept the problem as it is. Break the problem down into its inherent parts and then question your assumptions: Are they really true, or are they just accepted standards? Once you grasp the underlying requirements, you may develop new solutions.","Just because “everyone uses Framework Y for this” isn’t a reason you should do so. First principles thinking pushes you to ask why people do certain things the way they do.","Rather than saying, “This feature will take 3 months because that’s how long similar features took,” break the feature down. Estimate from the basics, which can sometimes show that the “similar” feature had additional issues that you may not have anymore. "],"title":"First Principles Thinking","url":"https://lawsofsoftwareengineering.com/laws/first-principles-thinking/"},{"description":"Solving a problem by considering the opposite outcome and working backward from it.","examples":"**Netflix's Chaos Monkey** is a prime example. Usually, engineers try to keep systems running. Chaos Monkey does the opposite: it randomly terminates servers in production to test resilience. This allowed Netflix to build fault-tolerant services that survive server failures.\n\n**Test-Driven Development (TDD)** applies inversion by writing a failing test first. You define the failure before writing code to make it pass, forcing you to think about how code could fail before implementing it.\n","experience":"mid","further_reading":[{"description":"Collection of Munger's speeches and talks on mental models including inversion","title":"Poor Charlie's Almanack - Charlie Munger","url":"https://www.stripe.press/poor-charlies-almanack"},{"description":"Book exploring systems that gain from disorder and stress","title":"Antifragile - Nassim Nicholas Taleb","url":"https://en.wikipedia.org/wiki/Antifragile_(book)"}],"group":"Decisions","image":"/images/laws/inversion.png","origins":"Inversion is explained by investor Charlie Munger's famous quote: \"All I want to know is where I'm going to die, so I'll never go there.\" Munger was inspired by 19th-century mathematician Carl Gustav Jacobi, who solved problems by inverting them and coined \"Invert, always invert.\"\n\nIn philosophy and Stoic practice, we also see a flavor of inversion. The Stoics had an exercise called premeditatio malorum (premeditation of evils), which means imagining in advance the worst things that could happen, just to be prepared. This is essentially inversion applied to life. \n","overview":"The core idea is that specific insights become clear when you look at a problem from the opposite angle. In software engineering, instead of designing only for the best case, you deliberately design for the worst case: What if the database goes down? What if latency spikes?\n\nBy thinking of how things can fail, you add features like circuit breakers, retries, or failover strategies. Inversion pairs well with First-Principles Thinking and is a form of defensive design that leads to robust outcomes by avoiding possible problems.\n","related":["first-principles-thinking","murphys-law","premature-optimization"],"slug":"inversion","takeaways":["For any goal, also ask the inverted question. If the goal is “deliver the project on time,” we should think about “what would make us miss the deadline?” Making a list of those factors (scope creep, underestimating tasks, etc.) can help us achieve those goals and escape issues.","Use techniques like pre-mortems. Our project failed, and we tried to determine what could have caused it. This critical thinking can show risks that optimistic planning overlooks.","In design and testing, we can account for edge cases and use cases of your system. For example, how could a malicious user break this API? Inverting in this way leads to better solutions (e.g., adding validation, rate limiting, etc., once you understand how things break)."],"title":"Inversion","url":"https://lawsofsoftwareengineering.com/laws/inversion/"},{"description":"80% of the problems result from 20% of the causes.","examples":"Microsoft found that around **20% of bugs in Windows and Office caused 80% of all crashes**, and a tiny 1% of bugs caused around 50% of errors. By focusing on the critical 1-20% of bugs, they dramatically improved stability. This is textbook Pareto: address the small set of high-impact issues to make most users happier quickly.\n\nA software team analyzed usage analytics and discovered that out of 50 features, only 5-10 (10-20%) were used by 80%+ of users. This guided them to simplify the interface around core features and remove unused ones.\n\n**Hot spots in code** follow the Pareto pattern. A small part of the codebase drives most defects, slowdowns, and \"scary to touch\" work. Track commits plus incidents to find them, then pay down debt where it compounds: add tests, simplify paths, reduce coupling, tighten interfaces.\n","experience":"junior","further_reading":[{"description":"How Microsoft applied Pareto to prioritize bug fixes","title":"Microsoft's CEO: 80-20 Rule Applies To Bugs","url":"https://www.crn.com/news/security/18821726/microsofts-ceo-80-20-rule-applies-to-bugs-not-just-features"},{"description":"Book on applying the Pareto Principle to business and life","title":"The 80/20 Principle - Richard Koch","url":"https://amzn.to/44QjIFH"},{"description":"Overview of the principle and its applications","title":"Pareto Principle - Wikipedia","url":"https://en.wikipedia.org/wiki/Pareto_principle"},{"description":"Steve Ballmer's 2002 memo referencing the 80/20 rule in Microsoft's strategy","title":"Full Text of 10/02 Ballmer Memo","url":"https://www.eweek.com/enterprise-apps/full-text-of-10-02-ballmer-memo/"}],"group":"Decisions","image":"/images/laws/pareto-principle.png","origins":"The principle is named after Vilfredo Pareto, an Italian economist who in 1906 noted that about 80% of Italy's land was owned by 20% of the population.\n\nIn the 1940s, quality management pioneer Joseph M. Juran adopted the idea when analyzing industrial defects, calling it the \"vital few and trivial many\" rule. Juran observed that by focusing on the vital few quality issues, one could improve quality with less effort than trying to tackle all problems at once.\n","overview":"The Pareto Principle is more of an observation than a law, but the 80/20 pattern (or similar ratios like 90/10) appears frequently. \n\nIn the domain of software engineering we say that, \"80% of the time in a program is spent in 20% of the code.\" This insight is significant for optimization: instead of micro-optimizing everything, profile to identify the hot 20% and optimize that.\n\nThe principle influences product development too. Often, a few core features satisfy the majority of user needs. When planning an MVP, teams focus on that core set rather than trying to do everything. It is an essential check against equal prioritization: everything is not equally important. \n\nThe Pareto Principle encourages strategic allocation of effort to maximize outcomes by investing where returns are highest.\n","related":["premature-optimization","kiss-principle","teslers-law"],"slug":"pareto-principle","takeaways":["Identify the top 20% of factors that contribute to 80% of whatever you care about. This could be 20% of features that account for 80% of usage, or 20% of bugs that cause 80% of crashes. Prioritize your time and resources on those vital few for maximum impact.","Don’t spend the same effort on everything. If a particular area of code is rarely run, it probably doesn’t need the same optimization or attention as a hotspot.","It's not always exactly 80/20, but the idea is the same. Use profiling, analytics, and data gathering to empirically identify where the imbalances are.","On a personal level, as an engineer or manager, identify which tasks produce most of your value. It might be coding core features or coaching team members. "],"title":"Pareto Principle (80/20 Rule)","url":"https://lawsofsoftwareengineering.com/laws/pareto-principle/"},{"description":"The best way to get the correct answer on the Internet is not to ask a question, it's to post the wrong answer.","examples":"A developer stuck on configuring an open-source library posts a question and gets no replies. Using Cunningham's Law, they post: \"For anyone else struggling, the solution is to set ConfigMode to False.\" If wrong, someone (possibly the library maintainer) will quickly reply: \"Actually, no, you should leave ConfigMode true, it's another setting you need to change.\"\n\nA new developer uncertain about implementing a feature submits a pull request with their best attempt rather than asking in the abstract. Senior engineers review it and point out improvements. By presenting a \"proposed answer,\" the developer gets the team's knowledge and ends up with the right approach.\n","experience":"junior","further_reading":[{"description":"Book about wiki philosophy and collaborative knowledge building","title":"The Wiki Way - Bo Leuf \u0026 Ward Cunningham","url":"https://en.wikipedia.org/wiki/The_Wiki_Way"},{"description":"Classic guide on effective communication in technical communities","title":"How to Ask Questions the Smart Way - Eric S. Raymond","url":"http://www.catb.org/~esr/faqs/smart-questions.html"},{"description":"Wikipedia article on the law and its origins","title":"Cunningham's Law - Wikipedia","url":"https://meta.wikimedia.org/wiki/Cunningham%27s_Law"}],"group":"Decisions","image":"/images/laws/cunningham-law.png","origins":"Cunningham’s Law is named after Ward Cunningham, the American programmer best known for creating the first wiki software. The actual phrasing of the law is often attributed to a colleague of Cunningham, Steven McGeady, who formulated the adage and named it after Cunningham. \n\nAccording to McGeady, Ward Cunningham gave him advice in the 1980s regarding early internet forums (Usenet), and McGeady later described it in a comment on a New York Times blog in 2010. \n\nThe irony is that Ward Cunningham’s invention, the wiki, is a platform built precisely on the idea that people will collaboratively correct and improve content. \n\nThe French have a proverb, “Prêcher le faux pour savoir le vrai” (preach the false to know the true), which captures a similar concept.\n","overview":"Cunningham's Law arose in the context of online communities, particularly wikis and forums. The underlying observation is that assertions draw more engagement than questions. On Wikipedia, if someone posts incorrect information, other editors will rush in to fix it.\n\nIn software engineering, you see this on Stack Overflow and mailing lists. A user asks a question and gets few responses, but if someone posts a slightly wrong answer, others quickly chime in to correct it. By putting something out there, you transform a passive question into an active discussion.\n","related":["linuss-law","broken-windows-theory"],"slug":"cunninghams-law","takeaways":["People online love correcting errors. If you’re stuck on a problem, sometimes proposing a solution (even if it might be wrong) can get you to the right solution faster.","Asking a question might evoke only silence, but confidently stating something (even if incorrect) often provokes a reaction. ","Instead of endlessly asking “How should we do X?”, propose a draft or prototype. Even if it’s not entirely correct, having a concrete starting point often gets more feedback (“No, not like that, do it this way”). "],"title":"Cunningham's Law","url":"https://lawsofsoftwareengineering.com/laws/cunninghams-law/"}],"title":"Laws of Software Engineering","url":"https://lawsofsoftwareengineering.com/"}