LanguagesDecember 15, 20254 min read
Go, Rust, Python: The Boring Truth About Choosing a Language
USAMA DARWASHI

Every few months the cycle repeats: a benchmark shows Go handling ten times the requests, a blog post celebrates rewriting a service in Rust for a 40x speedup, and a reply thread declares Python dead again. It's entertaining, and I read those threads like everyone else. But after six years of shipping software for regulators, telecom operators, and startups, I can say this with confidence: not a single project I've worked on succeeded or failed because of the programming language.
Projects succeed or fail because of deadlines, requirements, ownership, and whether anyone can trace a bug in production. The language was always a footnote.
Nobody gets paged over syntax
When people argue about languages, they argue about what you touch in the first week: syntax, the type system, how a toy benchmark performs. The things that actually hurt show up in month eight:
- The library that solved your hard problem stops getting commits, and its only maintainer disappears.
- The one engineer who truly understood the async runtime resigns.
- You need to hire two more developers, and your local market has fifty solid Java or Python engineers for every Rust candidate.
- Memory leaks in production, and nobody on the team has ever profiled this runtime under load.
None of these are language flaws. They are ecosystem, hiring, and operations questions, and they decide the outcome. When I led development of Sabr, the centralized analytics and monitoring platform of Oman's telecom regulator, we built the core on Spring Boot and PostgreSQL. Not because Java is exciting; it isn't, and that's precisely the point. A system a regulator depends on will live for years and pass through many hands. The boring machinery, from transactions and scheduled jobs to auth integration and metrics, had two decades of production hardening behind it. That mattered more than any benchmark.
When FastAPI beat Spring Boot, and when it lost
I'm not an "always pick the JVM" person. At Byanat we built an analytics platform for Ooredoo covering roughly 300K M2M/IoT SIMs, and FastAPI won there, clearly. The workload was data analysis wearing an API costume: the real logic lived next to pandas and the rest of Python's data stack, the team thought in Python, and Pydantic gave us honest request and response contracts. Iteration speed was the feature we were optimizing for. Rewriting that in Spring Boot would have meant translating every analytical idea across a language boundary for zero benefit.
Same framework, different project, opposite result. For the Indicators platform, the reporting system telecom operators use to submit data to the regulator, I chose Spring Boot and I'd choose it again: long-lived workflows, strict validation, role hierarchies, scheduled batch processing, and a codebase that would be refactored many times by many hands. During an early prototype I felt the pull of "FastAPI is faster to write", and it is, right up until you're hand-assembling the transaction, scheduling, and migration machinery Spring hands you for free, on a team that thinks in Java anyway.
The point isn't FastAPI versus Spring Boot. The point is that the same two tools ranked in opposite order once the context changed, and the context was never syntax.
The best stack for your project is the one your team can operate in production at 3 a.m.
The checklist I actually use
When a real project with a real deadline lands on my desk, I walk through these questions in order:
- Who maintains this in year three? If the honest answer is "whoever we can hire", look at your actual hiring market, not at what's trending online.
- *What does the ecosystem hand you for free for your problem?* Data work leans Python. Concurrency-heavy network services lean Go. A transactional enterprise core leans JVM or .NET. Fighting the grain costs months.
- Can the team operate it? Not just write it: profile it, read its stack traces, upgrade its dependencies without fear.
- Audit the top ten libraries you'll depend on. Last release date, open issues, bus factor. A dead dependency in a "modern" ecosystem is worse than an old one in a boring ecosystem.
- Familiarity beats theoretical fit. A language the team knows deeply will beat a "better" one they're learning from tutorials, on any schedule that matters.
- Count your novelty budget. Every project can absorb one or two unfamiliar pieces. Spend them on the genuinely hard part of your problem, not on the stack.
Notice what's not on the list: benchmarks, syntax elegance, whatever is trending this quarter. Rust, Go, and Python are all excellent. Nearly every mainstream language is excellent now, and that's exactly why the language stopped being the decision. Enjoy the flame wars as entertainment, I certainly do, then pick the boring option your team can carry and put the saved energy into the problem you're actually being paid to solve.