HomeProjectsBlogContact

How to Scale a Web App: The Steps That Matter, in Order

Most apps don't need Kubernetes to handle more users. They need measurement, indexes, caching and a few architectural habits. A practical, step-by-step path from one server to serious traffic.

How to Scale a Web App: The Steps That Matter, in Order

"Will it scale?" is a question that sends many developers straight to complex architecture diagrams. In reality, most web apps hit their first limits for boring, fixable reasons: a missing index, an N+1 query, no caching, or too many synchronous calls to a slow API. Scaling well means fixing the right bottleneck at the right time.

Here's the order that works for most apps.

Step 0: measure first

You can't scale what you can't see. Before changing anything:

  • Track response times (especially the slow tail, like the 95th percentile), error rates and throughput.
  • Find the slowest endpoints and the slowest database queries.
  • Watch CPU, memory, database connections and disk.

Optimising without data usually means optimising the wrong thing. (Logging and monitoring.)

Step 1: fix the database queries

The database is the most common bottleneck by far.

  • Add indexes for the queries you actually run. (Indexing explained.)
  • Remove N+1 queries. (The N+1 problem.)
  • Select only the columns you need, and paginate every list.
  • Use connection pooling, especially with serverless functions, so you don't exhaust database connections.

These changes often deliver 10× improvements and cost nothing.

Step 2: cache aggressively (and carefully)

  • Serve static assets through a CDN with long cache lifetimes.
  • Cache public pages at the edge, or generate them statically.
  • Cache expensive computations and queries in Redis or memory.

A request answered from cache never touches your servers or database. (Caching strategies.)

Step 3: move slow work out of requests

Emails, image processing, reports and third-party calls belong in background jobs. Requests get faster, and spikes in that work no longer slow down your API. (Background jobs and queues.)

Step 4: scale up (vertical scaling)

Give the server or database more CPU and memory. It's not glamorous, but it's fast, simple and often enough for a long time. Modern single machines are very powerful. Don't dismiss vertical scaling because it seems unsophisticated.

Step 5: scale out (horizontal scaling)

Run several app instances behind a load balancer. This requires your app to be stateless:

  • Sessions stored in the database or Redis, not in server memory.
  • Uploaded files in object storage, not on the local disk. (File uploads.)
  • Scheduled jobs that run once, not once per instance.
  • WebSocket events shared through a pub/sub layer. (Real-time options.)

Once stateless, adding capacity is just adding instances. Many platforms do this automatically. (Load balancing with Nginx.)

Step 6: scale the database

When the database itself becomes the limit:

  1. Scale it up (bigger instance) first.
  2. Read replicas handle read-heavy traffic: send reports, searches and listing pages to replicas, writes to the primary. Mind replication lag for data users just changed.
  3. Move specialised workloads to specialised tools: full-text search to a search engine, analytics to a data warehouse, caching to Redis.
  4. Partitioning and sharding come last. They add significant complexity and most apps never need them.

Step 7: protect the system

  • Rate limiting keeps abusive or buggy clients from overwhelming you. (Rate limiting.)
  • Timeouts on every external call, so one slow dependency doesn't tie up all your workers.
  • Graceful degradation: if recommendations fail, show the page without them instead of an error.
  • Load testing before big launches, with tools like k6, to find limits before users do.

What not to do too early

  • Microservices for scale reasons alone. (Monolith vs microservices.)
  • Kubernetes for an app that runs comfortably on a few instances.
  • Sharding a database that fits on one machine.
  • Rewriting in a "faster" language before fixing queries and caching.

Premature scaling costs real time and adds failure modes, while the actual bottleneck often sits untouched.

A rough mental model

Stage Typical setup
Early One app instance, one managed database, CDN for static files
Growing Indexes, caching, background jobs, bigger instances
Busy Several stateless app instances behind a load balancer, Redis, read replicas
Large Specialised data stores, service extraction where it helps teams, sophisticated observability

Many successful products live happily in the "Growing" or "Busy" stage for years.

FAQ

How do I make my web app handle more users?

Measure first, then fix slow database queries, add caching, move slow work to background jobs, scale servers up, and make the app stateless so you can run multiple instances.

What is the difference between vertical and horizontal scaling?

Vertical scaling gives one machine more resources. Horizontal scaling adds more machines or instances and spreads traffic across them, which requires a stateless application.

When do I need database sharding?

Rarely, and late. Indexes, caching, bigger instances, read replicas and specialised stores handle the vast majority of apps; sharding is for very large data or write volumes.

Keep reading

More from the workbench

All articles →