Appearance
Chapter 20: Tech Stack Decisions
Choosing the right tools is less about picking the "best" technology and more about picking the best technology for your team, timeline, and target market.
Why This Matters
- Owner: Your tech stack determines hiring pool size, development speed, infrastructure costs, and long-term maintainability. A poor choice here compounds over years.
- Dev: You will build on this foundation daily. The stack shapes your productivity, debugging experience, and career trajectory on this project.
- PM: Stack choices constrain feature velocity, third-party integrations, and what is feasible within a sprint. Understanding trade-offs helps you plan realistically.
- Designer: Frontend framework choice affects what animations, interactions, and design system tools are available to you.
The Concept (Simple)
Choosing a tech stack is like choosing tools to build a house:
- You could use premium tools and exotic materials, but if your crew only knows basic carpentry, the house will take forever.
- The "best" hammer is the one your team can swing effectively.
- Some tools lock you into a specific supplier (vendor lock-in). Others are interchangeable.
The goal is not to pick the trendiest stack. The goal is to pick the stack that lets your team ship reliable software fastest with the fewest regrets in 2-3 years.
How It Works (Detailed)
The SaaS Stack Layers
┌─────────────────────────────────────────────────────────┐
│ PRESENTATION │
│ Frontend Framework | Mobile | Design System │
├─────────────────────────────────────────────────────────┤
│ API LAYER │
│ REST / GraphQL | API Gateway | WebSockets │
├─────────────────────────────────────────────────────────┤
│ APPLICATION │
│ Backend Framework | Auth | Business Logic │
├─────────────────────────────────────────────────────────┤
│ DATA LAYER │
│ Primary DB | Cache | Search | Queue │
├─────────────────────────────────────────────────────────┤
│ INFRASTRUCTURE │
│ Cloud Provider | CI/CD | Monitoring | CDN │
└─────────────────────────────────────────────────────────┘Frontend Framework Comparison
| Framework | Learning Curve | Ecosystem | Hiring Pool | Performance | Best For |
|---|---|---|---|---|---|
| React | Medium | Massive | Largest | Good | Complex dashboards, SPAs |
| Next.js | Medium | Large | Large | Excellent | SEO + app hybrid, full-stack |
| Vue | Low | Good | Medium | Good | Rapid prototyping, SMB apps |
| Svelte | Low | Growing | Small | Excellent | Performance-critical UIs |
| Angular | High | Large | Large | Good | Enterprise, large teams |
| HTMX | Very Low | Small | Small | Excellent | Server-rendered, simple UIs |
Backend Framework Comparison
| Framework | Language | Hiring Pool | Performance | Best For |
|---|---|---|---|---|
| Express / Fastify | Node.js | Largest | Good | API-first, JS full-stack |
| Django | Python | Large | Moderate | Data-heavy, rapid prototyping |
| Rails | Ruby | Medium | Moderate | Convention-over-config, speed |
| Spring Boot | Java/Kotlin | Large | Excellent | Enterprise, complex domains |
| Laravel | PHP | Large | Good | CRUD-heavy, content platforms |
| Go (net/http/Gin) | Go | Medium | Excellent | High-throughput microservices |
| ASP.NET Core | C# | Large | Excellent | Enterprise, Microsoft ecosystem |
| Phoenix | Elixir | Small | Excellent | Real-time, high-concurrency |
Database Comparison
| Database | Type | Scaling | Best For |
|---|---|---|---|
| PostgreSQL | Relational | Vertical+ | Default choice for most SaaS |
| MySQL | Relational | Vertical+ | Simpler relational needs, wide support |
| MongoDB | Document | Horizontal | Flexible schemas, content-heavy apps |
| DynamoDB | Key-Value | Horizontal | AWS-native, predictable performance |
| Redis | In-memory | Cluster | Caching, sessions, real-time features |
| Elasticsearch | Search | Horizontal | Full-text search, log analytics |
| ClickHouse | Columnar | Horizontal | Analytics, event data, time-series |
Common Stack Combinations
┌─────────────────────────────────────────────────────────────┐
│ POPULAR SAAS STACK COMBOS │
├─────────────────────────────────────────────────────────────┤
│ │
│ "The Startup Default" "The Enterprise Java" │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Next.js (frontend) │ │ React (frontend) │ │
│ │ Node.js (backend) │ │ Spring Boot (API) │ │
│ │ PostgreSQL (DB) │ │ PostgreSQL (DB) │ │
│ │ Redis (cache) │ │ Redis (cache) │ │
│ │ Vercel / AWS (infra)│ │ AWS / GCP (infra) │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
│ "The Rapid Prototype" "The Data-Heavy SaaS" │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Rails (full-stack) │ │ React (frontend) │ │
│ │ Hotwire (frontend) │ │ Django / FastAPI │ │
│ │ PostgreSQL (DB) │ │ PostgreSQL (primary) │ │
│ │ Sidekiq (jobs) │ │ ClickHouse (OLAP) │ │
│ │ Heroku / Render │ │ Redis (cache) │ │
│ └─────────────────────┘ │ AWS (infra) │ │
│ └─────────────────────┘ │
│ │
│ "The Go Microservices" "The Full TypeScript" │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ React (frontend) │ │ Next.js (full-stack) │ │
│ │ Go (services) │ │ tRPC (API layer) │ │
│ │ PostgreSQL + Redis │ │ Prisma (ORM) │ │
│ │ Kafka (events) │ │ PostgreSQL (DB) │ │
│ │ Kubernetes (infra) │ │ Vercel (infra) │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘Tech Stack Decision Flowchart
START: What is your team's strongest language?
│
├── JavaScript/TypeScript ──▶ Next.js + Node.js + PostgreSQL
│ (Full-stack TypeScript)
│
├── Python ──▶ Is it data/ML heavy?
│ ├── Yes ──▶ Django/FastAPI + PostgreSQL + ClickHouse
│ └── No ──▶ Django + PostgreSQL + Redis
│
├── Ruby ──▶ Rails + PostgreSQL + Sidekiq
│ (Fastest time-to-MVP)
│
├── Java/Kotlin ──▶ Spring Boot + PostgreSQL + Redis
│ (Enterprise-grade from day one)
│
├── Go ──▶ Planning microservices early?
│ ├── Yes ──▶ Go services + gRPC + PostgreSQL + Kafka
│ └── No ──▶ Consider Node.js or Rails instead
│
└── C# ──▶ ASP.NET Core + SQL Server/PostgreSQL
(Microsoft ecosystem)
THEN: Add infrastructure
│
├── Budget < $500/mo ──▶ Vercel / Render / Railway
├── Budget $500-5K/mo ──▶ AWS / GCP managed services
└── Budget > $5K/mo ──▶ AWS / GCP + Kubernetes (if team can manage it)Build vs Buy Decision Matrix
Before building any infrastructure component, run it through this matrix:
| Component | Build | Buy / Use SaaS | Recommendation |
|---|---|---|---|
| Authentication | Full control, custom flows | Auth0, Clerk, Supabase Auth | Buy (always) |
| Payments/Billing | Custom pricing models | Stripe, Paddle, Chargebee | Buy (always) |
| Email sending | Deliverability control | SendGrid, Postmark, Resend | Buy |
| Search | Custom ranking, tight integration | Algolia, Typesense, Meilisearch | Buy until scale |
| File storage | N/A | S3, Cloudflare R2, GCS | Buy (always) |
| Monitoring | Custom dashboards | Datadog, Grafana Cloud, New Relic | Buy |
| Error tracking | N/A | Sentry, Bugsnag | Buy (always) |
| Feature flags | Simple on/off only | LaunchDarkly, Flagsmith, Unleash | Buy or OSS |
| Analytics | Privacy-first, custom events | Amplitude, Mixpanel, PostHog | Buy or OSS |
| Core product logic | Your competitive advantage | N/A | Build (always) |
| Admin dashboard | Custom workflows | Retool, Forest Admin | Depends on stage |
| Background jobs | Tight integration needed | Inngest, Temporal | Build early, buy later |
BUILD vs BUY Decision Tree:
Is this your core product differentiator?
│
├── YES ──▶ BUILD IT (this is your competitive moat)
│
└── NO ──▶ Does a reliable SaaS/OSS solution exist?
│
├── YES ──▶ Can you afford it at 10x current scale?
│ │
│ ├── YES ──▶ BUY IT
│ └── NO ──▶ Buy now, plan migration later
│
└── NO ──▶ Can you build it in < 2 weeks?
│
├── YES ──▶ BUILD IT (keep it simple)
└── NO ──▶ Find the closest solution + adaptVendor Lock-In Assessment
Rate each technology on a lock-in scale:
LOW LOCK-IN ◄──────────────────────────────────────► HIGH LOCK-IN
PostgreSQL AWS Lambda DynamoDB
Redis Cloud Functions Firebase Firestore
Kubernetes Managed Kubernetes Azure Cosmos DB
Docker CloudFront Vercel Edge Functions
OpenSearch RDS AWS Amplify
Self-hosted tools Managed Redis Proprietary AI APIs
S3-compatible SNS/SQS Cloud Spanner
RULE: Keep your core data layer low lock-in.
Accept higher lock-in for commodity infrastructure.Lock-in mitigation strategies:
| Strategy | Effort | Effectiveness |
|---|---|---|
| Use open-source databases | Low | High |
| Containerize everything | Medium | High |
| Abstract cloud SDK calls | Medium | Medium |
| Multi-cloud deployment | High | Overkill (usually) |
| Use Terraform/Pulumi for IaC | Medium | High |
In Practice
Case Study: Choosing a Stack for a B2B Analytics SaaS
Context: 3-person founding team (2 devs, 1 designer). Target market: mid-market companies. Data-heavy product with dashboards.
Decision process:
- Team skills: Both devs know TypeScript and Python
- Product needs: Complex dashboards, real-time data, CSV imports
- Timeline: MVP in 3 months
- Budget: $300/month infrastructure
Stack chosen:
- Frontend: Next.js (React expertise + SSR for landing pages)
- Backend: FastAPI (Python, great for data processing)
- Database: PostgreSQL (relational data) + ClickHouse (analytics queries)
- Cache: Redis
- Infra: Railway (simple, affordable, scales)
- Auth: Clerk (buy, not build)
- Payments: Stripe
Why it worked: Python excelled at data pipeline code. TypeScript handled the complex dashboard UI. They bought everything that was not their core product.
Common Mistakes
- Choosing Go or Rust for a CRUD SaaS -- you are optimizing for performance you will not need for years at the cost of development speed
- Using MongoDB as your primary database -- relational data (users, subscriptions, permissions) wants a relational database
- Building auth from scratch -- this wastes 2-4 weeks minimum and you will have security vulnerabilities
- Picking a stack based on blog posts -- choose based on your team's existing skills, not Hacker News trends
- Not considering the hiring market -- a niche language means fewer candidates and higher salaries
Key Takeaways
- The best stack is the one your team already knows; switching costs are almost always underestimated
- PostgreSQL is the correct default database for SaaS -- choose something else only with a specific reason
- Buy every commodity component (auth, payments, email, monitoring); build only your core product differentiator
- Vendor lock-in matters most at the data layer; accept lock-in for compute and edge infrastructure
- Your stack will evolve; optimize for speed-to-MVP now, not theoretical scale in 3 years
- Full TypeScript (Next.js + Node.js) is the highest-leverage choice for small teams in 2025-2026
Action Items
Owner
- [ ] Audit your current team's language skills before making stack decisions
- [ ] Set a monthly infrastructure budget ceiling for the first year
- [ ] Ensure the chosen stack has a healthy hiring market in your geography or remote pool
- [ ] Review the build vs buy matrix with your CTO -- every "build" decision delays your core product
Dev
- [ ] Prototype your top 2 stack candidates with a weekend spike before committing
- [ ] Set up the database schema with multi-tenancy from day one (see Chapter 19: SaaS Architecture 101)
- [ ] Containerize your application early (Docker) to avoid lock-in and ease deployment (see Chapter 21: Shipping and Deployment)
- [ ] Document your stack decisions and rationale in an ADR (Architecture Decision Record)
PM
- [ ] Map your feature roadmap against stack capabilities -- flag anything that seems hard
- [ ] Build integration requirements into your PRDs (what third-party services are needed?)
- [ ] Understand which "buy" components have usage-based pricing that could spike with growth
Designer
- [ ] Evaluate component libraries available for the chosen frontend framework
- [ ] Set up a design system that maps to the UI framework (e.g., Tailwind + Radix for React)
- [ ] Confirm that animation/interaction requirements are feasible in the chosen framework
- [ ] Review accessibility tooling available in the stack