FjellSystem Design Lab
Lesson 1.4• 7 min read

Scaling from one user to millions

The systematic step-by-step evolution from a single box to a resilient global architecture.

This walkthrough follows the primer's worked example of growing a service on AWS from one user to tens of millions. Each stage is driven by measuring the bottleneck, not by a user count: the primer gives no fixed thresholds, because they depend entirely on the workload.

What you will learn

  • Follow the primer's six stages of growing a service from one box to tens of millions of users.
  • Name the bottleneck each stage removes.
  • Explain why each stage is triggered by measurement rather than a user count.

Stage 1: A single box

Web server and database run on one machine, with DNS (such as Route 53) mapping the domain to its address. Scale by choosing a bigger box. Simple to run, but there is a hardware ceiling and no redundancy: one crash takes the whole service down.

Stage 2: Separate the database and static content

Move the database to its own managed instance (such as RDS) and static content to an object store (such as S3). Web and database tiers can now be sized and scaled independently.

Stage 3: Load balancer, redundancy and a CDN

Put a load balancer in front of several stateless web servers spread across availability zones; health checks stop routing to an instance that fails. Run the database as a primary with a standby for failover. Move static (and some dynamic) content to a content delivery network (CDN) such as CloudFront, closer to users.

Stage 4: Caching and read replicas

Web workloads are often read-heavy: the primer's example assumes 100 reads for every write. Add:

  • An in-memory cache (such as ElastiCache running Redis or Memcached) for frequently read data, which cuts both database load and latency.
  • Read replicas that copy the primary asynchronously and serve reads, leaving the primary for writes.

Stage 5: Autoscaling

Instead of sizing for the peak by hand, let the platform add and remove web and application servers as load changes.

Stage 6: Asynchronous work, NoSQL and a warehouse

Move slow work (sending email, processing images, payments) onto a queue (such as SQS): the application server enqueues a job and responds immediately, for example with HTTP 202 Accepted ("accepted for processing, but not yet completed"), and worker services process the queue. Move data that no longer fits the relational model to a NoSQL store, and older data used for analytics to a data warehouse.

Figure 4: Full multi-tier scalable architecture with DNS, CDN, ALB, stateless compute, caching, read replicas, and message queues.
  • Global Users: 1 × Clients & Users
  • Route53 Anycast: 2 × Anycast DNS / Route53
  • CloudFront Edge: 2 × CloudFront / CDN Edge
  • Application LB: 2 × Application Load Balancer
  • Stateless App Tier: 8 × App Compute Server
  • Redis Cluster: 2 × Redis In-Memory Cache
  • Kafka Queue: 2 × Message Queue / Kafka
  • Postgres Primary (HA): 2 × Primary Relational DB
  • Global Users sends requests to Route53 Anycast
  • Route53 Anycast sends requests to CloudFront Edge
  • CloudFront Edge sends requests to Application LB
  • Application LB sends requests to Stateless App Tier
  • Stateless App Tier sends requests to Redis Cluster
  • Stateless App Tier sends requests to Kafka Queue
  • Stateless App Tier sends requests to Postgres Primary (HA)
  • Redis Cluster sends requests to Postgres Primary (HA)
  • Kafka Queue sends requests to Postgres Primary (HA)

Key takeaways

  • Grow by measuring the bottleneck; the primer gives no fixed user-count thresholds because they depend on the workload.
  • First separate the database and static content, then add a load balancer, stateless web servers across zones, a standby database and a CDN.
  • Read-heavy loads get an in-memory cache and read replicas; autoscaling replaces sizing for the peak by hand.
  • Slow work moves onto a queue (answer with 202 Accepted), and data that outgrows the relational model moves to NoSQL or a warehouse.

Sources

Adapted from The System Design Primer by Donne Martin, licensed under CC BY 4.0. Changes were made.