How to Choose Your Technology Stack
I've seen teams choose technology for the worst reasons: because it's new, because a cofounder loves Rust, because they read a blog post about it last week, because it has the most GitHub stars. Then they're stuck maintaining it for five years while everyone curses the decision.
Here's how you actually choose your stack.
Principles of Good Stack Selection
Default to boring technology. This is the single best heuristic. When you're choosing between two options and one is boring and one is exciting, pick boring.
Why? Because boring technology is boring because it works. Boring technology has been used at scale. People know how to operate it. Libraries and tooling are mature. When something goes wrong at 2 AM, your on-call engineer can fix it because they've seen it a thousand times.
New technology is exciting because it's new. It hasn't been tested at your scale. Its libraries are immature. When something breaks, you're debugging the framework, not your code.
Boring means: Use PostgreSQL instead of trying the new distributed database. Use Node.js instead of the language invented last year. Use boring infrastructure. Boring works.
Optimize for hiring and maintainability, not for being cutting-edge. Your company's success depends on hiring and retaining great engineers. Great engineers want to work with technology they know and that has a healthy ecosystem. They don't want to be the on-call expert in your custom database.
Pick technology that's boring enough that you can hire people who already know it. Pick technology your team already knows before you pick theoretical improvements. The 20% performance gain you get from language X is not worth it if it means your team now has to learn a new ecosystem.
Prefer the technology your team already knows over theoretically better options. This is a corollary but important: given a choice, pick what your team already knows. Your team will be 5x more productive in JavaScript than in Rust, even if Rust would theoretically be better. Use that multiplier.
Exceptions exist. If you're hiring a Rust team to build a systems tool, use Rust. If you've sold customers on Go's performance and you're hiring Go engineers, use Go. But "should we switch to Rust for better performance" when your team is productive in your current language? No.
How to Evaluate a New Addition to the Stack
When someone proposes adding something to your stack, ask three questions:
What problem does this solve that your current tools don't? Not "it's cooler" or "it's faster" (maybe). What specific, documented problem does it solve? "Our current database can't handle our scale" is a problem. "We should use a graph database because it's cool" is not.
What's the operational overhead? Every technology you own has a cost: documentation, training, on-call expertise, upgrades. If you add a new database, now you need people who understand that database. Now you need backups, monitoring, and disaster recovery for it. Is the problem worth that cost?
What's the exit strategy? If you choose this technology and it doesn't work out, how do you get out? If you built your core application on it and it was a mistake, can you migrate away? This is why you don't build on bleeding-edge technology that has no migration path. Use technology that you could migrate away from if needed.
The exit strategy also includes: if the project is abandoned (open source libraries die), can you fork it or move to alternatives? If it's commercial software and the company shuts down, what happens? If the license terms change unfavorably, do you have recourse?
Documenting Your Stack
Most teams have a stated stack and a shadow stack. The stated stack is what the CTO says you use. The shadow stack is what actually exists in production because teams built things differently.
Fix this. Document your actual stack. Use Architecture Decision Records (ADRs).
An ADR has these sections:
- Title: "Decision: Use PostgreSQL for core database"
- Status: Accepted / Proposed / Deprecated
- Context: Why did we need to make this decision? "We were using MongoDB but found ACID transactions critical for payment processing."
- Decision: What did we decide? "Use PostgreSQL 14 for the core database."
- Consequences: What tradeoffs does this create? "PostgreSQL won't auto-scale horizontally like our previous solution, so we'll need to focus on vertical scaling and read replicas."
- Alternatives: What else did we consider? "We considered Spanner, CockroachDB, and staying with MongoDB. Spanner is expensive. CockroachDB is less mature. MongoDB doesn't have the transaction support we need."
Write ADRs before you deploy new infrastructure, not after. This forces you to think through the tradeoffs. It creates a record so you don't make the same decision twice.
Communicating to Non-Technical Stakeholders
Your CEO doesn't care if you use Kubernetes or Docker Swarm. They care about cost, reliability, and how fast you can build. But they'll ask about your technology choices, and you need to help them understand.
Here's how to communicate:
"We use PostgreSQL because it's reliable, well-understood, and we can hire people who know it. We could use a more exotic database that theoretically scales better, but the tradeoff is that we'd be the only experts, maintenance would be harder, and we couldn't hire easily. Our current database scales to our projected five-year demand with vertical scaling and read replicas, which is simpler than dealing with the distributed consistency problems of some alternatives."
Translate to: "We're optimizing for something other than cutting-edge. We're optimizing for reliability and team productivity."
"We use Node.js because most of our team knows it, the ecosystem is mature, and we can ship fast. We know Go would be more efficient in some cases, but the time to train the team and the risk of shipping slower outweighs the efficiency gains. We'll revisit this when we hit specific performance constraints we can't solve in Node."
Translate to: "We're making a conscious choice, not a default choice."
When to Change Your Stack
Very rarely. Rewrites are expensive. You stay on your stack until:
- It's not scaling: You've truly hit the limits of what the technology supports at your scale, you've exhausted the optimization space within that technology, and migration is worth the cost.
- It's blocking hiring: You can't find engineers. This actually matters. If you're building in COBOL and you can't hire anyone, that's real.
- It's a critical dependency that's dead: The language or framework is being abandoned, no active development, security vulnerabilities aren't being patched. This is actually rare.
You don't change because there's something newer and cooler. You don't change because another company uses something different successfully. You change because you're truly blocked.
Connecting to Codebase Intelligence
Here's where Glue helps. You've stated your tech stack. What's actually in the codebase?
Glue lets you ask: "Show me all the HTTP clients we're using. Are they the standard library? Are they 10 different third-party libraries? Do any of them violate our standards?" You discover tech stack drift and shadow IT.
Or: "Show me all the places we're using our database. Are we using the ORM consistently? Are there places where we're writing raw SQL that violates our security patterns?" This is codebase reality vs. stated standards.
Or: "Show me all our JavaScript packages. Which ones are out of date? Which ones are unused? Which ones have security vulnerabilities?" Your stated stack is clean. Your actual dependencies might not be.
Codebase intelligence helps you keep your actual stack aligned with your stated stack.
Tech Stack Guide in 60 Seconds TL;DR
Default to boring technology that works at scale. Optimize for hiring and maintainability, not cutting-edge. Prefer what your team already knows. When adding technology, ask: what problem does it solve? What's the operational overhead? What's the exit strategy? Document your stack with ADRs (Architecture Decision Records) that capture context and tradeoffs. Change your stack only when truly blocked: can't scale, can't hire, or critical dependency is dead.
Frequently Asked Questions
Q: Is choosing boring technology the same as not innovating?
A: No. Boring infrastructure is a foundation for innovation. You innovate on your product, not on your database driver. Use boring technology for infrastructure and plumbing. Invest in innovation in the core product.
Q: A new team member is fluent in Rust. Should we adopt it?
A: Not just because one person knows it. "One person knows Rust" means one person can maintain Rust code and everyone else is dependent on them. You need at least three people with fluency for technology to be reliable. Then ask: what problem would Rust solve? If there's no specific problem, stick with what the rest of the team knows.
Q: How do we decide on the right database?
A: Start with PostgreSQL unless you have a specific reason not to. PostgreSQL handles 90% of use cases. Only switch if you have a documented requirement it doesn't meet: extreme write scale, specialized data structures, etc. Most "we need NoSQL" decisions are from people who haven't tried PostgreSQL's JSON columns.
Related Reading
- What Is Story Point Estimation?
- What Is Agile Estimation?
- Story Points Are Useless
- Velocity Doesn't Tell You How Far You Need to Go
- Glue for Engineering Planning