← All essays

What Actually Is Scalability? A Practical Guide to Load, RPS, Throughput, Latency, Bottlenecks & Capacity Planning

Scalability isn't Kubernetes or more servers. It's how your system behaves when the work increases — load, RPS, concurrency, throughput, latency, bottlenecks, saturation, and capacity planning, built up from first principles.

When engineers hear “This system needs to scale”, the conversation often immediately jumps to:

  • Kubernetes
  • Load balancers
  • Redis
  • Kafka
  • Database sharding
  • Microservices
  • Horizontal scaling
  • Auto-scaling

But there is a problem.

You can't design a scalable system if you don't understand what “scale” actually means.

Scalability isn't a technology.

It isn't Kubernetes.

It isn't adding more servers.

And it certainly isn't simply handling “more users.”

Scalability is fundamentally about one question:

How does your system behave when the amount of work it has to handle increases?

To answer that properly, we need to understand a collection of concepts that are tightly connected:

Traffic → Load → RPS → Concurrency → Throughput → Latency → Capacity → Resource Utilization → Bottlenecks → Saturation → Scaling

Once you understand this chain, system design becomes much more intuitive.

Let's build that mental model from the ground up.

1. What Is Scalability?

Scalability is the ability of a system to handle increasing workload by adding resources while maintaining acceptable performance and reliability.

Suppose you build an API that handles:

100 requests/second

And everything works perfectly.

Now your application becomes popular and traffic increases to:

1,000 requests/second

Then:

10,000 requests/second

A scalable architecture should have a reasonable way to handle this increasing workload.

But here's an important distinction:

Scalability ≠ Capacity

A server might currently handle:

5,000 RPS

That tells us something about its capacity.

Scalability asks:

“What happens when we need 10,000 RPS?”

Can we add resources?

Can we distribute the work?

Does performance remain acceptable?

Does adding more machines actually increase capacity?

That's where the rest of these concepts become important.

2. Start With Load

Before talking about scaling, we need to understand load.

Load is simply:

The amount of work being imposed on a system.

Imagine an API handling requests.

The load could be described using:

  • Requests per second
  • Number of concurrent requests
  • Amount of data processed
  • Database queries
  • CPU operations
  • Network traffic
  • Messages consumed
  • Disk I/O

For example:

text
10,000 API requests/sec

Application servers

50,000 DB queries/sec

Database

The application isn't experiencing just one kind of load.

Different components experience different workloads.

That's why saying:

“Our application gets 10,000 requests/sec”

isn't enough.

You need to understand what those requests cause the system to do.

3. Traffic vs Load

These terms are often used interchangeably, but they aren't exactly the same.

Traffic

Traffic generally describes incoming demand.

For example:

10,000 HTTP requests/sec

Load

Load describes the work generated by that traffic.

Imagine one API request performs:

text
1 API request

Authentication

3 DB queries

Redis lookup

External API call

Image processing

Now:

10,000 RPS

could translate into:

text
30,000 DB queries/sec
10,000 Redis operations/sec
10,000 external API calls/sec

Therefore:

Traffic is demand. Load is the work that demand creates.

This distinction becomes extremely important when identifying bottlenecks.

4. Requests Per Second (RPS)

One of the most common ways to measure traffic is:

Requests Per Second (RPS)

If your API receives:

text
10,000 requests

in:

text
10 seconds

then:

text
RPS = 10,000 / 10
    = 1,000 RPS

RPS gives us a simple measure of incoming request rate.

For example:

text
Small application      → 10 RPS
Growing application    → 1,000 RPS
Large application      → 100,000+ RPS

But RPS alone doesn't tell us whether the system is overloaded.

Why?

Because not all requests cost the same.

Consider:

text
GET /health

versus:

text
POST /generate-report

The first might consume almost no resources.

The second might:

  • Query a database
  • Perform expensive computation
  • Read files
  • Generate a PDF
  • Upload it to object storage

Both are one request.

But their loads are completely different.

So:

RPS measures demand, not computational cost.

5. Concurrent Users

Another commonly misunderstood metric is:

Concurrent users

Suppose your application has:

text
1 million registered users

That doesn't mean your servers are handling:

text
1 million users simultaneously.

Maybe only:

text
20,000 users

are active at the same time.

And perhaps only:

text
2,000 requests

are actually being processed concurrently.

This is why:

Total users ≠ concurrent users ≠ RPS

They measure different things.

Consider an application with:

text
100,000 active users

If each user sends:

text
1 request every 10 seconds

then the approximate request rate is:

text
100,000 / 10
= 10,000 RPS

Concurrency depends on how long those requests remain in flight.

Which brings us to latency.

6. Latency

Latency is the time required to complete an operation.

For an API:

text
Client

Request

Server

Response

If the response arrives after:

text
100 ms

the request latency is approximately:

100 milliseconds.

Latency matters because it affects how much work can be simultaneously in flight.

Imagine:

text
1,000 RPS

with:

text
100 ms latency

A useful approximation from Little's Law is:

text
Concurrency ≈ Throughput × Latency

Therefore:

text
Concurrency ≈ 1,000 × 0.1
             ≈ 100

So approximately 100 requests may be in flight at any given moment.

Now imagine latency increases to:

text
2 seconds

Then:

text
Concurrency ≈ 1,000 × 2
             ≈ 2,000

Same request rate.

But dramatically more work is simultaneously in flight.

This is one reason latency and scalability are deeply connected.

7. Throughput

Throughput is how much work the system successfully processes per unit of time.

For an API, throughput might be:

text
5,000 successful requests/sec

For a messaging system:

text
100,000 messages/sec

For a database:

text
50,000 transactions/sec

Traffic represents incoming demand.

Throughput represents successfully processed work.

Imagine:

text
Incoming traffic

   10,000 RPS

   Application

    7,000 RPS

If the system can only process 7,000 requests/sec, then:

text
Traffic   = 10,000 RPS
Throughput = 7,000 RPS

The remaining demand may:

  • Queue up
  • Time out
  • Get rejected
  • Be dropped
  • Cause retries

This is where capacity becomes important.

8. Capacity

Capacity is the maximum workload a system can handle while staying within defined performance and reliability requirements.

Suppose you define your requirements as:

text
Latency < 200 ms
Error rate < 0.1%

You benchmark your service and discover:

text
1 server → 1,000 RPS

while maintaining those requirements.

You might say:

The server has approximately 1,000 RPS of capacity under this workload.

But capacity isn't a universal number.

It depends on:

  • Request type
  • Hardware
  • Software
  • Dataset size
  • Query complexity
  • Network conditions
  • Latency target
  • Error-rate target
  • Resource utilization

For example:

text
Capacity @ 200ms latency = 1,000 RPS
Capacity @ 500ms latency = 1,500 RPS

You technically processed more requests.

But the system became slower.

Therefore:

Capacity must always be defined relative to an acceptable service level.

9. Resource Utilization

Every system consumes resources.

Common examples include:

  • CPU
  • Memory
  • Disk
  • Network bandwidth
  • Database connections
  • File descriptors
  • Threads
  • Connection pools
  • GPU
  • IOPS

We often express utilization as a percentage.

For example:

text
CPU:       70%
Memory:    60%
Network:   40%
Disk I/O:  80%
DB pool:   90%

A common mistake is to look only at CPU.

Imagine:

text
CPU       → 30%
Memory    → 40%
DB pool   → 100%

Your application might appear “healthy” from a CPU perspective.

But requests are waiting for database connections.

The database connection pool is the bottleneck.

This leads to one of the most important ideas in scalability:

The slowest or most constrained resource often determines system capacity.

10. Bottlenecks

A bottleneck is a component that limits the overall performance or capacity of the system.

Consider:

text
             ┌── Application Server
Traffic ────►├── Application Server
             └── Application Server

                 Database

Suppose the application servers can collectively handle:

text
20,000 RPS

but the database can only handle:

text
5,000 RPS

Then your system's effective capacity may be close to:

5,000 RPS

The database is the bottleneck.

Adding more application servers won't solve the fundamental problem.

You could have:

text
10 servers
50 servers
100 servers

and still be limited by the database.

This is why:

Scaling the wrong component doesn't scale the system.

11. Limiting Resources

A system usually has one or more limiting resources.

For example:

text
CPU-bound service

might be limited by CPU.

A database-heavy service might be limited by:

text
DB connections

A file-processing system might be limited by:

text
Disk I/O

An API gateway might be limited by:

text
Network bandwidth

A service calling another API might be limited by:

text
External API rate limits

So when designing for scale, ask:

What resource will run out first?

That's often more useful than asking:

“How many servers do we need?”

12. Saturation

As workload increases, resource utilization increases.

For example:

text
RPS       CPU
100       10%
500       30%
1000      50%
1500      70%
2000      90%
2500      100%

At some point, the resource becomes saturated.

Saturation means a resource is operating at or near its effective limit.

Once a critical resource becomes saturated, performance often deteriorates rapidly.

You might see:

text
CPU ↑
Queue length ↑
Latency ↑
Timeouts ↑
Errors ↑

This is why running every server at 100% utilization is generally a terrible scaling strategy.

You need headroom.

13. The Knee Point

One of the most useful concepts in performance engineering is the knee point.

Imagine plotting:

text
Load → Latency

Initially:

text
Load increases

Latency increases slowly

Then you reach a point where latency suddenly starts increasing much faster.

Conceptually:

text
Latency

   │                 /
   │               /
   │             /
   │           /
   │        __/
   │______/
   └────────────────── Load

         Knee point

The knee point is where the system transitions from:

“Everything is behaving nicely”

to:

“Additional load is causing disproportionate performance degradation.”

This is extremely important for capacity planning.

You don't want to operate permanently at the absolute maximum capacity.

You want sufficient headroom before the knee point.

14. Vertical Scaling — Scale Up

The simplest scaling strategy is:

Make the machine bigger.

For example:

text
4 CPU
16 GB RAM

16 CPU
64 GB RAM

This is called:

Vertical scaling / Scale Up

It's simple because you don't fundamentally change the architecture.

For example:

text
              ┌──────────────┐
Traffic ────► │ Large Server │
              └──────────────┘

Advantages:

  • Simple
  • Easy to operate
  • Often requires minimal application changes
  • Useful for databases and stateful workloads

But there are limitations.

A machine has physical limits.

You can't infinitely increase:

text
CPU
RAM
Network
Disk

And larger machines can become increasingly expensive.

Which brings us to horizontal scaling.

15. Horizontal Scaling — Scale Out

Horizontal scaling means:

Add more machines instead of making one machine bigger.

Instead of:

text
       ┌──────────┐
──────►│ Server   │
       └──────────┘

you create:

text
              ┌──────────┐
          ┌──►│ Server 1 │
          │   └──────────┘
Traffic ──┤
          │   ┌──────────┐
          ├──►│ Server 2 │
          │   └──────────┘

          │   ┌──────────┐
          └──►│ Server 3 │
              └──────────┘

Usually a load balancer distributes traffic.

This provides a potentially much larger scaling range.

For example:

text
1 server  → 1,000 RPS
2 servers → ~2,000 RPS
5 servers → ~5,000 RPS

But notice the word:

~

Because horizontal scaling is not automatically linear.

16. Why Scaling Isn't Always Linear

Suppose:

text
1 server → 1,000 RPS

You might assume:

text
10 servers → 10,000 RPS

But real systems have overhead.

For example:

text
1 server → 1,000 RPS
2 servers → 1,900 RPS
4 servers → 3,600 RPS
8 servers → 6,500 RPS

Why?

Because the servers might share:

  • Database
  • Network
  • Cache
  • Message broker
  • Storage
  • Coordination mechanisms

Eventually another bottleneck appears.

This leads to:

Diminishing returns.

17. Diminishing Returns

Diminishing returns means:

Each additional unit of resource produces less additional capacity than the previous one.

Imagine:

text
Servers      Capacity

1            1,000 RPS
2            1,900 RPS
4            3,500 RPS
8            5,500 RPS
16           7,000 RPS

Adding servers still increases capacity.

But not proportionally.

Why?

Because the workload isn't perfectly parallelizable.

Some part of the system remains shared.

For example:

text
             ┌── Server 1 ──┐
             ├── Server 2 ──┤
Traffic ───► ├── Server 3 ──┤ ──► Database
             └── Server 4 ──┘

If the database becomes saturated, adding more application servers doesn't help.

This is closely related to Amdahl's Law:

The portion of work that cannot be parallelized limits the maximum speedup you can achieve.

18. A Simple End-to-End Example

Let's put everything together.

Imagine you run an e-commerce API.

Your system receives:

text
5,000 RPS

Each request:

text
API

Application

Redis

PostgreSQL

Your current measurements are:

text
CPU        → 45%
Memory     → 50%
Redis      → 30%
Database   → 85%
Latency    → 120 ms

Everything appears healthy.

Now traffic increases:

text
5,000 RPS

8,000 RPS

Measurements become:

text
CPU        → 65%
Memory     → 55%
Redis      → 40%
Database   → 98%
Latency    → 250 ms

What happened?

The application servers aren't necessarily the problem.

The database is approaching saturation.

Now suppose you horizontally scale the application:

text
4 servers

8 servers

CPU drops.

But database utilization becomes:

text
100%

and latency becomes:

text
500 ms

You haven't solved scalability.

You've simply moved the bottleneck closer to the database.

The same system, as one architecture diagram

Traffic enters through NGINX, fans out across stateless app servers, and converges on shared infrastructure — Redis, PostgreSQL, the payment API. The app tier scales horizontally. The shared tier is where saturation shows up first. In the numbers above, that shared resource is the database.

19. The Scalability Mental Model

A useful way to reason about systems is:

text
                 TRAFFIC

                   LOAD

         ┌──────────┴──────────┐
         ↓                     ↓
       RPS                CONCURRENCY
         │                     │
         └──────────┬──────────┘

                 WORKLOAD

              RESOURCE USAGE

               BOTTLENECK

                SATURATION

                 LATENCY

              SYSTEM CAPACITY

When the workload increases, resources become increasingly utilized.

Eventually one resource becomes the limiting factor.

That creates a bottleneck.

The bottleneck approaches saturation.

Latency increases.

Eventually the system reaches its effective capacity.

Scaling means increasing that capacity without violating your performance and reliability requirements.

20. Capacity Planning

Now we can finally talk about capacity planning.

Capacity planning is the process of estimating:

How much infrastructure you need to handle expected future workload while maintaining acceptable performance and reliability.

Suppose your current traffic is:

text
10,000 RPS

and you expect:

text
20% growth/month

You shouldn't simply provision infrastructure for:

text
10,000 RPS

You need to consider:

  • Expected growth
  • Peak traffic
  • Traffic spikes
  • Failure scenarios
  • Resource utilization
  • Latency requirements
  • Database capacity
  • Network capacity
  • Cost
  • Safety margin

For example:

text
Expected peak = 20,000 RPS

Required headroom = 30%

Target capacity =
20,000 × 1.3

= 26,000 RPS

Now you're planning for:

26,000 RPS

rather than hoping the system survives exactly 20,000.

21. Capacity Is Not Just “How Many Servers?”

This is an important mindset shift.

A junior engineer might ask:

“How many servers do we need for 100,000 users?”

A better question is:

“What workload does 100,000 users generate?”

Then:

“What resources does that workload consume?”

Then:

“Which resource saturates first?”

Then:

“How can we increase the capacity of that resource?”

For example:

text
100,000 users

10,000 concurrent users

2,000 RPS

6,000 DB queries/sec

Database CPU = 95%

Database is bottleneck

Now you have an engineering problem you can actually solve.

22. Scalability Is a Property of the Entire System

One of the biggest misconceptions in system design is:

“Our application servers scale horizontally, therefore our system is scalable.”

Not necessarily.

Consider:

text
              Load Balancer

        ┌───────────┼───────────┐
        ↓           ↓           ↓
     App 1       App 2       App 3
        └───────────┼───────────┘

                 Database

The application layer might scale beautifully.

But if the database cannot scale with it, the overall system eventually stops scaling.

Similarly:

text
Application

Redis

External API

The external API might impose:

text
10,000 requests/minute

That becomes your limiting factor.

Therefore:

Scalability is a system-level property, not a property of an individual server.

23. What Engineers Should Actually Measure

When investigating scalability, don't look at a single metric.

Look at the relationship between metrics.

A useful dashboard might include:

Traffic

text
RPS

Concurrency

text
Active requests
Open connections
Queue depth

Performance

text
p50 latency
p95 latency
p99 latency

Resources

text
CPU
Memory
Disk I/O
Network
DB connections

Reliability

text
Error rate
Timeouts
Retries
Dropped requests

Then ask:

What changed first as load increased?

That's often how you find the bottleneck.

24. Don't Optimize What Isn't the Bottleneck

Suppose you have:

text
CPU = 30%
Memory = 40%
Database = 99%

And you spend two weeks optimizing application CPU.

You might reduce:

text
CPU: 30% → 20%

Congratulations.

But your system's capacity might barely change.

Why?

Because the database was limiting the system.

This is one of the most important engineering principles:

Optimize the constraint, not the component that happens to look easiest to optimize.

25. Scalability vs Performance

These concepts are related but different.

Performance

Asks:

“How fast is the system?”

For example:

text
API latency = 80 ms

Scalability

Asks:

“How does performance change as workload increases?”

For example:

text
1,000 RPS  → 80 ms
5,000 RPS  → 100 ms
10,000 RPS → 140 ms
20,000 RPS → 400 ms

This tells us much more about scalability.

A system can be extremely fast at low load but scale terribly.

Another system might be slightly slower initially but maintain predictable performance as load grows.

26. The Real Definition of a Scalable System

A scalable system isn't necessarily one that can handle:

“Millions of users.”

A better definition is:

A scalable system is one where capacity can be increased predictably as workload increases, without unacceptable degradation in latency, reliability, or cost.

That final part—cost—matters.

If doubling traffic requires 20× more infrastructure, the system technically scales, but poorly.

Good scalability considers:

text
Performance
+
Reliability
+
Capacity
+
Cost

27. A Practical Scalability Checklist

When you're asked:

“Can this system scale?”

Walk through these questions.

1. What is the workload?

text
RPS?
Messages/sec?
Concurrent requests?
Data volume?

2. What does one unit of work cost?

text
CPU?
Memory?
DB queries?
Network?
Disk?

3. What is the current capacity?

text
How much workload can one instance handle?

4. What is the limiting resource?

text
CPU?
DB?
Memory?
Network?
Connections?

5. Where is the bottleneck?

text
Application?
Database?
Cache?
Queue?
External dependency?

6. How does it scale?

text
Vertical?
Horizontal?
Both?

7. Where is the knee point?

At what load does latency begin increasing rapidly?

8. What happens during failure?

Can the system survive:

text
1 server failure?
1 AZ failure?
Database failure?
Traffic spike?

9. How much headroom do we need?

Don't design only for today's traffic.

10. What happens to cost?

Does capacity increase reasonably as workload increases?

28. The One Mental Model You Should Remember

If you remember only one thing from this article, remember this:

text
More Users

More Traffic

More Load

Higher RPS / Concurrency

More Resource Consumption

Resource Becomes Bottleneck

Resource Approaches Saturation

Latency Starts Increasing

System Reaches Capacity

We Need To Scale

And scaling means finding a way to move that constraint.

Sometimes that's:

text
Scale Up

Sometimes:

text
Scale Out

Sometimes it's:

text
Caching

Sometimes:

text
Database optimization

Sometimes:

text
Async processing

Sometimes:

text
Partitioning

And sometimes the answer is simply:

Stop doing unnecessary work.

That's scalability thinking.

29. Final Takeaway

Scalability isn't about memorizing technologies.

You don't become good at system design because you know:

Kubernetes + Kafka + Redis + PostgreSQL + AWS.

You become good at system design when you can look at a workload and reason:

How much work is arriving?

How much work can each component handle?

Which resource becomes constrained first?

When does the system hit its knee point?

How does adding resources change capacity?

What happens when the workload doubles?

That's the foundation of scalability.

Once you understand load, RPS, concurrency, throughput, latency, capacity, utilization, bottlenecks, saturation, scaling, and capacity planning, the architecture decisions that come later become much easier to reason about.

Because instead of saying:

“Let's add Kubernetes.”

You start asking:

“What exactly are we trying to scale?”

And that is the question that leads to better system designs.

Want to practice this intuition?

Reading about system design is useful.

But saying your reasoning out loud under pressure is a completely different skill.

That's why I built Intervues — a platform designed to help engineers practice technical interviews by actually speaking through their answers instead of relying on an AI copilot to feed them responses. See pricing; hiring teams can explore companies.

If you're preparing for system design, backend, software engineering, or technical interviews, practice explaining concepts like scalability, bottlenecks, databases, distributed systems, and architecture out loud.

Practice the interview before the interview.

Visit intervues.club and try it yourself.

Hey — it's Ayoush.

Nine years as an engineer, three interviewing candidates. I built Intervues because the gap isn't knowledge — it's saying what you know out loud. Real email at the other end: admin@intervues.club.

Keep reading

Rehearse the room. Then walk in ready.

An interview is the first day of the job — practice before it counts.

3 free credits · pay per interview · nothing recurring