5/12/2026 at 1:02:24 PM
I'll give you the cheat sheet:- Good design is a single idea pervaded throughout.
- More generally, your goal should be to minimize surprise.
- If your system allows it, people will do it.
- Everyone will not just. If your solution starts with "if everyone will just..." then you don't have a solution.
- Isolate the parts of your system that transform data from the ones that use it. Data models outlive code.
- Coupling is the root of most evil.
- Versioning is inevitable.
- Make state explicit.
- Every piece of information should have a single source of truth.
- You should spend more time thinking about naming things correctly.
- If testing is difficult, the design is wrong.
- You will regret every undocumented decision.
- Communication is a tax that you should justify before paying it.
Remember that the job of an engineer at any level is to use rules of thumb to solve problems for which there is incomplete information.
by CSMastermind
5/12/2026 at 7:08:45 PM
I don't agree with all of these, but I'll add a couple of my own:- The ultimate goal of software is to solve the immediate problem at hand. The secondary goal of software is to solve likely future problems with as little work as possible. Any bad design which is better on those goals than a good design is actually a good design.
- Make your interfaces easy to use correctly and hard to misuse. Think of how people unfamiliar to the project will interact with them, make the obvious way be the correct way.
- Correct code should be easy to write; suspicious code should stand out.
- Shift bugs left.
- Fixing a bug class is better than fixing a bug.
- Interfaces are harder to change than implementations. An ugly implementation is ok if it has the correct interface.
- Use comments and documentation to explain why the code is the way it is. If it feels like there's a simpler way to do it, but that simpler way wouldn't actually work due to a constraint some people may be unaware of, document that.
- Don't repeat yourself; when it comes to data. If you store a single fact in multiple places; those places will inevitably get out of sync, and that causes bugs.
- There's a cost to straying off the well-trodden path. Don't be afraid to do so when it's truly worth it, but don't underestimate that cost. Worse (boring) technology is often better technology.
- Think in terms of expected value. Think not "Is this thing worth doing?", but "Is this thing worth doing, compared to the other things we could be doing instead?"
- Even if you think you're smarter than everybody else, intelligence isn't always enough, some problems can't be discovered until they happen. Other people have worked longer on this problem than you have. Learn from their mistakes.
- Friction is the silent killer.
by miki123211
5/13/2026 at 1:08:10 AM
> The ultimate goal of software is to solve the immediate problem at hand. The secondary goal of software is to solve likely future problems with as little work as possible.Not really. Today I learned of a story where a vibe coding PM deployed a vercel app, which was in its entirety a single react component that serves a banner, that was embedded via an iframe into an entirely separate web app, whose repo they have full access to, because they needed to get a modal component out the door, but were blocked because they “couldn’t upload the image to s3.” (They could just use the public/ or assets/ directory and have the cdn pick it up, too.)
People do the most insane things when they are tight on time and don’t have the intuition to do a bit of research up front. If you ask them, they’re solving the immediate problem at hand. If you ask anyone else who interacts with their work, they’re disrupting our days/weeks/months/years when we have to step through systems that don’t know any better.
If you have the muscle to plan ahead, even a little bit, which is usually just following the same pattern over and over again, then you are fine.
In this world you are still optimizing for the now problem but you have also solved, to some and ideally a better degree, some future problems for free
by dirtbag__dad
5/12/2026 at 1:09:20 PM
I'd add- data migrations are inevitable and should be planned for (corollary of versioning)
- planning is good, sometimes you just have to try things out
- everything costs money. Designing without costs in mind will force hard choices down the line
by laszlojamf
5/12/2026 at 2:15:01 PM
I'll add another to that:- Code lives longer than you expect. You forget sooner than you expect. Make a readme/architecture overview/theory of operation document. Put more in it than you think is needed. Check it in with the code.
by AnimalMuppet
5/12/2026 at 11:31:38 PM
If I had a dollar for every time "throwaway code" became foundational code...by abustamam
5/12/2026 at 1:58:39 PM
I wish I could buy you a beer, as this is very validating. I have been building a video game for over a year. But more importantly I have been building a sustainable engine with a distinct data pipeline, resource rendering/management layer fully decoupled, explicit catalogueing of viable state transformation modes, and honestly, most of your list is absolutely applicable. Even tho it is solo, the constraints of my engine guides forgetful me to 'this is the way to add this weird new feature that arose from testing because reasons' without having to have a tome of 'if you want to build a new sound effect that executes at a particular state transformation multiple times, here is how you do it'Cheers
by RobRivera
5/12/2026 at 6:10:12 PM
Ah, the infamous "I believe I'm building a video game, but in reality I'm building a video game engine and I don't realize it yet" every game developer goes through at least once, god speed to you :)by embedding-shape
5/12/2026 at 7:36:44 PM
Its been such a fun endeavorby RobRivera
5/13/2026 at 4:34:59 AM
I have nothing to add other than I love seeing this attitude of someone enjoying getting "lost" down what many would consider a mistaken path.Good reminder for the rest of us to enjoy the journey once in a while.
by dodu_
5/12/2026 at 3:26:48 PM
Missing the single most important thing, that people seemingly are purposefully trying to avoid nowadays for some reason:- It depends
No solution I've come across, is a solution for everything, everywhere. It's almost always context dependent, and something that is right in one place, can be utterly wrong in another, and there is no universal truths regarding design and architecture.
The more flexible you can be with "right tool for the right job", the easier time you'll have designing, because you're no longer trying to shoehorn in things that are "right" and "correct".
> - You should spend more time thinking about naming things correctly.
This should almost be on the list twice too, the amount of people who couldn't care less about naming, is so damn high, but if people just cared a tiny bit, it'd solve so much future confusion. Whenever I get pulled into helping a "legacy project" or whatever, establishing a "true vocabulary" based on what people actually call things, is the very first thing to do, because it always uncovers that people been talking about different things the entire time.
by embedding-shape
5/12/2026 at 10:09:08 PM
To be honest, "It depends" is also exhausting. I have some defaults that I push until the breaking point, though I apply this more often on personal projects. DDD is an exception, as even professionally I will vomit DDD concepts as solutions for literally anything. "This could have been an aggregate", I will say like a mantra.by rafael-lua
5/12/2026 at 11:35:16 PM
I found I did pretty well in the interview stage whenever I'd start an answer with "it depends"Of course, I'd have to back that up with assumptions and goals and such, but I think that's the point. X technology is great at Y but not so great at Z, so if you want to optimize for Z maybe don't use X.
by abustamam
5/13/2026 at 12:24:26 AM
I don't actually think this has much to do with software architecture. Except maybe the "Isolate parts of your system..."In fact the article itself didn't really seem to be too coherent on software architecture. I think the 4+1 view of software architecture is a good conceptual way to think about things (minus all the UML). It's not a complete picture but it addresses the bigger picture. The book series Pattern-Oriented Software Architecture is pretty good and outlines a number of architectures people tend to land on. One stage Grady Booch was working on a handbook of software architecture, but seems to be kind of dead ish, but he did have a mailing list where he'd go to companies or look at large open source projects and look document big system architectures (and some smaller scale), not sure where you can see this anymore. All of these things are worth diving into if you want to learn about software architecture. You can see these architectures are built for different focuses, things like scale, safety, performance, interoperability, failsafe, etc. i.e. there are very specific goals of an architecture with very real tradeoffs.
by keithnz
5/13/2026 at 1:17:43 AM
Good architecture is not about the patterns you pick. It’s about having a team dev cohesively on any pattern(s)- programmatically enforce your style with in-house linters and scaffolders. Be highly opinionated
- if you # ignore anything, leave a comment explaining why
- use bdd so your cases are human readable and must update with the code (unlike a stale comment)
- follow the same pattern in all your services (I love hexagonal design for backend). If you break from the design have a good reason for it
- COMPOSE your code. It’s almost always the case that two endpoints or jobs or whatever happen to have a few things in common, but differ wildly. Don’t get DRY, just import those things in each spot and don’t entangle them with each other, it’s too confusing
- scope your interfaces tightly. No optional params unless the domain is actually optional. Make separate jobs or endpoints for different configs. I can’t figure out wtf all your configs were from 4 years ago and neither can you
- code is default testable with DI/DIP
- always run tests running real infra like testcontainers - cement ci/cd as your guardian. Employ every linter you can.
- hammer workarounds with comments in the code
- break all systems into small problems and nothing is challenging technically (though the domain might be!)
- work with less people on your code. It’s easier to stay aligned and follow the same patterns
- don’t expect anyone to figure it out. You need to champion your changes. Do code reviews, hold their hand, show them the way
- clear out mundane items like installfests, local auth, server reloads. Slow dev pisses people off
- finally, and most important, employ an org policy for review. Don’t let shit fall through the cracks unknowingly. It compounds. You have skills now as a quick and dirty to eval and enforce. Use them!
by dirtbag__dad
5/12/2026 at 7:45:57 PM
I work in this space as well - I know that my particular work is much less abstract (we're modeling the healthcare industry) than some others.But as a designer of the system you must understand the industry and while you don't need to embrace their terminology and modeling habits fully, you must understand their rationale and how they view the data set. There are some places where we've intentionally simplified complications of the healthcare market to eliminate needless (to us) over definitions and provide a more unified modeling. But these changes took significant comprehension of the problem area to make with confidence.
> You should spend more time thinking about naming things correctly.
On this point in particular. Names never die - that's a lie, occasionally they do, but it takes an extreme amount of effort to enforce a renaming. It really is worth spending a big bulk of time letting SMEs stew with naming proposals to make sure you bases are covered. You can force through a few concepts but your business wing (sales, marketing) will constantly put pressure on you towards industry terminology and force your model to adhere to the current view of the industry. If you decide to break with that that break must be decisive and obvious in intent.
Oh, the single biggest attribute of software to emphasize is maintainability. How much will this cost to build is one question - how much will this cost to run (not just infra but compounding feature requests and code refactoring and maintaining third party software versions etc...) is the far more impactful.
by munk-a
5/12/2026 at 4:53:30 PM
Great list but I dunno about coupling being evil, it is literally the only place anything important happens.by bfivyvysj
5/12/2026 at 10:11:24 PM
Coupling is evil, as it is the main root of all the nastiest problems I have found in many projects I worked on. It is the main cause of "throw it all away and start greenfield" in my experience. I mean, it is important and needs to be done right, but it is yet evil.by rafael-lua
5/12/2026 at 5:22:11 PM
What exactly do you mean by “make state explicit”?by kachnuv_ocasek
5/12/2026 at 7:52:17 PM
Minimizing side effects (e.g. functional programming) is a good habit in general. But when we're talking at the scale of a company's entire software solution state is the enemy of everything that is good.You never want to work on a platform with 500k lines of code any of which could mutate variable state at will and the more you can isolate or simplify state usage the better your life will be.
by munk-a
5/13/2026 at 12:30:57 AM
It's also the enemy of evil things your company does.by topaz0
5/12/2026 at 7:14:03 PM
Depends on the language I'd say, but overall, try to keep state in as few places as possible, and make it more obvious when it's being used. Modern example would be Rust defaulting to immutability for variables, and makes it very clear when you should expect that this variable actually carries state rather than just a value, by prefixing it with `mut `. Other languages might make it the other way around, making constants/read-only variables stick out, and defaulting to "hiding that they have state" basically.by embedding-shape
5/12/2026 at 1:22:09 PM
Can you explain the last one? What types of communications are you suggesting an arch would avoid?Otherwise, a very wise list!
by mwexler
5/12/2026 at 2:45:06 PM
Not the OP. However, in my experience, the "tax" of communication is that everything has winners and losers. You can state that the "1+1=2" or "the sky is blue" and someone will lose politically. You have to prepare yourself to defend your position even if 19 out of 20 agree with you; because the one person who disagrees with you has the most to lose.by rawgabbit
5/12/2026 at 1:51:03 PM
You can make the feature with one colleague, or you can call in five more people to weigh in and do their parts of the work.If you involve five more, the result could be better in theory, but it will certainly take MUCH more time because of communication overhead.
by murkt
5/12/2026 at 7:55:13 PM
Pretalking is highly valuable. Making sure that key stakeholders have an aligned vision and are invested in defending it before opening up a discussion (or dictate, depending on the culture) to a wider audience is necessary. Occasionally expect that the stakeholders and you got it wrong and you'll need to invest time into rebuilding the solution, but, if you're honest with yourselves and diligent, assume that generally the expert subgroup will supply a comprehensive solution.by munk-a
5/12/2026 at 4:22:16 PM
When I read it, I assumed it meant like network communication in your program. File and network I/O having/being a "tax" makes sense to me.by ragnese
5/12/2026 at 7:01:30 PM
Just one more alternative interpretation… I thought it’s about systems calling into other systems, making everything slower, more complicated and brittle…But maybe it’s about discussing an issue with 10 other people from different teams when it’s not necessary.
But we will never now. I guess OP didn’t want to pay the communication tax on expressing this idea clearly :)
by serial_dev
5/12/2026 at 1:43:32 PM
Completely agree. Had me until the very last point. WTF. Communicate.by theteapot
5/12/2026 at 1:52:34 PM
The last one is about involving less people. You don't have to read it as "shut up and keep your thoughts for yourself". I read it more like "Do we really need to have six people working on this feature/present in this call?"by murkt
5/12/2026 at 7:56:34 PM
I strongly prefer the phrasing of "When do we actually need to have six people involved on this?" It's often valuable to set a momentum and prune obviously poor decision branches before bringing proposals to a wider audience.by munk-a
5/12/2026 at 2:08:55 PM
well, it needs to be communicated better.by ulbu
5/12/2026 at 1:58:53 PM
I wonder if they don't mean "between systems".by gavmor
5/12/2026 at 2:13:27 PM
> Communication is a tax that you should justify before paying it.I thought it meant like keep things as local as possible. Like within the same process, within the same machine, avoid going through the network because staying on the processor is always the fastest, going to ram is next fastest, and if you need to communicate across the network it is always slowest
by collabs
5/12/2026 at 2:30:47 PM
I don't think performance advice should be part of a general architectural principles list, so I don't think that's what they meant. Otherwise might as well add "avoid nested loops", etc, and then it devolves into a general programming advice list.Performance is and always was something dependent on the domain rules. You don't start architecting for performance before understanding requirements so why make it a pillar of all architecture.
by alternatex
5/12/2026 at 1:57:54 PM
> - Make state explicit.Don't save the same state in more than one place.
by ofrzeta
5/12/2026 at 7:58:21 PM
You can and you must replicate state in a complex system. The key is that state should always have an explicit owner and other carriers of that state should understand that their version of the state has some inherent lag or inconsistency off the true state.There's a reason caching (and it's invalidation) is one of the two hardest problems in computer science.
by munk-a
5/12/2026 at 1:55:39 PM
Good list!One addition?
* start with a modular monolith
by electrosphere
5/12/2026 at 10:20:45 PM
This one has yet to enter my head. I read Martin Fowler's related article* a few times, and it is sound... But I still can't see microservices being so "complex" to be so avoided early on. Especially in 2026, with the level of IaC and pipelines we have. I might be naïve, but I just don't get it.by rafael-lua
5/12/2026 at 8:02:19 PM
I don't want that to be limited to just architecture though - proper initial factoring of a software product is invaluable at the large and most microscopic level.by munk-a
5/12/2026 at 4:32:30 PM
Yes. I’d add: design the module boundaries before splitting deployment.A modular monolith still forces you to name ownership, data boundaries and invariants, but without making every mistake a networking/ops problem.
by perkovsky
5/12/2026 at 5:31:36 PM
Good list, although things get weird when you are limited by some legacy software/database.by avgDev
5/12/2026 at 8:00:35 PM
You are always limited by some legacy software/database.If you're not limited by some legacy software/database initially then you will have such a large problem scope that you'll create your own legacy software/database internally.
I'll grant that if your problem is really simple and straightforward you can sometimes just build an ideal greenfield solution that's perfect and wonderful - but those problems are rarely the problems that are profitable to solve.
by munk-a
5/12/2026 at 1:20:31 PM
Thanks for sharing! Really agree with #2 even though ultimately - we can only minimise rather than totally eliminate.by thedetailsguy
5/12/2026 at 3:43:19 PM
> If testing is difficult, the design is wrongOr domain/IO is cumbersome. Think videogames.
by ivanjermakov
5/12/2026 at 4:00:00 PM
That's one of the few places where creating abstractions makes a lot of sense, especially in video games. You really, really want as much to be automated tested as humanly possible, because the user/player surface ends up enormous and testing gets "expensive" much quicker than a typical SaaS.by embedding-shape
5/12/2026 at 4:04:50 PM
Nope, that's just the design being wrong. Factorio has no issues with testing.It doesn't matter if nobody is interesting it fixing it, video games have been and almost always are written like shitty single use code, (Even when it's not) so it shouldn't surprise anyone that proper test harnesses aren't available in engine.
by nullsanity
5/12/2026 at 1:56:15 PM
As a corollary to> Communication is a tax that you should justify before paying it.
> Every piece of information should have a single source of truth.
- Do as much as possible on a single system and minimize sharing state.
- Recognize that every system is distributed, it's just a question of how and where.
One of the biggest ills I observe with most modern software systems is that we've gone full tilt towards things like microservices which require synchronizing state across multiple interdependent parts. Regardless of how clean the abstractions or how well contracted the APIs, doing all of that copying and state synchronization is going to result in problems: performance problems, cost problems, and synchronicity problems.
by tristor
5/12/2026 at 4:05:23 PM
Good, really good. But not real. You can achieve such ideal only without human which makes no sense.by dmitrijbelikov
5/12/2026 at 7:33:15 PM
then comes the order from your manager: "Put it in production and we can work through this list later".. or even worse, now with Claude, managers are putting stuff "Quick and Dirt" in production and you have to maintain it.. sadly true story..by pelasaco
5/12/2026 at 8:04:42 PM
The job of an architect and good technical management is to teach non-technical management the true costs of their decisions. It's not an easy job by any measure and LLM driven know-nothings in management can make it far more frustrating. But, you need to make sure you're capturing the true[1] costs of decisions to the best of your ability including externalities.1. You're allowed to lie for expediency, but make sure you never delude yourself into believing your own lies.
by munk-a
5/12/2026 at 1:18:30 PM
great list! tyby john_builds