Posted by SerCe 4 hours ago
“Hear me out: what if instead of deploying a fleet of web servers to handle 10M identical GET requests per second, we put a handful of servers behind a few Varnish caches with a 1 second expiration?”
“Wait, this thing is spec’d to serve 3000 requests per day and an acceptable downtime of 20 hours per week? Kubernetes is cool, but why don’t we spin up a single VPS and run the whole stack on it?”
There’s a subtle art to talking dev teams down off a ledge, but sometimes the simple path is better in every way. Being able to spot those times is golden. And, of course, knowing when the simplest reasonable version is still quite complex and being willing to roll with it is equally important.
I’ve watched this exact dynamic play out: one person ships the boring implementation, nothing breaks, everyone moves on. Another person ships the “platform” version, there are docs, diagrams, an internal talk… and now there’s a subsystem that needs to be explained to every new hire. Guess which one looks like “impact” on paper.
The part I think is under-discussed is that complexity has a carrying cost that rarely gets charged to the builder. The team pays it later: more surface area, more failure modes, more time spent reading before changing. In that sense, unearned complexity is like taking on leverage. Sometimes it’s the right move, but you should need a business case, not just enthusiasm.
What’s helped on teams I’ve liked: make “simplicity” legible by treating it as a decision record. In the PR/ADR, explicitly list the two “cooler” options you didn’t take and why, and write down the trigger conditions for upgrading later (“if p95 > X for Y days”, “if we add a second producer”, etc.). That turns “implemented feature X” into “made a deliberate tradeoff, reduced risk, and defined a clear escape hatch.” It also forces the room to argue with specifics rather than vibes like “future-proofing.”
Also +1 on the interview point. A lot of system design interviews are accidentally training people that the goal is to draw more boxes until the interviewer nods. The more senior move is usually: start simple, instrument, set thresholds, and only then add machinery. But that’s harder to “perform” in 45 minutes than rattling off Kafka and sharding.
If an org wants to fix the incentive, I think the question to ask in reviews isn’t “how big was the thing you built,” it’s “did you make the system easier to change next quarter.” That’s the kind of impact that compounds, and it’s usually correlated with simplicity.
This has been my personal mission and motivation to go into management. I see my job as making sure engineers are rewarded for building the simplest thing that works.
So far the best way to align incentives that I've found is a simple policy: We'll ship whatever you want, but we know your phone number and you're on-call for your systems. At least 2nd tier on call.
It's a little mean but you'd be surprised how quickly engineers start simplifying stuff when they feel like they can't get anything done because someone's always asking questions or triggering alarms about that weird thing they built 3 months ago.
> A lot of system design interviews are accidentally training people that the goal is to draw more boxes until the interviewer nods. The more senior move is usually: start simple, instrument, set thresholds, and only then add machinery
I do the system design interview. The easiest way to fail is to over-design the solution. I am going to ask deep probing questions and you better have answers. My favorite answer is when people go "Oh yeah you're right, this box doesn't add any value, we can remove".
But that's an unpopular approach these days where many companies are obsessed with minimising the bus factor to the point that their IP is as replaceable as their employees.
No takers yet.
These days its turned less into bus factor and more into got-fed-up-of-wage-compression-and-left factor
Two questions:
1) How did this principal engineer get this title?
2) How is he going to get the next one?
By delivering, or helping the team deliver, outsized returns on engineering hours invested.
If a design is bloated, a good principal engineer should point out gaps, help simplify the solution and enable the team to deliver faster. That definitely gets noticed.
The best engineer I know who can work with huge complex systems in a big company usually starts with a complex solution then after he understands what he wants to achieve thinks backwards and reimplements it in the fewest possible lines of code change with the already complex system.
Every large company has a ladder for promotions that includes many words that basically come down to "complex." "Drive a year long initiative" or "multiple teams" or "large complex task with multiple components" are all examples I've seen.
What is funny is you can dance through the hoops for 3-5 years for promo. Or grind leet for 100 hrs and get it by jumping.
Person A writes some code that just works, no one hears about it and the developer may tend to fade into the background.
Person B made a lot of mistakes is always stepping in to fix problems and be the hero, and everyone forgets that they caused those issues in the first place.
When it comes time for promotions, Person B is fresh in everyone’s mind due to the heroics performed to fix their own code over the weekend. They can take credit for the features being shipped and the operational work done to help run it.
Meanwhile, Person A is overlooked, they just shipped some solid code and were able to get a good night sleep.
I'm back to being a senior in a new org and I try to be person A, but be extra communicative of what I'm working on and how it impacts and why it's important.
I find I spend more time trying to understand how to explain the value my work has to the business (screenshots, demos, docs) than trying to actually do my work. But I think it's important though, otherwise I'll be the person A who never gets promoted.
I relate to this a lot. I was a product owner for a while and made sure we could always explain the value of what was being delivered to stakeholders in language they would understand and matter to them. We spent a lot of time on preparing the demo, running it through internally, providing feedback, tweaking the wording, gathering metrics, etc. In many cases the developer was really interested in the technicality of a certain function, but we’d push them to shift focus to the value that was being delivered to the people we were presenting to. The last thing we want is for people to tune out, because someone is deep diving into code no one understands or really cares about seeing.
In my view, it doesn’t matter what you do if no one understands what you did or why it matters. If we can tell the story well, we will be valued. As a result, the team got great feedback, was highly valued, and our management felt we were miles ahead of every other team.
Fast-forward to now… I chose to move back to an engineering role. We don’t do demos anymore, despite protests from the team. No one knows what we do. We’ve seen multiple people laid off from the team and our direction is all over the place. It feels like we can never catch up, which is a far cry from the days when my boss was telling me to take a 3 month vacation, because of how far ahead we were.
This small shift in focus and opinions around things like demos has dramatically changed the team, how the work is viewed, and the team’s morale. It’s been very upsetting.
People who are easy to work with get promoted, and that is downstream from building simple solutions.
I think it's easy to state this sort of opinion, it sounds good on the surface, but I don't feel it stands up to scrutiny. I'd like to see some evidence or studies done to see if this is actually a trend.
Simple solutions are good enough some of the time, perhaps even most of the time, but often fall down with edge cases. But edge cases add up, and dealing with them is complicated.
For example, calculating pay for hourly paid workers is a "simple" problem. Deduct start time from end time and multiply by rate. Covers 90% of the workforce.
But the other 10% take much more work. That team that rotates an on-call worker (which earms an allowance), who gets a call (first hour is free, next is double time etc.)
So it is with software. Adding 2 numbers is trivial. But what about overflows? What about underflows? What if one number is infinity? What if it's i?
The simple solution is "just add, ignore edge cases". The complex solution handles the edge cases. Which is better in the long run?
Unnecessary complexity is a microservice architecture to do the same thing.
But also, just because there is complexity in the domain doesn't mean there needs to be complexity in the software. An elegant, simple solution could be implemented for calculating payroll or adding infinity. That's the hard part though.
Would you want to be in charge of simplifing this architecture for a 'senior staff' title for 4+ years?
This is just one of many examples who have this sort of complexity and it is celebrated, and the microservices hype (originated from Netflix and overhyped by Thoughtworks) have somewhat caused this madness and for some, it has turned into a mountain of technical debt to maintain.
Unless you have a very good reason to save a company from drowing over it's own complex infrastructure costs to run itself, attempting to simplify this architecture will be met with feroucious backlash by other teams of senior staff engineers, hundreds of meetings with risk officers and being blocked because of forever meetings with architects.
Since they made me in charge of this, at least management already is aware of the problem. Convincing Some engineers to start on a new greenfield project to replace their old solution is also not difficult.
The excuse always comes back "but it's extendable", how many implementations of a ConfigurationSingleton could you have in an application?
Put the class in and if you need the interface later any refactoring tool can easily create it when you have that second class (which 99% of the time will never happen).'
This is what worries me when people say AI is great for boilerplate, I worry this is the kind of boilerplate they'll be creating because they've put "must be well designed and extendable" in their AGENTS.md.
An interface specifies a contract that its users can depend on. Having one saves me from reading implementations of dependencies when reading a class.
In a good interview, the interviewee would ask clarifying questions; perhaps get told to build something simple that works; and then follow-up questions would expand towards bigger scale to test the breadth of knowledge and experience of the candidate.
The thing being evaluated is not blindly repeating random "best practices", but understanding and adapting to requirements.
> Now, promotion time comes around. Engineer B’s work practically writes itself into a promotion packet: “Designed and implemented a scalable event-driven architecture, introduced a reusable abstraction layer adopted by multiple teams, and built a configuration framework enabling future extensibility.” That practically screams Staff+.
What are these companies where you have unlimited money to pay engineers to solve problems in less efficient ways??
My principal is: you don't have to do it right now, but make sure you could do it if you need to. This mainly comes down to avoiding assumptions. Simplifying assumptions can make things easier, but designs that don't leave room for extension make it really difficult to add those things later. It's a difficult balancing act, but I greatly appreciate any engineer who recognizes it and can manage it.