Choose the stack your team already ships fastest in, built from boring, widely hired technology: for most web products that means TypeScript or Python, a mainstream full-stack framework, PostgreSQL and a managed hosting platform. Spend your care on the few decisions that are expensive to reverse (the database and data model, the primary backend language, identity and the tenancy model) and treat everything else as replaceable. Decide within a week, prove the choice with a spike that deploys to production, and write the decision down.
Key takeaways
- Fluency beats theoretical fit. A language the team ships in today is worth more than a better-benchmarked one it is still learning.
- Rank decisions by the cost of reversing them. The database, tenancy model, primary language and identity provider deserve real analysis; the CSS library does not.
- PostgreSQL is the right default database for most startups. Add specialized stores when a measured need appears, not before.
- Start on a managed platform. Kubernetes, multi-region and service meshes solve problems you do not have yet, and they cost you on-call time from day one.
- Prove the choice with a one-week spike that covers auth, migrations, a background job, a deploy and error tracking, then record it in an ADR.
Rank decisions by how expensive they are to reverse
Most stack debates spend equal energy on every layer. That is backwards. A few decisions are nearly permanent; most can be changed in a sprint.
| Decision | Cost to change later | Why | How much care |
|---|---|---|---|
| Database and data model | Very high | Data migration, dual writes, every query touched | The most |
| Tenancy model (shared tables, schema per tenant, database per tenant) | Very high | Affects every query, index, backup and support tool | High |
| Primary backend language | High | Effectively a rewrite plus a hiring change | High |
| Identity provider and user model | High | User IDs everywhere, SSO connections, and some providers will not export password hashes, which forces resets | High |
| Frontend framework | Medium | Usually migratable route by route | Medium |
| Hosting platform | Low to medium | Containers move easily; proprietary platform features do not | Medium |
| Email, analytics, queue, cache vendors | Low | Replaceable if wrapped behind an interface | Low |
| Component library and CSS approach | Low | Cosmetic, incremental | Least |
If you are debating Tailwind for a week and picked your tenancy model in an afternoon, swap those time budgets.
Six questions that decide most of the stack
1. What does the team already ship in? Not "know", ship: deploy, debug at 2 a.m., profile. A team of Python engineers will reach production faster with Django or FastAPI than with a framework they are learning, whatever the benchmarks say.
2. What shape is the product? A CRUD-heavy B2B dashboard, a realtime collaborative editor, an AI product built around model calls, a mobile-first consumer app and a data-intensive analytics tool have different hard parts. Pick technology for the hard part, and accept a mainstream default everywhere else.
3. Where will you hire for the next eighteen months? Look at real job listings and candidate supply in the cities or time zones you recruit from. A niche language narrows the pool and lengthens every search, and the one person who knows it becomes a key-person risk.
4. What must it integrate with? List the third parties that are core to the product: payments, identity, your LLM provider, email, the domain APIs your customers use. Check that each has a maintained first-party SDK in your language. Writing your own client for a payments API is not a good use of a startup's first month.
5. What compliance constraints apply? Data residency, HIPAA, SOC 2 or PCI scope push you toward managed services that offer the right agreements and audit logs, and toward a cloud region you can name in a security questionnaire.
6. What is the realistic load in year one? Be honest. Most B2B products in their first year serve traffic that one PostgreSQL instance and a few application containers handle comfortably. Optimize for change speed, and keep a clear path to scale.
A weighted scoring worksheet
When two options are close, score them. The point is not the arithmetic. Writing the weights forces the team to agree on what matters before arguing about frameworks.
Illustration: a three-person team with deep Python experience is building a B2B workflow product with one ML-backed feature. They compare full-stack TypeScript with a Python backend plus a React frontend. Scores run from 1 (poor) to 5 (excellent).
| Criterion | Weight | TypeScript full stack | Python backend + React |
|---|---|---|---|
| Team fluency | 30 | 2 | 5 |
| Hiring pool where they recruit | 15 | 5 | 4 |
| SDKs for their integrations | 15 | 4 | 5 |
| Fit for the hard part (the ML feature) | 20 | 3 | 5 |
| Operational simplicity | 10 | 4 | 3 |
| Reversibility if wrong | 10 | 3 | 3 |
| Weighted score (sum of weight × score, divided by 100) | 3.25 | 4.45 |
The Python option wins on fluency and fit, even though full-stack TypeScript would be a fine default for a team without that background. Change the team and the answer changes. That is the point.
Default stacks by product type
Use these as starting points, not prescriptions.
| Product type | Default stack | Why | Watch out for |
|---|---|---|---|
| B2B SaaS and dashboards | TypeScript, Next.js or React with a separate API, PostgreSQL, a managed PaaS | One language, shared types, large hiring pool | Keep business logic in plain server modules, not scattered through UI components |
| AI-centered product | Python (FastAPI) for model and retrieval work, TypeScript frontend, PostgreSQL with pgvector | Python's ML and data ecosystem | Two toolchains. Keep one typed API contract between them |
| Realtime collaboration | TypeScript or Elixir for the realtime layer, PostgreSQL, WebSockets | Connection-heavy workloads suit an event loop or the BEAM | Presence and reconnect logic are the hard part, not the framework |
| Mobile-first consumer | React Native with Expo for a TypeScript team, native Swift and Kotlin for heavy device integration | Shared code with the web for a TS team | Store review cycles slow every fix; use feature flags and over-the-air updates where allowed |
| Data-intensive analytics | Python, PostgreSQL for transactions, ClickHouse or a warehouse for analytics | Separate transactional and analytical load early | Analytics queries on the primary database will hurt the product |
| Regulated (fintech, health) | Mainstream language your team knows (Java or Kotlin, Go, TypeScript, Python), PostgreSQL, one major cloud | Auditors and security questionnaires favor the well-trodden path | Audit logging, encryption and access reviews are features, not afterthoughts |
| Developer tools, agents and CLIs | Go or Rust | Single static binary, no runtime to install | Cross-compilation and code signing need CI work up front |
The last row is personal. We wrote Trinetra, our server monitor, in Go and Braid, our download manager, in Rust, because both ship to machines we do not control, where a single binary with no runtime is worth a slower development pace.
Frontend choices
Next.js is the strongest default for products that need SEO, marketing pages and an app in one codebase, with a large ecosystem and hiring pool. The cost is complexity at the server and client boundary. Keep data access on the server and treat client components as the exception.
React Router v7, which absorbed Remix's framework features, suits teams that like web platform primitives: forms, HTTP caching, progressive enhancement.
SvelteKit produces small bundles and is pleasant to write. The ecosystem and hiring pool are smaller than React's.
A plain React single-page app built with Vite is often the right call for a complex tool behind a login, where SEO does not matter and the interface behaves more like a desktop app than a website.
Backend languages compared
| Language | Strengths | Costs | Choose it when |
|---|---|---|---|
| TypeScript on Node.js | One language end to end, shared types, huge ecosystem | CPU-bound work blocks the event loop; dependency sprawl needs discipline | Web SaaS with a JavaScript-fluent team |
| Python | Unmatched ML and data libraries; FastAPI and Django are mature | Slower for CPU-bound work; free-threaded builds exist but are not the default; packaging needs a tool like uv | AI and data products |
| Go | Static binaries, simple concurrency, low memory, fast builds | More verbose; fewer batteries-included web frameworks | Infrastructure, high-concurrency APIs, CLIs |
| Java or Kotlin | Mature JVM, strong typing, deep enterprise libraries | Heavier frameworks and runtime | Fintech, enterprise integrations, JVM-fluent teams |
| Ruby on Rails | Very fast path from idea to CRUD in production | Smaller hiring pool in many markets; needs performance work at scale | Rails-fluent founders building CRUD SaaS |
| Elixir | Realtime and fault tolerance on the BEAM; Phoenix LiveView | Small hiring pool | Realtime products with Elixir-fluent founders |
| Rust | Performance and memory safety without a garbage collector | Slow to write; steep learning curve | Performance or safety is the product |
Database: start with PostgreSQL
PostgreSQL covers relational data, JSON documents (jsonb), full-text search, geospatial queries (PostGIS) and vector similarity search (pgvector) in one system you can back up, replicate and reason about. Every major cloud runs it as a managed service, as do Supabase and Neon. Our database selection guide goes deeper on when something else is warranted.
Add other stores when you can point at a measured need:
- Redis or Valkey for caching, rate limiting, sessions and simple queues.
- A search engine (OpenSearch, Meilisearch, Typesense) when PostgreSQL full-text ranking or typo tolerance is not good enough for users.
- ClickHouse or a warehouse when analytical queries start competing with product traffic.
- A document database only when the data really is document-shaped and you rarely join across it.
Two rules that save rewrites: store timestamps in UTC with a time zone-aware type, and store money as integer minor units or a fixed-point decimal, never as a float.
Infrastructure by stage
Before product-market fit: a managed platform such as Vercel, Render, Railway or Fly.io, or one cloud's managed container service (Google Cloud Run, AWS ECS on Fargate, Azure Container Apps). Managed PostgreSQL with point-in-time recovery. One region. CI deploys on merge.
After product-market fit: move to one major cloud when you need private networking, compliance controls or pricing the platform cannot match. Describe it in infrastructure as code (Terraform, OpenTofu or Pulumi) from the first resource. Run containers on a managed service before considering Kubernetes; our comparison of Kubernetes and serverless covers the trade-offs.
Prove it with a one-week spike
A slide comparing frameworks proves nothing. A spike that reaches production proves most of it. Give one or two engineers a week and this list:
- Sign-up and login through the chosen identity provider, with one role check enforced on the server
- One table created by a migration that CI applies, then a second migration that alters it
- One flow from UI to database and back, with server-side validation
- One background job with retries and a visible failure state
- One call to the most critical third-party API (payments, LLM, email)
- A deploy from CI to a production-like environment, and a rollback that you actually performed
- Error tracking receiving a deliberate exception with a readable stack trace
- One integration test running in CI against a real database
If any item costs a day of fighting the framework, take that seriously. It will cost a day every month for years.
Write the decision down
Record the choice as an Architecture Decision Record so the next engineer, investor or acquirer can see why it was made and when to revisit it. Decision records are one of the first things evaluators ask for in technical due diligence.
## ADR-001: Primary application stack
Status: Accepted, 2026-10-04
Context: Three engineers, strongest in Python. B2B workflow product with one
ML-backed feature. EU customers expected in year one.
Decision: Python (FastAPI) API, React frontend built with Vite, PostgreSQL
(managed, EU region), deployed as containers on a managed service.
Options considered: Full-stack TypeScript with Next.js; Django monolith.
Consequences: Two toolchains. API contract defined in OpenAPI and types
generated for the frontend. Background jobs need a separate worker process.
Revisit if: the team becomes mostly TypeScript engineers, or the frontend
needs server rendering for SEO.What goes wrong in production
These are stack-related failures that reach the pager, usually months after the decision was made.
Serverless functions exhaust database connections. Each function instance opens its own connection, and a traffic spike opens hundreds. Use a connection pooler (PgBouncer or your provider's pooler) from the first deploy.
Edge runtimes surprise you. Code that runs fine in Node.js fails at the edge because a database driver or a Node API is not available there. Keep data access in the regular server runtime unless you have a reason not to.
The ORM hides N+1 queries. A page that runs one query per row is fast with fifty rows and times out with fifty thousand. Log query counts per request in development and fail tests that exceed a budget.
Slow work runs inside the request. Sending email or calling an LLM inside the signup handler couples your page latency to someone else's API. Many serverless platforms also stop work after the response is sent. Put it on a queue.
Two languages drift apart. Validation rules and models get duplicated between a TypeScript frontend and a Python backend and then disagree. Generate types from one schema, such as an OpenAPI document.
The niche language owner leaves. The service written in the language only one engineer knows becomes untouchable. If you choose something unusual, make sure at least two people can ship and debug it.
Floats in money columns. Rounding errors show up as invoices that are off by a cent, which finance will notice before you do.
Frequently Asked Questions
What is the best tech stack for a startup?
The best stack is the one your team already ships quickly in, built from mainstream technology with a large hiring pool. For most web products that means TypeScript or Python, a full-stack framework such as Next.js or Django, PostgreSQL and a managed hosting platform. Technology choice matters far less than how fast the team can ship and fix things.
Should a startup use microservices?
Almost never at the start. A well-structured monolith with clear module boundaries is faster to build, easier to debug and cheaper to run for a small team. Extract a service later when a module needs independent scaling, a different deploy cadence or a separate owning team.
Is Python or Node.js better for a startup backend?
Choose the one your team is fluent in. Python is the stronger choice when machine learning or data processing is central to the product, while Node.js with TypeScript lets a web team use one language and share types across frontend and backend. Both run large production systems.
When should a startup move from a PaaS to AWS, GCP or Azure?
Move when the platform blocks something you need: private networking, specific compliance controls, data residency, or pricing that no longer fits your usage. Moving earlier adds infrastructure work and on-call surface without a matching benefit. When you do move, define everything in infrastructure as code from the start.
Does the tech stack matter to investors?
Investors rarely care which framework you chose, but technical due diligence does check whether the choice fits the team and the product. They look for mainstream, maintainable technology, a team that can explain its decisions, and no key-person risk from a niche language. A documented decision record helps.
Need help choosing your stack?
We are senior engineers who build production systems and keep running them after launch: if we built it, we are on the pager. We can pressure-test your stack against your product and team, run the spike with you, or take an existing prototype to production on a foundation you will not have to rewrite.