DEV Community

Cover image for The Unwritten Laws Running Your Code
Adam - The Developer
Adam - The Developer

Posted on

The Unwritten Laws Running Your Code

Nobody warns you about these in bootcamp. You learn them the hard way, usually at 11pm before a release, wondering how a three-week feature became a three-month saga. These are the laws, theorems, and hard-won principles that quietly govern every software project. The sooner you internalize them, the sooner you stop being surprised.


1. Brooks's Law

Adding developers to a late project makes it later.

Fred Brooks figured this out in 1975. We are still ignoring it in 2025.

The intuition is straightforward: if a project is behind, hire more people. The reality is brutal. Every new developer needs onboarding. Every existing developer loses productivity doing that onboarding. Communication overhead grows not linearly but combinatorially. With 4 people you have 6 communication channels. With 8 you have 28.

The deeper lesson is that software development is not like digging a ditch. You cannot divide a nine-month baby into nine one-month babies by assigning nine mothers. Some work is inherently sequential, and coordination is never free.

When a project is late, the first instinct should be to cut scope, not add headcount.


2. Conway's Law

Your architecture mirrors your org chart.

Mel Conway wrote this in 1968. It still lands like a punch every time a team discovers it firsthand.

Teams build systems that reflect their communication structures. If your frontend, backend, and data teams barely talk to each other, you will end up with a frontend, a backend, and a data layer that barely talk to each other. Want a clean service boundary? First, create a clean team boundary. Want a monolith? Put everyone in the same room.

This is not a coincidence or a failure of engineering discipline. It is gravity. You cannot fight it by drawing better architecture diagrams. You fight it by changing how people coordinate.

The inverse, sometimes called the Inverse Conway Maneuver, is actionable: design your team structure to match the architecture you want to build.


3. Parkinson's Law

Work expands to fill the time available for its completion.

Cyril Northcote Parkinson was writing about British bureaucracy in 1955. He may as well have been writing about sprint planning.

Give a developer two weeks for a two-day task and they will find ways to fill those two weeks. Not out of laziness, but out of a very human tendency to explore, refine, and polish when there is room to do so. Deadlines create focus. Vague timelines create scope creep, gold plating, and endless bike-shedding.

This is not an argument for crunch. It is an argument for honest estimation, enforced constraints, and clear definitions of done. A deadline without consequences is not a deadline. It is a suggestion.


4. Hofstadter's Law

It always takes longer than you expect, even when you take Hofstadter's Law into account.

Douglas Hofstadter wrote this in 1979, and the recursive phrasing is entirely intentional. The law mocks itself, and you, and all of us.

Human brains are optimism machines. We plan for the best case. We forget about testing, code review, integration issues, vague requirements, and the three meetings that will interrupt every afternoon this week. We have been burned before. We add buffer. We are still wrong.

The practical response is not despair. It is padding estimates by more than feels reasonable, tracking estimation accuracy over time, and treating deadlines as planning tools rather than commitments to the millisecond.

Accept the inevitability. Build in slack. Communicate early when things slip.


5. Gall's Law

A complex system that works evolved from a simple system that worked.

John Gall wrote this in 1975 and it is perhaps the most violated law in this entire list.

The failure mode is familiar: a team designs the full, complete, production-ready, infinitely scalable, perfectly abstracted system from day one. They spend months building something nobody has validated. It collapses under its own weight before a single user touches it.

The alternative is to start with the smallest working system possible, prove it solves the actual problem, and grow complexity only as the problem demands it. You cannot design your way to a working complex system. You can only grow one.

Microservices extracted too early. Event-driven architectures added before the data model is stable. Kubernetes before you have five users. These are Gall's Law violations. Start simple. Earn complexity.


6. Goodhart's Law

When a measure becomes a target, it ceases to be a good measure.

Economist Charles Goodhart articulated this in 1975. It is a trap every engineering team eventually falls into.

Lines of code per day. Story points per sprint. Test coverage percentage. Deployment frequency. Every one of these is a useful signal until it becomes a goal. Once it becomes a goal, people optimize for the metric rather than the outcome. Coverage climbs because developers write tests for easy code paths. Velocity climbs because teams inflate estimates. Deployment frequency climbs because you split changes into trivial one-liners.

The metric looked healthy. The system got worse.

Metrics are diagnostic tools. Treat them as health checks, not scorecards. Rotate them before they calcify into targets. Be suspicious of any number that is trending in the right direction too smoothly.


7. Hyrum's Law

With a sufficient number of users, all observable behaviors of your system will be depended upon by somebody.

Hyrum Wright articulated this from hard experience at Google. If you have ever tried to deprecate anything in a widely-used API, you already understand it viscerally.

It does not matter what your documentation says is the contract. Users observe the actual behavior of your system, and they build on top of it. Response time. Error message wording. Undocumented side effects. The order that items appear in a list. If it is observable and consistent, someone is depending on it.

This means that at scale, there are no truly internal implementation details. Any change to observable behavior is a breaking change for someone. Design public interfaces with this in mind. Version carefully. Deprecate slowly. Test the behavior your users actually rely on, not just the behavior you intended.


8. The Law of Leaky Abstractions

All non-trivial abstractions, to some degree, are leaky.

Joel Spolsky wrote this in 2002 and it remains one of the most useful mental models for debugging and system design.

Abstractions are supposed to hide complexity. TCP hides the unreliability of IP. ORMs hide the complexity of SQL. HTTP clients hide the messiness of network sockets. And they do hide it, until they do not.

The leak happens when the abstraction fails in a way that exposes the complexity underneath. Your ORM generates a query so inefficient that you have to write raw SQL to fix it. Your HTTP client fails with a timeout and you have to understand TCP keepalives to diagnose it. You cannot escape the underlying system. You only get to ignore it until something goes wrong.

The practical implication is that you must understand what your abstractions are built on, even if you never intend to touch that layer. When the leak appears, and it will, ignorance of the underlying system is expensive.


9. The 90/90 Rule

The first 90% of the code accounts for the first 90% of the development time. The remaining 10% accounts for the other 90% of the development time.

Tom Cargill is credited with this. It is darkly funny because everyone has lived it.

The feature works in the demo. It handles the happy path. It impresses stakeholders. Then comes the edge cases, the error handling, the accessibility, the performance under load, the mobile layout, the security review, the QA pass, the localization, the migration script, the rollback plan, the documentation, and the six bugs that only appear in production.

This is why "it is basically done" is a phrase that should make project managers nervous. The last stretch of software development is where assumptions meet reality, and reality usually has more surface area than you planned for.

Budget for it. Estimate it honestly. Do not promise shipping dates based on the completion of a working prototype.


10. No Solutions, Only Tradeoffs

There is no perfect solution. Every architectural decision trades one set of problems for another.

This one does not have a single author because it is a hard-won truth that every experienced engineer arrives at independently.

Microservices give you independent deployability and team autonomy. They also give you distributed systems complexity, network latency, and operational overhead. Caching improves read performance and introduces stale data problems. Type systems catch bugs at compile time and slow down iteration in early stages. Consistency guarantees in databases trade throughput. Premature optimization trades readability.

Every time you hear someone describe a technology as universally better than another, be skeptical. Better for what workload, at what scale, with what team, under what constraints? The question is never which option is good and which is bad. The question is which set of tradeoffs fits your current situation.

Senior engineers are not people who know more answers. They are people who have learned to ask better questions about tradeoffs.


Putting It Together

These laws do not predict the future. They describe the shape of problems you are already walking toward. Brooks's Law will not stop you from overstaffing a late project, but knowing it might make you pause before you do. Goodhart's Law will not prevent a manager from turning metrics into targets, but it might help you push back when you see it happening.

The goal is pattern recognition. The more fluent you are in these principles, the earlier you can name what is happening, and naming it is the first step to navigating it.

You will still ship late. You will still underestimate. You will still inherit a complex system that nobody planned to build. But you will be a little less surprised, and in this industry, that counts for a lot.

Top comments (0)