Latest / The Tech Career Podcast with Fexingo: Engineering Jobs, Interviews, and FAANG Career Strategy / How FAANG Engineers Stop Overengineering Their Code
Transcript
- Lucas: So it's June 22, 2026, and I just had a conversation with a friend at Amazon who told me his team spent three months building a generic data pipeline that could handle 'any future use case' — and then never used it for anything beyond the one simple query they had on day one. Luna: Oof. That's the overengineering trap. I see it all the time in code reviews. Someone adds an abstraction layer 'just in case' and suddenly a ten-line function turns into a hundred lines of interfaces and factories. Lucas: Exactly. And it's an especially seductive trap at FAANG companies, where the engineering culture rewards sophistication. You don't get promoted for writing something boring that works — or at least, that's the perception. But the cost is real. That team burned three months of capacity. Lucas: And look, there's a reason it happens. Senior engineers have seen systems that were impossible to extend because they cut corners early. So they swing hard in the other direction and overcorrect. Luna: Right. The trauma of past technical debt makes you want to build for every possible future. But the future is unpredictable. Most of those abstractions never pay off. Lucas: There's a principle for this — YAGNI. You Ain't Gonna Need It. It comes from extreme programming, but it applies everywhere. Build what you need now, not what you think you might need in six months. Luna: I feel like that's hard to sell in a performance-review culture where 'strategic thinking' is a rubric item. How do you convince your manager that deliberately building less is the right call? Lucas: You frame it as speed. 'I shipped this feature in two weeks instead of six because I didn't build the generic pipeline.' That's a concrete win — faster time to value, less code to maintain, easier to change later based on real feedback. Lucas: Honestly, if today's episode saves you even a week of overengineering, that's worth more than a coffee. And if it does, you know where to find us — buy me a coffee dot com slash fexingo. It's how we keep this thing ad-free and focused on real engineering craft. Luna: Yeah. And we genuinely read every message that comes with it. It's a small signal that what we're talking about actually lands. Lucas: Anyway — back to the pipeline story. My friend's team built this generic ingestion layer that could handle CSV, JSON, Avro, Parquet, the works. But the only data source they ever connected was a single JSON feed from an internal tool. All that flexibility was dead weight. Luna: And now they have to maintain it. Every time a dependency updates, they have to test all those unused paths. That's active technical debt — code that exists but isn't exercised. Lucas: Right. One rule I've seen work well is the 'two-minute whiteboard test.' If you can't sketch your design on a whiteboard in two minutes and have a peer understand it, it's too complex. Strip it down until you can. Luna: I like that. It forces you to focus on the core flow. I've used that in system design interviews too, actually — but it's just as useful for real architecture. Lucas: Another habit: when someone proposes an abstraction — a base class, a factory, a configuration file — ask them to name the concrete use case that requires it right now. Not 'we might need this later.' Right now. Luna: And if they can't? Then you push it out of the sprint. You can always add it later when the need actually materializes. Lucas: Exactly. There's a cost to adding complexity later, sure — but it's usually lower than the cost of carrying that complexity forever. Especially if that 'later' never comes. Luna: What about when the pressure comes from a senior engineer or a staff engineer? It's harder to push back when the person advocating for the abstraction outranks you. Lucas: That's the hardest case. I think the best approach is to ask data-driven questions. 'Can we quantify the expected number of future data sources? Can we start with the simple version and measure how long it takes to add a second source if we need it?' Often the answer is that the risk is low. Lucas: And if they still push, you can propose an RFC — a short document that explicitly justifies the abstraction with concrete scenarios. Writing it down forces clarity. A lot of overengineered designs collapse under the weight of their own documentation. Luna: That's smart. Because writing an RFC is work, and if the justification is weak, people will call it out in the review. Lucas: Right. And it creates a paper trail. Six months later, when that abstraction is still unused, you can point back and say 'remember this? We never needed it.' That's a learning moment for the team. Luna: So let's talk about the flip side — when is overengineering actually justified? I think there are cases where a little future-proofing makes sense. Lucas: I agree. The classic example is when you're building a public API. Once you release it, you can't change it without breaking clients. So you need to think about versioning and extensibility upfront. But that's a different category — it's about contract stability, not speculative features. Lucas: Another case is when the cost of changing later is astronomically high — like a database schema migration for a system with millions of users. If you know you'll need that second index eventually, adding it early is cheap insurance. Luna: But those are exceptions. Most of the time, the simplest thing that works is the right call. And I think the real skill is knowing the difference. Lucas: That's the engineering judgment you develop over years. And it's worth practicing deliberately. Every time you catch yourself thinking 'what if...' for a scenario that hasn't happened, stop and ask: 'What's the probability? And what's the cost of adding it later?' Luna: One more thing: I've seen teams that have 'overengineering retrospectives.' They look back at code that was overly complex and trace why it happened — was it fear? Was it a desire to use a cool new technology? Was it a manager pushing for 'enterprise readiness'? Lucas: That's a great practice. It normalizes the conversation. Overengineering isn't a personal failure — it's a systemic pattern. You fix it by making it discussable. Lucas: So to wrap up: when you sit down to write code today, ask yourself one question — 'What is the absolute minimum I can build to solve the problem in front of me?' Start there. You can always add more later. The code you don't write is the code that has zero bugs, zero maintenance, zero cognitive load. Luna: And that's a superpower, especially in 2026 when teams are being asked to do more with fewer resources. Simplicity isn't just elegant — it's efficient.