I said I’d move them to google sheets. There was about five minutes of awkwardness after that as I was interviewing for software developer. I was supposed to talk about what kind of tool I’d build.
I found it kind of eye opening but I’m still not sure what the right lesson to learn was.
The general way to handle this as an interviewer is really simple: acknowledge that the interviewee gave a good answer, but ask that for the purposes of evaluating their technical design skills that you'd like for them to design a new system/code a new implementation to solve this problem.
If the candidate isn't willing to suspend disbelief for the exercise, then you can consider that alongside all of the other signals your interviewer team gets about the candidate. I generally take it as a negative signal, not because I need conformance, but because I need someone who can work through honest technical disagreements.
As a candidate, what's worked for me before was to ask the interviewer if they'd prefer that I pretend ____ doesn't exist and come up with a new design, but it makes me question whether I want to join that team. IMO it's the systems design equivalent of the interviewer arguing with you about your valid algorithm because it's not the one the interviewer expects.
He got the prompt, asked questions about throughput requirements (etc.), and said, “okay, I’d put it all in Postgres.” He was correct! Postgres could more than handle the load.
He gets a call from Patrick Collison saying that he failed the interview and asking what happened. He explained himself, to which Patrick said, okay, well yes you might be right but you also understand what the point of the interview is.
They made him do it again and he passed.
I realize this is part of an interview game, but perhaps the best response is still to ask why this is a problem in the first place before you launch into a technical masterpiece. Force the counterparty to provide specific (contrived) reasons that this practice is not working for the business. Then, go about it like you otherwise would have.
There are a lot of good reasons for not using Google Sheets. Maybe the spreadsheet is using features that Google Sheet doesn't support, maybe one of the parties is in China, where Google services are blocked, maybe it is against company policy to use Google Docs, maybe they have limited connectivity.
It is good to acknowledge the obvious, off the shelf solutions, but if you are given a job, that's either because the customer did their homework and found out that no, it is indeed not appropriate, or, for some reason, they have money burning their pockets and they want a custom solution, just because. In both cases that's how you are getting paid. So, I don't consider "use Google Sheets, you idiot" to be an appropriate answer. Understand the customer specific needs, that's your job, even more so in the age of AI.
And maybe the interviewer will be honest and say "just assume you can't, this is just an exercise in software architecture".
https://sites.google.com/site/steveyegge2/five-essential-pho...
Question three is this:
Last year my team had to remove all the phone numbers from 50,000 Amazon web page templates, since many of the numbers were no longer in service, and we also wanted to route all customer contacts through a single page.
Let's say you're on my team, and we have to identify the pages having probable U.S. phone numbers in them. To simplify the problem slightly, assume we have 50,000 HTML files in a Unix directory tree, under a directory called "/website". We have 2 days to get a list of file paths to the editorial staff. You need to give me a list of the .html files in this directory tree that appear to contain phone numbers in the following two formats: (xxx) xxx-xxxx and xxx-xxx-xxxx.
How would you solve this problem? Keep in mind our team is on a short (2-day) timeline.
In Yegge's case, he explicitly does NOT want a hand-written program, he wants the candidate to suggest a CLI tool, e.g.
grep -l -R --perl-regexp "\b(\(\d{3}\)\s|\d{3}-)\d{3}-\d{4}\b" > output.txt
———
So...
These questions aren't good or bad unto themselves, but when the person asking is engaging in "Guess the answer I'm thinking of," don't beat yourself up if you guessed wrong. Your answer might be prized by someone else with an enormous amount of experience hiring engineers.
These days if I were interviewing someone and they said, "I'd use the simple solution that is fairly ubiquitous", I'd say, "yes! you've now saved yourself tons of engineering hours - and you've saved the company eng money".
I would have said the exact same thing and pushed the interview to consider 'why are we creating a tool when something off the shelf solves our business needs? What kind of runway and resources do I have to meet this goal? What is good enough for our problem here? Do we want to expand our scope to enable external data integration and downstream data consumption"
You will find better employment outside the circus, possibly even selling to the circus
As an interviewee it’s important to try and identify whether the group you’re interviewing with operates this way, literally: How will they get the money to pay for your salary? That way you avoid giving nom-starter answers to interview questions.
I don't think any of my applicants so far has double clicked the file to open it in Excel, plotted the data, and saw just how linear it was. You could follow the line with your finger and come up with a decent prediction. Maybe do that in ggplot2 or matplotlib if you want to show you can write code. Even a quick lm(dta$attendance ~ dta$date) would get you great results.
Spreadsheets are a tricky one some people like the power and automomy they have with spreadsheets.
But more often spreadsheets are the only way to transfer data between solos and it wastes a lot of time and is error-prone.
I'd actually trust you to take on harder problems
Doesn't really matter what the situation is, there's much more that can be achieved in my book with that kind of mindset :)
I'm also of the opinion that in an increasingly LLM software written world, being able to have this kind of mindset will actually be really valuable
Sometimes we'll ask market sizing questions. We will say it's a case question, it's to see their thought process, they're supposed to ask questions, state assumptions, etc.
Occasionally we'd get a candidate that just doesn't get it. They respond "oh I'd Google that". And I'll coach them back but they just can't get past that. It's about seeing how you approach problems when you can't just Google the answer, and we use general topics that are easily accessible to do so. But the downside is yes, you can google the answer.
I get that "communicate your thought process" or "play along with the exercise" gets offered as the fix here. But that framing bothers me too. Why should simplicity require more justification than complexity? Google Sheets is the design. The fact that it doesn't sound like engineering is the whole point.
I'm just not convinced the solution is learning to package simplicity in a more impressive wrapper.I looked at the formula, and drew two wires, connecting a couple of the leads from the input, to the output.
I was offered the job, but ended up declining it.
Then after a brief discussion of that you could actually ask if the purpose of the question was for you to design a system to handle that situation and jump into the design.
e.g. no access to internet (or at least VPN access via completely locked down devices) / internal email server / only open source etc.
Exactly because that means less costs for software development when deliverying solutions.
At least from the point of view of the interviewer, this was the point where they should give you a polite "hey, play along" nudge.
So now you get Engineer B's output even faster, with even more impressive-sounding abstractions, and the promotion packet writes itself in minutes too. Meanwhile the actual cost - debugging, onboarding, incident response at 3am - stays exactly the same or gets worse, because now nobody fully understands what was generated.
The real test for simplicity has always been: can the next person who touches this code understand it without asking you? AI-generated complexity fails that test spectacularly.
To be fair, a lot of the on call people being pulled in at 3am before LLMs existed didn't understand the systems they were supporting very well, either. This will definitely make it worse, though.
I think part of charting a safe career path now involves evaluating how strong any given org's culture of understanding the code and stack is. I definitely do not ever want to be in a position again where no one in the whole place knows how something works while the higher-ups are having a meltdown because something critical broke.
I like to have something like the following in AGENTS.md:
## Guiding Principles - Optimise for long-term maintainability - KISS - YAGNI
Avoid hands-on tech/team lead positions like hell.
But given how poorly bought software tends to fit the use case of the person it was bought for... eventually generate-something-custom will start making more and more sense.
If you end up generating something that nobody understands, then when you quit and get a new job, somebody else will probably use your project as context for generating something that suits the way they want to solve that problem. Time will have passed, so the needs will have changed, they'll end up with something different. They'll also only partially understand it, but the gaps will be in different places this time around. Overall I think it'll be an improvement because there will be less distance (both in time and along the social graph) between the software's user its creator--them being most of the time the same person.
Biggest problem is that next person is me 6 months later :) but even when it’s not a next person problem how much of the design I can just keep in my mind at a given time, ironically AI has the exact same problem aka context window
Currently they can't. Anyone with a basic understand of sw engineering will find numerous issues with the result of such a prompt within minutes.
In the FAANGs I've worked at, engineers who come from scrappy companies and implement hacks (Like the example of emailing spreadsheets around) undermine the business and will cost the productivity of thousands of people.
However, at the startups I've worked at, the folks from big companies that try to implement a super complex thing (e.g. exotic databases, overly ambitious infrastructure) The results are equally catastrophic for a company attempting to bootstrap when the complexity is so far removed from their core business.
What makes an experienced engineer is recognizing both states, understanding what works where and making the right trade-offs, usually from experience you can't fake your way through. I've seen a lot of projects that took 10-20 engineers 18 months to so we could sell something that landed a $100M contract with a customer. You see that enough times and you won't bias as hard against complexity. But of course it's situation dependent, like anything.
For some reason, this middle ground gets the smallest population.
Even just taking fault incidence rates, assuming constant injection per dev hour...
In many ways, the Door Desk award was for simplicity. I remember, one time, someone got an award for getting rid of some dumb operations room with some big unused LCD TVs. When you won these awards, you rarely got any kind of reward. It was just acknowledgement at the meeting. But that time, they literally gave the guy the TVs.
(amzn 94-96)
"Dorsk" (not the Jedi).
"Reduced incidents by 80%", "Decreased costs by 40%", "Increased performance by 33% while decreasing server footprint by 25%"
Simplicity for its own sake is not valued. The results of simplicity are highly valued.
Building a system that's fast on day one will not usually be rewarded as well as building a slow system and making it 80% faster.
That's regardless of the lip service they pay to cost cutting or risk reduction. It will only get worse, in the AI economy it's all about growth.
(when there is a simpler design over more complex "big ball of mud abomination" in contrast)
My experience is no one really gets promoted/rewarded for these types of things or at least not beyond an initial one-off pat on the back. All anyone cares about is feature release velocity.
If it's even possible to reduce incidents by 80% then either your org had a very high tolerance for basically daily issues which you've now reduced to weekly, or they were already infrequent enough that 80% less takes you from 4/year to 1/year.. which is imperceptible to management and users.
The longest lived projects and solutions I've worked on have always been the simplest, easiest to replace solutions. Often derived from simple tests scenarios or solutions that just work and get shifted over without much re-work.
What's somewhat funny, with this is that AI code assistants have actually helped a lot with continuing this approach for me... I can create a stand alone solution to work on a library or component, work through the problems, then copy the component/library into the actual work project it was for. I'm in a really locked down internalized environment, so using AI for component dev is on my own hardware... but the resulting work is a piece that can be brought in as-is. No exposure of internal data/resources.
I don't think I'll have a level of trust to "one-shot" or vibe code solutions from AI, but leveraging the ability to spin up a project as a sample to test a component/library is pretty great to say the least.
I often end up saying, "I can build this, and I will build this if product insists on it, but first let me suggest an alternative ordering of deliverables that starts with a simple implementation and moves towards this one." In almost every case, that simple implementation is still what's in production years later.
Don't even get me started on the resume-driven development that came along with it.
And maybe I'm completely wrong. This is a perspective of one.
In the hands of an experienced developer/designer, AI will help them achieve a good result faster.
In the hands of someone inexperienced, out of their depth, AI will just help them create a mess faster, and without the skill to assess what's been generated they may not even know it.
I feel/am way more productive using chatgpt codex and it especially helps me getting stuff done I didn't want to get started with before. But the amount of literal slop where people post about their new vim plugin that's entirely vibecoded without any in-depth thinking about the problem domain etc. is a horrible trend.
Slightly related: I've noticed that there are lots of "ideas guys" (yes, guys) in our field who love to bloviate, and maybe even accomplish some stuff that looks really good. I have made a career out of just putting my head down and getting shit done. I may not have grand design ideas, and in fact have had to unlearn the "fact" that you need to come up with, and implement, Big Ideas. In my experience, people who "get shit done" may not get fancy awards, but their work is recognized and rewarded.
Not if management is moving at the speed of the more complex solution.
> yes, guys
I thought that blatant sexism wasn't a part of this website.
> In my experience, people who "get shit done" may not get fancy awards, but their work is recognized and rewarded.
top kek
As a manager, I preferred engineers that delivered simpler code, but I also ran a team of experienced, high-functioning coders. I suspect teams with many less-experienced people get The Parable of The Toaster[0].
Too often the smallest changeset is, yes, simple, but totally unaware of the surrounding context, breaks expectations and conventions, causes race conditions, etc.
The good bit in tfa is near the end:
> when someone asks “shouldn’t we future-proof this?”, don’t just cave and go add layers. Try: “Here’s what it would take to add that later if we need it, and here’s what it costs us to add it now. I think we wait.” You’re not pushing back, but showing you’ve done your homework. You considered the complexity and chose not to take it on.
The answer to this is almost always "NO" in my experience, because no one ever actually has good suggestions when it comes up. It's never "should we choose a scalable compute/database platform?" It's always "should we build a complex abstraction layer in case we want to use multiple blob storage systems that will only contain the lowest common denominator of features of both AND require constant maintenance AND have weird bugs and performance issues because I think I'm smarter than AWS/Google AND ALSO we have no plans to actually DO that?"
/I'm not bitter...
For example, if you implement a job framework of things calling a REST API to do stuff async, a sufficient first implementation is a simple monolith doing the stuff and some retries or periodic calls. Because, if it does not scale, we can start thinking about replacing that with something to put things into queues and scaling stuff-doers horizontally and such. But often enough, these simple things scale quite the distance.
On the other hand, if you start introducing in-memory caches into a singular instance to taper around database performance... that's a huge issue. That always leads to pain.
Additionally though, I"ve started to keep notes about people doing simple, efficient things without fanfare. This way, if my boss asks me what Bob did over the year, I can tell them that Bob made these problems disappear and how Bob is starting to handle this area of topics more and more. Suddenly Bob is growing responsible for this area, and if my boss asks Bob about these topics they did well in an annual review, Bob can shine. Hope they learn though.
Software dev's tendency to build castles is great for technical managers who want to own complex systems to gain organizational leverage. Worse is better in this context. Even when it makes people who understand cringe.
You would think that things not breaking should be career-positive for SysAdmins, SREs, and DevOps engineers in a way it cannot be for software devs. But even there simplicity is hard and not really rewarded.
Unix philosophy got this right 50 years ago — small tools, composability, do one thing well. Unix reimagined for AI is my attempt to change that.
A lot of this boils down to promo system being so systematized. I've never heard of people in any other field min/max their promotions as hard along with all of the expert jargon in any other field I've worked in. Packets, peers, comp, other co comps, what your boss thinks of you, what your boss thinks of your peers (nee: competitors), and the inevitable crash out when they don't get the promotion. All part of the bigco experience! I feel like when we systematized comp into ranks Lx, Ly we gave up our leverage a little bit.
The irony is that the elaborate design usually handles those hypotheticals incorrectly anyway, because you can't predict real requirements from imagination. The simple version gets modified when real feedback arrives, and the modifications are cheaper because there's less architecture to work around.
Instead you talk about how you complete all your tasks and have so much bandwidth remaining compared to all your peers, the beneficial results of simplicity. Being severely under used while demonstrating the ability to do 2x-10x more work than everybody else is what gets you promoted.
In this vein simplicity is like hard work. Nobody gives a shit about hard work either. Actually, if all you have to show is how hard you work you are a liability. Instead its all about how little you work provided and that you accomplish the same, or more, than everybody else.
Ideally we need metrics saying, "my projects require 30% less support or 50% less brainpower than comparable projects". Things like "average cyclomatic complexity", etc.
If every company I know does this, how am I suppose to make money?
There are reasons for "unnecessary" complexity. Mainly cost and time.
Why? We learn all these cool patterns and techniques to address existing complexity. We get to fight TRexes… and so we get paid good money (compared to other jobs). No one is gonna pay me 120K in europe to build simple stuff that can work in a single sqlite db with a php fronted.
I guess it may be important to underscore the value that simplicity provides over needless complexity or to sell people on the value of problems prevented rather than preventable catastrophes that were dealt with
Maybe we could encourage a culture of patting people on the back for maintaining reliable "boring" systems
Some people also crave "drama" so there might be a way to frame "boring reliability" as some kind of "epic daily maintenance struggle that was successfully navigated"
As engineers, we tend to keep away from the limelight and quietly get shit done and be happy with it. But professional growth and recognition requires visibility somehow. We need to be creative on how to achieve that.
More than once I have seen the same project yield two separate promotions, for creating it and deleting it. In particular this happens when the timescale of projects is longer than a single engineer's tenure on a given team.
But yes, avoiding complexity is rarely rewarded. The only way in which it helps you get promoted is that each simple thing takes less time and breaks less often, so you actually get more done.
In fact, simplicity often is the best future-proofing. Complex designs come with maintenance costs, so simple designs are inherently more robust to reorgs, shifted priorities, and team downsizing.
It's not just the most "elaborate system". The same thing happens in so many other ways. For example a good/simple solution is one and done. Whereas a complex one will be an interminable cause of indirect issued down the road. With the second engineer being the one fixing them.
Then there's another pattern of the 10x (not the case with all 10x-ers) seeding or asked to "fix" other projects, then moving on to the next, leaving all the debt to the team.
It's really an amazing dynamic that can be studied from a game theoretical perspective. It's perhaps one of the adjacent behaviors that support the Gervais principle.
It's also likely going to be over soon, now that AI is normalizing a lot of this work.
I built a showback model at a prior org. Re-used shelfware for the POC, did the research on granular costs for storage, compute, real estate, electricity, HVAC maintenance, hardware amortization, the whole deal. Could tell you down to the penny how much a given estate cost on-prem.
Simple. Elegant. $0 in spend to get running in production, modest spend to expand into public cloud (licensing, mainly). Went absolutely nowhere.
Got RIFed. On the way out the door, I hear a whole-ass team did the same thing, using additional budget, with lower confidence results. The biggest difference of all? My model gave you the actual cost in local currency, theirs gave you an imagined score.
The complexity (cost of a team, unnecessary scoring) was rewarded, not the simplicity.
It was a 8 bit embedded application in something like 10k of code. When I left I generated a short and clear explanation of why what I had done was awesome in terms of their future business ... because that is what you have to do if you work contracts. Which is the real message of the article. You have to write things up.
> You have to write things up.
...and someone has to read it who understands the value you brought by deleting complexity.
As a consultant/contractor I always evangelise simplification and modelling problems from first principles. I jump between companies every 6-12 months, cleaning up after years of complexity-driven development, or outright designing robust systems that anybody (not just the author) can maintain and extend.
This level of honesty helps you build a reputation. I am never short for work. I also bill more than I could ever as a full-time engineer based in Europe.
Rarely have I seen an actually straightforward, simple feature that can be done in a day used as the basis to spin up a 3-week mini-project with a complicated new architecure.
What happens is a complicated-sounding feature is requested, and some devs will just take it literally and implement it, maybe along with some amount of "future-proofing" that logically follows because the spec is poorly scoped.
Other devs will spend some time thinking about it, realize that there is a really a simple requirement at the core of the request, and it only sounds complex because it was vaguely specified (or maybe these days an LLM was used to write the spec, and its vomit was copy-pasted verbatim). They just implement the simple thing that is the actual need.
This is one place where the agile/scrum practice of planning poker can help. You get a few smart people in a room, and discuss the story and its requirements. Hopefully someone will throw out a low number of points and say "isn't this simply asking for..."
Over my career, most of the complicated code I have written is no longer running. What is still running after 10 years? Postgres (or more broadly, a relational database). Fad frameworks or architectures come and go pretty quickly, they don't end up working as advertised, and it's on to the next thing. I no longer want to spend time in this hamster wheel churning out complicated code that will only end up as next year's tech debt.
Instead I went to the hardware store across the street and bought the biggest (and cheapest) screwdriver I could find and attached it with some cord to the HSM. They never lost it afterwards.
At core, complexity is derived from discovery of demand within those pesky complex humans.
Simplicity is the mechanism of finding common pathways within the mess of complexity of a product.
the tragedy is that simplicity is very expensive and beyond most organizations ability to support (especially since it can slow down demand discovery), and this is one of the allures of big tech for me. I was greatly rewarded and promoted for achieving simplicity within infrastructure.
> But for Engineer A’s work, there’s almost nothing to say. “Implemented feature X.” Three words. Her work was better. But it’s invisible because of how simple she made it look. You can’t write a compelling narrative about the thing you didn’t build. Nobody gets promoted for the complexity they avoided.
Well, Engineer A's manager should help her writing a better version of her output. It's not easy, but it's their work. And if this simpler solution was actually better for the company, it should be highlighted how in terms that make sense for the business. I might be naive and too optimistic but good engineers with decent enough managers will stand out in the long run. That doesn't exclude that a few "bad" engineers can game their way up at the same time, even in functional organizations. though.
There's a significant asymmetry though, it's not just a bit more work. I'm a bit cynical here, but often it's easier to just overengineer and be safe than to defend a simple solution; obviously depending on the organization and its culture.
When you have a complex solution and an alternative is stacked up against it, everything usually boils down to a few tradeoffs. The simple solution is generally the one with the most tradeoffs to explain: why no HA, why no queuing, why no horizontally scalable, why no persistence, why no redundancy, why no retry, etc. Obviously not all of them will apply, but also obviously the optics of the extensive questioning will hinder any promotion even if you successfully justify everything.
Simpler than what? The reason this phenomenon is so pervasive in the first place is that people can’t know the alternatives. To a bystander (ie managers), a complex solution is proof of a complex problem. And a simple solution, well anyone could have done that! Right?
If we want to reward simplicity we have to switch reference frame from output (the solution), to input (the problem).
I had to stop trying to prove myself to the company. I have already done that when y'all interviewed me. Now I do what's best for everyone, and I want the company to prove to me that it deserves people who do the right thing despite the processes not valuing it. If it does not, I have enough resources to spend some time on the projects I cared about most.
This mentality gave me peace of mind and helped many people in partner teams go faster and with higher quality.
Management still does not openly appreciate it, but it shows in how they interact with me. Like when you learn to talk to your parents as equals. It's unexpected for them, but they quickly embrace the new interaction and they love it much more than the one before.
BUT, at least very occasionally I have seen people get promoted for simplicity, I've even successfully made the case myself. With a problem that was itself so complex that it was causing fires on a regular basis, and staff & principal engineers didn't want to touch it with a ten foot pole. When a senior eng spent a couple of weeks thinking about the problem and eventually figured out a way to reframe it and simplify the solution, melting away months of work, making the promo case was actually quite easy.
The problem is, the opportunities to burn down complexity like that don't present themselves nearly as often as the opportunities to overcomplicate a thing, which are pretty much unbounded.
It's hard to keep things simple. Management should be mindful of that and encourage engineers to follow YAGNI, to do refactorings that remove more code than they add, etc.
The sad thing is that it is common to get fired when you make things better bc then your work is perceived as "done" and your skills are no longer necessary. There are countless IT job stories where someone delivers a technical solution that saves a company a ton of money or generates revenue, then they get fired bc the solution has been delivered and an off shore team has been hired to maintain the work.
Big corps suck.
Edit -- reading some the responses here on this topic and they are...eye-opening and depressing.
It could be something overbuilt, large organization structures. Brittle solutions that are highly performant until they break. Or products/offerings that don't grow for similar reasons, simpler-is-better, don't compete with yourself. Or those that grow the wrong way-- too many, much to manage, frailty through complexity, sku confusion.
Alternatively, things that are allowed to grow with some leeway, some caution, and then pruned back.
There's failure modes in any of these but the one I see most often is overreaching concern for any single one.
— C. A. R. Hoare
[0] https://www.theguardian.com/technology/2014/feb/25/apples-ss...
The environment where the over-engineer tends to be promoted is one where the engineering department is (too) far separated from where the end users are. Think of very large organizations with walled departments, or organizations where there simply is not enough to do so engineers start to build stuff to fight non existing issues.
You can try to explain this OP’s concept to a stakeholder in a 1000 different sensible ways and you’ll get blinking deer-in-headlight eyes back at you.
This skill is hard-earned and, so, rare.
Therefore, many hierarchies are built on sufficient mediocrity top to bottom.
Which works because bottom line doesn’t often matter in software dev anyway.
And even when it does matter it’s multiplicatively rare to have a hierarchy or even the market that it tries to serve who can build, comprehend, handle high power::complexity systems, products, tools.
it just isn't very appetising
I've only worked at my startup so I can't comment on scale elsewhere, but if our simple architecture can handle 30k requests per second, I think it can handle most other companies scale too.
Good leaders perceive workhorse vs showhorse spectrum, critical toil vs needless flash (and vice versa).
It’s hard. Most fail at hard things. The industry in the aggregate will fail at hard things
So you get articles like this.
I'm currently building a full-blown OpenAPI toolchain at work, where the OpenAPI document itself is the AST. It contains passes for reference inlining, document merging, JSON Schema validation, C++ code generation and has further plans for data model bindings, HTML5 UI...
Why? Because I'm working on a new embedded system which has a data model so complex, it blew past 10k lines of OpenAPI specifications with no end in sight. I said "ain't no way we're implementing this by hand" and embarked on the mother of all yak shavings.
I want all of the boilerplate/glue code derived from a single source of truth: base C++ data classes, data model bindings, configuration management, change notifications, REST API, state replication for device twins and more. That way we can focus on the domain logic instead, which is already plenty complex on its own.
I'm not designing all of this to be simple to develop. I'm designing it so that it's simple for the developers. Even with the incomplete prototype I have currently, the team is already sold ("you mean I just write the REST API specification and it generates all of the C++ classes for me to inherit?"). The roadmap of features for that toolchain is defined, clear and purposeful: to delete mountains of menial, bug-prone source code before it is ever written by hand.
Sometimes, it takes complexity to deliver simplicity. The trick is to nail the abstractions in-between.
Essentially, there are two parallel teams, one is seen constantly huddling together, working late, fixing their (broken) service. The other team is quiet, leaves on time, their service never has serious issues. Which do you think looks better from the outside?
Promotions are supposed to incentivise people to stay, rather than leave. If the company never promoted anyone, people would leave. So there needs to be a path for promoting people. But that process doesn’t have to be transparent, or consistent, or fair - in-fact it rarely is.
You promote people who consistently overdeliver, on time, at or below cost, who are a pleasure to work with, who would benefit the company long term, who would be a pain to lose. A key precondition is that such people consistently get more done compared to other people with equal pay, otherwise, they don’t stand out and they are not promotion material.
What counts as overdelivering will vary based on specific circumstances. It’s a subjective metric. Are you involved with a highly visible project, or are you working on some BS nobody would miss if it got axed? Are you part of a small team, or are you in a bloated, saturated org? Are you the go-to person when shit hits the fan, or are you a nobody people don’t talk to? Are you consistent, or are you vague and unpredictable? Does your work impact any relevant bottom lines, or are you just part of a cost centre? It really isn’t rocket science, for the most part.
Numerous times I've seen promotions going to people who were visible but didn't do the actual work. Those who share the achievements on Slack, those who talk a lot, get to meetings with directors, those who try to present the work.
In my (limited) experience as an engineer and manager, leadership (e.g., a VP) didn’t like (or reward) simplicity. Simple solutions often meant smaller teams, which wasn’t something they were pushing for, especially pre-2024. I do think this is slowly evolving, and that the best leaders now focus on removing unnecessary complexity and improving velocity.
This extends to suggesting huge licenses like from Salesforce. The Marketing and HR teams are ecstatic that they can purchase another license of their favorite software, they can go shopping! If I had implemented a free and more efficient CRM, there would be no networking effect.
This all builds systems that are vastly more expensive (to the tune of hundreds of thousands of dollars), slower, and much harder to fix. YCombinator financially benefits from this and it's all very corrupt. Most of the time, I have to really gain the "soft skills" to activate the networking (nepotism) effects.
It's not about what you know, it's about who you know.
"Premature flexibilization is the root of all evil that is left":
https://product.hubspot.com/blog/bid/7271/premature-flexibil...
I've noticed the incentive breaks down even further when you consider that simplicity often means saying no upfront, which requires correctly predicting future maintenance costs that nobody has experienced yet. Complexity requires no such foresight. You just build the thing someone asked for.
The orgs where I've seen this actually work had explicit "deleted lines" culture, where removing code was celebrated as loudly as shipping features. Not many places do that. Most treat a 2000-line deletion PR with the same energy as taking out the trash.
I got emotional reading this. This is way too real.
Also survivorship bias is a very real thing (problem prevented is ignored, while problem solved is appreciated regardless of who and why caused it).
Can you actually imagine a promo committee evaluating the technical choices? "Ok, this looks pretty complex. I feel like you could have just used a DB table, though? Denied."
Absolutely not! That discussion happens in RFCs, in architecture reviews, in hallway meetings, and a dozen other places.
If you want simplicity, you need to encourage mentorship, peer review, and meaningful participation in consensus-building. You need to reward team-first behavior and discourage lone-wolf brilliance. This is primarily a leadership job, but everybody contributes.
But that's harder than complaining that everything seems complicated.
A committee with no skin in the game, who knows? But a manager who actually needs stuff done, absolutely.
a) finding a new theoretical frame that simplifies the space or solutions, helps people think through it in a principled way
b) finding ways to use existing abstractions, that others may not have been able to find
c) using non-technical levers, like working at the org/business/UX level to cut scope, simplify requirements,
The way you can make complexity work for your career, is to make it clear why the problem is complex, and then what you did to simplify the problem. If you just present a simple solution, no one will get it. It’s like “showing your work”.
In some orgs, this is hopeless, as they really do reward complexity of implementation.
The service saw maybe a few hundred transaction per day, total database size: 2 - 3GB. The systems would hold data about each transaction, until processed and then age it out over three months, making the database size fairly stable.
Talking to a developer advocate for Azure we learned that CosmosDB would get a Cassandra API and we got access to the preview. The client was presented with a solution were the service would run as a single container in Azure Websites and using CosmosDB as the database backend. The whole thing could run within the free tier at that point. Massive saving, much easier to manage. We got rejected because the solution didn't feel serious and to simplistic for an organisation of their scale.
On the other hand I also once replaced a BizzTalk server with 50 lines of C# and that was well received by the client, less so of my boss who now couldn't keep sending the bill for a "BizzTalk support contract" (which we honestly couldn't honour anyway).
- CV-driven development. Adding {buzzword} with {in production} sounds better than saying I managed to make simple solutions faster.
- Job security. Those who wish to stay longer make things complicated, unsupportable, and unmaintainable, so they become irreplaceable.
“Everything should be made as simple as possible, but not simpler.”
Or, more fully [1]:
“It can scarcely be denied that the supreme goal of all theory is to make the irreducible basic elements as simple and as few as possible without having to surrender the adequate representation of a single datum of experience.”
[1] https://www.makingthemuseum.com/newsletter/the-einstein-rule...
By chance, recently in an architecture discussion document I added that one of aspects to consider is how easy is to remove (the whole thing) if it's not wanted anymore.
It was an obvious case because it was an AI capability, which can be become deprecated/useless/too-risky very fast.
Of course, over-simplification is the wrong decision some times, the same as abstraction and complexity is the wrong decision some times...
Your shortcut for promotion is generally building value for the company, but people need to remember that promotions support the business and they aren't free to the company.
They take less to review and maintain etc, but the credit for those positives aren't assigned to the original engineer. Which is the point of the article.
One thing engineers can do to fight this, and I think it's mentioned in the article, is to write extensive documentation. Bosses in these companies are too lazy to dig into solutions and figure out for themselves; so they resort to proxies like the number of lines of code, number of pages in the design doc, etc.
Unfortunately, some of us who aim for simplicity are also averse to writing long docs; but with the advent of LLMs, there is some relief in sight.
My career has suffered a lot in terms of promos, etc. because I hate complexity.
Since one of microservice's benefits is solving a coordination problem, now that teams are getting smaller due to AI, I wonder if we will see monoliths make a resurgence in some cases.
And complexity doesn't always sell better. A lot of times it might look like the whole thing is messy, or too hard to maintain, tech burden nightmare. Things that are simple might look complex and vice versa too, I think anyone who had to implement requirements from people who don't understand the implementation complexities will know this very well.
In smaller companies it's a lot easier to express the distinctions and values of simplicity to ears that might actually appreciate it (so long as you can translate it into what they value - simple example is pointing out that you produced the same result in much less time, and that you can get more done on overall feature/task level as a result).
Rather than trying to anticipate all the different failure modes one tries at first just to handle fact of failure itself, assuming there's no remediation.
If there's a way to make sure the worst case isn't terrible in some simple way then you do that first - like making a backup file or tr4ying to keep APIs idempotent so you can recover from issues and so on.
I don't think this phenomenon is unique to programming. My plumber was explaining how he put in a manifold and centralized whole-house off valve accessible indoors and I was like, okay, thanks? I can just turn it off at the street.
Only established professionals have the status and self-confidence to show restraint. I think that explains interviews.
We have a calendar reminder to exercise the valves in our house yearly, and the fact that they’re easy to get at helps make sure it’s a quick job, not a tedious one.
Not a plumber, but have lived in enough old houses with iffy valves to have been bitten a few times.
* You can have a bunch of simple code for a latent or implicit concept that is complex; and that making the code more complex might make the reflect principle simpler.
* You have trade-offs: If one aspect is simple, other aspects must become more complex to accommodate.
* There is no consensus over what constitutes complex vs simple code.
It's often simpler to build something you know than to integrate a 3rd party service, but it's highly frowned upon by a lot of devs and management.
Auth and analytics are things I'm thinking of - we have good tools to build these in-house. Also just running a database - never seen so many people afraid of installing postgres and a cronjob to back it up.
It can even happen that the tag "very smart" gets attached to those sidelined engineers. That's not necessarily a compliment.
Simplicity is worth recognizing only when the person started with a complex problem and ended up with a relatively simpler solution.
For a straightforward ask you will have people who will just build a hut and another will build a campus, who is right really depends on many factors and time.
And long before performance review time, I'd have mentioned further up that A was looking like a 5X engineer - best if we keep her happy.
The real question is how do you tell engineer A who can figure out how to make the complex problems simple from engineer C who can't handle complexity and so writes simple solutions when the complex one is needed.
This was the model at my last job. The "director" of software had strong opinions about the most random topics and talked about them like they would be revolutionary. His team was so far from the product teams they would just build random crap that was unhelpful but technically demo'ed well. Never put into practice. Promoted for 4 years, then fired.
Take these two alternatives:
class UserService {
PostgresDatabase db;
}
class UserService {
IDatabase db;
}
There are some coworkers who will veto the first example for being too complex, because it brings Postgres (and its state and connections and exceptions and mappings) into the scope of what otherwise could have been a service concerning Users.There are some coworkers who will veto the second example for being too complex, because Postgres is all you use for now, and if you really need to use a second database, you can change the code then (YAGNI). Also the Interface gives you a pointless indirection that breaks IntelliSense so you can't just 'click-through' to follow the code flow.
I on the other hand spent 3 weeks optimizing our core service and reduced 2x the opex costs of the large complex 3 year migration.
In my yearly review my manager acknowledged my impact, but said I need to solve more complex problems to get to Staff Engineer. I protested saying that my 3 weeks of work had a larger impact than 20 engineers over 3 years, but he told me that is just how it works.
The obvious outcome will be that the most skilled pretenders optimizing for their selfish profit narrow view, no matter what the consequences will be for the collectivity on large scale and at long terms.
So the way we write software piecemeal today is fundamentally broken. Rather than starting with frameworks and adding individual packages, we should be starting with everything and let the compiler do tree shaking/dead code elimination.
Of course nobody does it that way, so we don't know what we're missing out on. But I can tell you that early in my programming journey, I started with stuff like HyperCard that gave you everything, and I was never more productive than that down the road. Also early C/C++ projects in the 80s and 90s often used a globals.h header that gave you everything so you rarely had to write glue code. Contrast that with today, where nearly everything is just glue code (a REST API is basically a collection of headers).
A good middle ground is to write all necessary scaffolding up front, waterfall style, which is just exactly what the article argues against doing. Because it's 10 times harder to add it to an existing codebase. And 100 times harder to add it once customers start asking for use cases that should have been found during discovery and planning. This is the 1-10-100 rule of the cost of bugs, applied to conceptual flaws in a program's design.
I do miss seeing articles with clarity like this on HN though, even if I slightly disagree with this one's conclusions after working in the field for quite some time.
Your job is to deliver value. If you can get stuff done quicker and without it breaking, you did great. Some one who spent more time doing the same thing except took longer and has a more brittle solution they have to keep going back and fixing doesn't look good.
And simple solutions are easier to explain and convince people.
In case you ask “how can simple solutions be hard to understand and test?”
Lets just say you use single line bash scripts with multiple pipes, loops and very niche cmds.
It will work, it will look like nightmare, it will be simple -> one line.
Most of my engagements consisted of replacing politics-driven complications with simple solutions.
The bigger problem was first quietly showing all the affected people other interesting things that needed doing so they would let go.
And TBH, the simple stuff lasted the longest because it harder to misunderstand or misrepresent.
Adding extra things can always help, specially like in the UI side of things, since higher ups will probably just notice that part.
The engineer that consistently quotes 3x my expectation (and ends up taking 4x with bugs) is going to look way worse than the engineer that ships things quickly with no drama.
P.S. I know this sounds obvious, but I was a slow learner.
> The interviewer is like: “What about scalability? What if you have ten million users?”
This reminded me of how much more fun I find it to work on software that always only has one user, and where scaling problems are related solely to the data and GUI interaction design.
> Engineer B gets a similar feature. He also looks at the problem, but he sees an opportunity to build something more “robust.” He introduces a new abstraction layer, creates a pub/sub system for communication between components, adds a configuration framework so the feature is “extensible” for future use cases. It takes three weeks. There are multiple PRs. Lots of excited emojis when he shares the document explaining all of this.
So in this scenario two solutions are produced: Fast to develop but probably brittle (it is not described as robust, but it is described as easy to change), slow to develop but not brittle (but perhaps too complex and likely hard to change).
Both fucked up. Engineer A stopped too soon, and Engineer B built too much up before any value was realized.
You want Engineer C: Makes the fast solution that gives you feedback (is the feature worth pushing further? do users want/need it?), and continues to produce a more robust solution that won't crap the bed.
Engineer A is a potential chaos agent, tossing out and abandoning work too soon. Engineer B is a bottleneck who will waste weeks or months producing invalid solutions.
Go for the middle path.
I once hacked a spreadsheet in a week that was good enough to not embark on a multiple-months 3-devs project.
In the same team, I tweaked a configuration file for distributed calculations that shaved 2 minutes of calculation on an action that the user would run thirty times a day.
I got paid all right.
People don't give a shit about complexity or simplicity. They care about two things:
1. Does it work
2. How soon can you ship
There is a third thing that stakeholders really like: when you tell them what they should be building, or not building.
Be the change you want to see in the world. If you are in management, promote those that see the value in simplicity.
Problem is in big tech -- the incentives are all aligned towards complex stuff
you wanna get promoted - do complex stuff that doesn't make sense. If you get promoted, then it also boosts the performance of your manager.
the only way to escape this nonsense is to work at smaller companies
right now you've people advocating for A.I coded solutions yet never realizing that A.I solutions result in a convoluted mess since A.I never possesses the ART of software engineering i.e knowing what to cut out
> It also shows up in design reviews. An engineer proposes a clean, simple approach and gets hit with “shouldn’t we future-proof this?” So they go back and add layers they don’t need yet, abstractions for problems that might never materialize, flexibility for requirements nobody has asked for. Not because the problem demanded it, but because the room expected it.
$100 says the "clean, simple" approach is the one which directly couples the frontend to the backend to the database. Dependencies follow the control flow exactly, so that if you want to test the frontend, you must have the backend running. If you want to test the backend, you must have the database running.
The "abstractions for problems that might never materialize" are your harnesses for running real business logic under unit-test conditions, that is, instantly and deterministically.
If you do the "simple" thing now, and push away pesky "future-proofing" like architecting for testing, then "I will test this" becomes "I will test this later" becomes "You can't test this" becomes "You shouldn't test this."
What happened?
For example, person A implements the simple solution, gets the project done faster while person B over engineers, has seemingly impressive stuff to talk about but at the end of the day doesn't ship.
as a manager its constant fighting the pressure to build "Great software" that is way above what the company needs instead building working software that addresses customer needs in a timely manner.
My dude we are s startup with two servers and 20 customers, we do not need infinite scalability.
When a scientist says "simplicity" they mean "elegance". This is very different from "easy to understand". There's a reason that quote says simplicity is difficult to achieve. This doesn't seem in line with the author's examples. But it's easy to see what Dijkstra was talking about. Have you ever derived an equation in math or physics? You start one place, do a whole lot of work, and then you get out this "simple" thing. You could write pages of math to come up with an equation that uses only a few symbols. E=mc^2 is simple but getting there was very hard and took a lot of time, thinking, and abstraction.
The author conflates simplicity with speed, not with what the end result is and how well it solves the problem.
Why are CS people against abstraction? All we do is abstraction? We act like all abstraction is the same, and it's evil.
We have to be more nuanced. I could see the entire blog post written in the exact other way where engineer A gets promoted because they complete more tickets and engineer B doesn't because they take too long. But the reality is that from such a high level we can't determine which solution is right. Sometimes A's method is the best and sometimes B's is the best. But we don't know the impact. B's solution could create more problems, like the author suggests, but also it could solve many problems that don't end up appearing. Same for A's solution!
I don't like this over simplification and the author's conclusion is naïve. If we make everything understandable to everybody then it's a race to the bottom Who does it need to be understandable to? The senior? An experienced developer? A junior? A manager?
Don't get me wrong, there's tons of unnecessary complexity out there and that's bad too. But for that I'll reference Knuth's famous and misunderstood quote where he says "get a fucking profiler before optimizing things". He too is talking about elegance, but a balance of how we should prioritize things.
[0] Concern for Correctness as a Guiding Principle for Program Composition https://www.cs.utexas.edu/~EWD/transcriptions/EWD02xx/EWD288...