How to choose boring technology on purpose.

•

•

Spend Your Novelty Budget Somewhere Else

I remember sitting in a dark apartment at 3:14 AM, staring at a terminal window while a “revolutionary” distributed database I’d insisted on using three months prior systematically ate our entire production dataset. There was no Stack Overflow thread for this specific failure, no seasoned engineer to call, just me and the realization that I had traded sleep for a shiny new feature set we didn’t even need. People talk about innovation like it’s a moral imperative, but in a production environment, innovation is often just a fancy word for unvetted edge cases. Learning how to choose boring technology on purpose isn’t about being a Luddite; it’s about realizing that every new dependency is just a future outage waiting for its moment to shine.

I’m not here to sell you on a specific stack or argue about which framework is more “performant” in a synthetic benchmark. What I want to do is show you how to build a toolkit based on predictability and documentation rather than hype cycles. I’ll walk through my personal mental model for vetting tools, focusing on why the “boring” stuff is actually the most powerful thing you can bring to a platform team.

Table of Contents

Why I Prioritize Operational Reliability vs Innovation

Why I Prioritize Operational Reliability vs Innovation

The tension between operational reliability vs innovation is usually where the most expensive mistakes happen. In my experience, innovation isn’t just about using a new language or a bleeding-edge database; it’s about the features you ship to your users. If I spend my entire sprint wrestling with a distributed database that has no documentation and a community of three people, I haven’t actually innovated anything. I’ve just traded my engineering time for a massive amount of unplanned maintenance. I’ve learned the hard way that every new, shiny dependency is a potential liability that someone—usually me—will have to debug when the logs start screaming at midnight.

I tend to favor proven software stacks because they come with something a new framework can’t provide: scars. When you use a mature technology ecosystem, the edge cases have already been discovered, documented, and solved by thousands of other engineers. You aren’t the one finding the memory leak in the connection pool; someone else already did that three years ago. By choosing tools that offer predictable system performance, I’m not being “lazy” or “old-fashioned.” I’m intentionally minimizing architectural complexity so that when the system eventually does break, I can spend my time fixing the business logic instead of fighting the infrastructure.

Minimizing Architectural Complexity Before It Breaks Everything

Minimizing Architectural Complexity Before It Breaks Everything

Complexity is a silent killer. I’ve seen teams spend six months building a sophisticated, distributed event-driven architecture for a service that essentially just moves a few rows of data from a database to a cache. They thought they were being “future-proof,” but they were actually just building a labyrinth that no one could debug when the first race condition inevitably hit. To me, minimizing architectural complexity isn’t about being lazy or lacking ambition; it’s about acknowledging that every new moving part is a new way for the system to fail in a way you haven’t anticipated yet.

When I look at a new project, I try to ask: “What is the simplest way to achieve this that won’t require a specialized degree to maintain?” I prefer leaning on mature technology ecosystems where the edge cases have already been discovered, documented, and patched by thousands of other engineers. If I can solve a problem with a standard relational database and a well-structured monolith, I’m going to do that every single time. It might not look impressive on a resume, but it ensures predictable system performance and, more importantly, it means I won’t be staring at a distributed trace at 3:00 AM trying to figure out why a message vanished into the ether.

A few rules of thumb for when you're actually picking the stack

  • Look for the “boring” problems. If you’re choosing a database, don’t ask how fast it is in a benchmark; ask how many people have already written a blog post about how to recover it after a corrupted write. I’d rather use a tool with a thousand mediocre StackOverflow answers than one with ten brilliant ones.
  • Prioritize “Day 2” operations. It’s easy to get a new tool running in a local Docker container in twenty minutes. It’s much harder to figure out how to rotate its secrets, back up its state, or observe its internal metrics when it’s running in a production cluster at scale. If the tooling for maintenance is thin, the technology is too expensive.
  • Avoid the “New Version” trap. There is a massive difference between a technology that is mature and one that is currently in a state of constant, breaking API changes. I don’t mind using something older, but I hate being forced to rewrite my integration logic every three months because the maintainers decided to rename a core package.
  • Check the ecosystem, not just the syntax. A language is only as good as its library support for the things you actually do, like connecting to a specific message queue or handling weird character encodings in a legacy CSV. If you have to write your own drivers for basic infrastructure, you aren’t building a product; you’re building a toolkit.
  • Evaluate the “bus factor” of the community. If the entire success of a library depends on one guy in a specific time zone who hasn’t pushed a commit in six months, walk away. I want tools that are so widely used that if our lead engineer leaves, we can find someone else who already knows where the bodies are buried.

The Bottom Line

Choose tools based on how many people have already broken them in production, not how many stars they have on GitHub.

If a new technology doesn’t solve a problem you are currently losing sleep over, it’s just a distraction with a high maintenance cost.

Your goal isn’t to build the most sophisticated system; it’s to build the one that is easiest to debug when things inevitably go sideways at 2:00 AM.

The Trade-off is the Point

The Trade-off is the Point in tech.

At the end of the day, choosing boring technology isn’t about being a luddite or fearing progress; it’s about managing your cognitive load. We’ve talked about prioritizing operational reliability over the hype cycle, keeping our architecture simple enough to actually reason about, and avoiding the trap of complexity for complexity’s sake. When I look at a stack, I’m not asking “how cool is this?”, I’m asking “how many StackOverflow threads exist for this error message?” and “how many people can actually fix this at 3:00 AM?”. If the answer to those questions is “none,” then the tech is too expensive, no matter how low the licensing cost is. It’s a calculated trade-off between the thrill of the new and the stability of the known.

I’ve spent enough years chasing the “perfect” cutting-edge solution only to spend the next six months debugging the very tools that were supposed to save me time. My goal now is to build systems that are predictable. I want to write code that works, deploy it, and then actually get some sleep—or maybe go for a long bike ride without checking my phone every twenty minutes. Don’t feel guilty about picking the tool that everyone already knows how to use. In a world of constant technical churn, there is a profound, quiet power in building things that just stay working.

Frequently Asked Questions

How do you draw the line between "boring" and just being stuck in the past with tech that's actually dead?

There’s a difference between “boring” and “obsolete.” Boring is a tool that has a massive community, predictable failure modes, and a decade of Stack Overflow answers. It’s tech that stays out of your way. Obsolete is tech that no one maintains, where a single security patch takes three months to arrive. I don’t mind using an old version of Postgres; I mind using a library that hasn’t seen a commit since the Obama administration.

Won't choosing old tech make it harder to hire good engineers who want to work with modern tools?

I get this question a lot. The fear is that we’ll become a museum for legacy code and nobody will want to join the team. But I’ve found the opposite is true. Good engineers—the ones who actually solve problems—don’t care about the shiny new syntax; they care about building things that work. They want to solve interesting business problems, not spend their weekends debugging a framework that changes its API every six months.

Is there a specific way to test if a "boring" tool is actually stable enough for our specific scale?

I don’t rely on marketing benchmarks or “scale” whitepapers. I look for the edge cases. I usually run a stress test that mimics our specific traffic patterns—not just a generic load, but the weird, bursty, uneven reality of our actual production. If the tool chokes or, worse, fails silently when the connections spike, it’s not boring; it’s just untested. I’d rather find the breaking point in a controlled environment than during a Tuesday morning deployment.

How do you convince a product manager that spending time on a stable stack is better than shipping a new feature faster?

I don’t try to win this with architectural purity arguments; that’s a losing battle. Instead, I talk about the “tax.” I explain that every new, unproven tool comes with a hidden interest rate paid in debugging time and on-call rotations. If we ship this feature on a shaky stack, we aren’t actually moving faster—we’re just borrowing time from next month’s sprint to pay for today’s deployment. I show them the math on downtime.

Tomasz Wierzbicki

About Tomasz Wierzbicki

I am not interested in arguing about frameworks. I am interested in why the thing broke at two in the morning and what would have prevented it. Most of what I know came from being wrong in production and writing it down afterwards.