Production Engineering/
Lesson

It's tempting to pick a technology stack first and then fit your project into it. Many teams do it. They choose microservicesWhat is microservices?An architecture where an application is split into small, independently deployed services that communicate over the network, each owning its own data. because Netflix uses microservices, or GraphQLWhat is graphql?A query language for APIs where clients specify the exact shape of data they need in a single request, avoiding over-fetching and under-fetching. because it sounds modern, or Kubernetes because someone at a conference was enthusiastic about it. Then they spend the first three months fighting infrastructure instead of building features. Requirements analysis is the discipline of reversing that order.

The wrong way and the right way

Wrong order:
  "Let's build with React, Next.js, TypeScript, Prisma,
   PostgreSQL, Docker, Kubernetes, and GraphQL!"
  ... but what exactly are you building? For how many users? With what team?

Right order:
  1. What problem are we solving?
  2. Who uses it and how many?
  3. What are our constraints (time, money, team)?
  4. What's the simplest stack that meets those constraints?
02

The four dimensions

Scale and traffic

How many users you expect, and what their traffic pattern looks like, determines whether you need anything beyond a single server.

UsersTraffic patternImplication
< 1,000SteadyBasic VPS or serverless
10,000-100,000SteadyStandard hosted database + app server
100,000+SpikyAuto-scaling, CDN caching
MillionsVariableArchitecture becomes a feature

Team and skills

The best stack is often the one your team already knows. Learning a new framework under deadline pressure adds weeks and bugs.

What technologies does your team know well? How large is the team, and will it grow? If you plan to hire, how available is talent for your chosen stack? React developers are common; Elm developers are not.

Timeline and budget

A prototype due in three weeks has different constraints than a product expected to last five years. Speed of development and long-term maintainability pull in opposite directions, the right balance depends on where you are.

Hosting budget matters too: $5/month points you toward static hosting or free-tier serverlessWhat is serverless?A hosting model where individual functions run on demand and the platform handles all server management, scaling, and uptime for you.; $500/month opens up managed databases and auto-scaling services.

Technical requirements

Some product requirements directly constrain your architecture:

SEO required?         → Server-side rendering (Next.js, Remix)
Real-time updates?    → WebSockets or SSE
Offline support?      → Service workers, local-first data
Mobile app needed?    → Shared API layer, possibly React Native
Regulatory compliance? → Specific data residency, audit logging
03

Working through an example

Say you're building a blog platform. Let's actually apply the framework:

  • Public blog posts with good SEO → needs SSRWhat is ssr?Server-Side Rendering - generating HTML on the server for every request so users and search engines see fully formed pages immediately.
  • 100-1,000 daily visitors → no exotic scaling needed
  • Solo developer → pick familiar tech, minimize overhead
  • $10/month budget → serverlessWhat is serverless?A hosting model where individual functions run on demand and the platform handles all server management, scaling, and uptime for you. or static hosting
  • Ship in one month → no time for a complex setup

Every one of those constraints points the same direction: Next.js on Vercel's free tier, with a managed Postgres database. That's not a lazy choice, it's a correct one for these requirements.

04

The anti-patterns

Over-engineering is real and it kills projects. Here are the three most common forms:

Premature scaling: building for millions of users when you have zero. Your architecture should match your actual scale, not your aspirational scale.

Resume-driven development: choosing Rust, WebAssembly, or a brand-new framework because they look good on a CV, not because they solve a problem you have.

Analysis paralysis: spending weeks comparing React vs Vue, PostgreSQL vs MySQL, RESTWhat is rest?An architectural style for web APIs where URLs represent resources (nouns) and HTTP methods (GET, POST, PUT, DELETE) represent actions on those resources. vs GraphQLWhat is graphql?A query language for APIs where clients specify the exact shape of data they need in a single request, avoiding over-fetching and under-fetching., without making any decision. Most of these choices don't matter much, pick one and start.

05

YAGNI

"You Aren't Gonna Need It" is a principle from Extreme Programming that still holds. Don't build internationalizationWhat is i18n?Short for internationalization (18 letters between i and n) - structuring your code so it can support multiple languages and regions. support for a product that launches in one country. Don't build microservicesWhat is microservices?An architecture where an application is split into small, independently deployed services that communicate over the network, each owning its own data. for a product with three users. Don't add a message queue for features that don't need async processing yet.

Build for what you need now. Keep the architecture flexible enough to extend later. Refactor when the need actually arrives, not when you imagine it might.
06

Decision checklist

QuestionPoints toward
Team < 5, tight timelineFamiliar stack, monolith
Need SEO, public-facingSSR framework
Budget < $20/monthServerless, free tier hosting
Real-time features requiredNode.js + WebSockets or Supabase
Unknown requirements, might pivotStart simple, design for change
Large team, multiple squadsConsider service boundaries
javascript
// Example: Decision tree for a new project

function chooseTechStack(requirements) {
  const stack = {};

  // Frontend framework
  if (requirements.seo) {
    stack.framework = requirements.teamKnowsReact
      ? 'Next.js'
      : 'Remix';
  } else if (requirements.simple) {
    stack.framework = 'Vanilla JS or small library';
  } else {
    stack.framework = requirements.teamSize > 5
      ? 'React' // More devs know it
      : 'Vue';   // Easier to learn
  }

  // Database
  if (requirements.users < 1000) {
    stack.database = 'SQLite'; // Simple
  } else if (requirements.relationalData) {
    stack.database = 'PostgreSQL';
  } else if (requirements.flexibleSchema) {
    stack.database = 'MongoDB';
  }

  // Hosting
  if (requirements.budget < 10) {
    stack.hosting = 'Vercel/Netlify (free tier)';
  } else if (requirements.budget < 50) {
    stack.hosting = 'VPS (DigitalOcean, Linode)';
  } else {
    stack.hosting = 'Managed services (AWS, GCP)';
  }

  // Type safety
  stack.typescript = requirements.teamSize > 3 || requirements.longTerm;

  return stack;
}

// Example usage
const myProject = {
  seo: true,
  teamKnowsReact: true,
  users: 500,
  relationalData: true,
  budget: 15,
  teamSize: 2,
  longTerm: true
};

const stack = chooseTechStack(myProject);
console.log(stack);
// {
//   framework: 'Next.js',
//   database: 'SQLite',
//   hosting: 'VPS (DigitalOcean, Linode)',
//   typescript: true
// }