System Design / Curriculum / Day 2

DAY 2 Phase 1 Β· Scalability 15 min read 0 / 10 Mastered

Scalability, Load Balancing & Stateless Services

Horizontal vs vertical scaling, Layer 4 vs Layer 7 load balancers, health checks, stateless architecture, sticky sessions, and eliminating single points of failure (SPOF).

πŸš€ System Design Interview Preparation β€” Day 2

Topic: Scalability, Load Balancing & Stateless Services

Day 1 taught us how to approach a system-design problem.

Today we'll understand one of the most important building blocks of scalable systems:

How do we handle increasing traffic without relying on one server?

This topic comes up constantly in .NET/Azure interviews.


1. Why Do We Need Scalability?

Imagine you have an ASP.NET Core Web API running on one server:

Architecture Blueprint
              Users
                β”‚
                β–Ό
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚ API Server  β”‚
         β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                β”‚
                β–Ό
            Database

Initially:

Architecture Blueprint
1,000 requests/sec

Maybe the server handles it comfortably.

But your application grows:

Architecture Blueprint
10,000 requests/sec

Now the server becomes overloaded.

Eventually:

Architecture Blueprint
CPU β†’ 100%
Memory β†’ High
Response time β†’ Increasing
Requests β†’ Timing out

We need to scale.


2. Vertical Scaling

We covered this briefly on Day 1.

You make the existing machine more powerful.

Architecture Blueprint
Before:

4 CPU
8 GB RAM

       ↓

After:

16 CPU
64 GB RAM

Advantages

  • Simple
  • Minimal architectural changes
  • Easy for smaller systems

Disadvantages

  • Hardware limits
  • Increasing cost
  • Potential single point of failure
  • Eventually you cannot keep scaling vertically

3. Horizontal Scaling

Instead of making one server bigger, add more servers.

Architecture Blueprint
                 Users
                   β”‚
                   β–Ό
             Load Balancer
             /      |      \
            β–Ό       β–Ό       β–Ό
         Server1 Server2 Server3

If one server handles:

Architecture Blueprint
5,000 requests/sec

three servers could potentially handle roughly:

Architecture Blueprint
15,000 requests/sec

assuming the workload distributes evenly and the rest of the architecture can support it.

Why is horizontal scaling powerful?

Because you can continue adding instances:

Architecture Blueprint
3 servers
   ↓
10 servers
   ↓
50 servers
   ↓
100 servers

This is fundamental to distributed systems.


4. What is a Load Balancer?

A load balancer distributes incoming requests across multiple backend servers.

Without load balancing:

Architecture Blueprint
Users
  β”‚
  β–Ό
Server

With load balancing:

Architecture Blueprint
                 Users
                   β”‚
                   β–Ό
             Load Balancer
             /      |      \
            β–Ό       β–Ό       β–Ό
         Server1 Server2 Server3

The load balancer acts as the entry point for backend servers.


5. Why Do We Need a Load Balancer?

There are several reasons.

1. Distribute traffic

Instead of sending every request to one server:

Architecture Blueprint
100% β†’ Server 1

we can distribute:

Architecture Blueprint
33% β†’ Server 1
33% β†’ Server 2
34% β†’ Server 3

2. Scalability

If traffic increases:

Architecture Blueprint
Before:

LB
β”œβ”€β”€ Server 1
└── Server 2

We can add:

Architecture Blueprint
LB
β”œβ”€β”€ Server 1
β”œβ”€β”€ Server 2
β”œβ”€β”€ Server 3
β”œβ”€β”€ Server 4
└── Server 5

3. Fault tolerance

Suppose:

Architecture Blueprint
Server 2 ❌

The load balancer can stop sending traffic to that unhealthy server.

Architecture Blueprint
                 Load Balancer
                /      |      \
               β–Ό       X       β–Ό
           Server 1  Server 2  Server 3
             βœ…         ❌        βœ…

Users can continue using the system.


6. Types of Load Balancers

At a high level:

Layer 4 Load Balancer

Works primarily with network-level information such as:

  • IP
  • TCP
  • Port

Example:

Architecture Blueprint
Client
  ↓
TCP
  ↓
Load Balancer
  ↓
Server

Layer 7 Load Balancer

Works at the application/HTTP level.

It can inspect things such as:

Architecture Blueprint
HTTP method
URL
Headers
Cookies
Host

For example:

Architecture Blueprint
/api/products
      ↓
Product Service

/api/orders
      ↓
Order Service

Layer 7 load balancing is especially useful when routing decisions depend on HTTP-level information.


7. Load Balancing Algorithms

The interviewer may ask:

"How does a load balancer decide which server receives a request?"

There are several approaches.


Round Robin

Requests are distributed sequentially.

Architecture Blueprint
Request 1 β†’ Server 1
Request 2 β†’ Server 2
Request 3 β†’ Server 3
Request 4 β†’ Server 1
Request 5 β†’ Server 2

Pattern:

Architecture Blueprint
S1 β†’ S2 β†’ S3 β†’ S1 β†’ S2 β†’ S3

Simple and commonly used.


8. Weighted Round Robin

Not every server has the same capacity.

Suppose:

Architecture Blueprint
Server 1 β†’ powerful
Server 2 β†’ medium
Server 3 β†’ small

We could assign:

Architecture Blueprint
Server 1 β†’ weight 5
Server 2 β†’ weight 3
Server 3 β†’ weight 2

The stronger server receives more traffic.


9. Least Connections

The load balancer sends a new request to the server with the fewest active connections.

Example:

Architecture Blueprint
Server 1 β†’ 100 connections
Server 2 β†’ 50 connections
Server 3 β†’ 20 connections

New request:

Architecture Blueprint
             ↓
         Server 3

This can be useful when requests have different processing times.


10. IP Hash

The load balancer calculates a hash based on the client's IP.

Conceptually:

Architecture Blueprint
Client IP
   ↓
Hash
   ↓
Server

This can help maintain affinity for a client, although relying on IP-based affinity has limitations and is not automatically the best solution.


11. Health Checks

This is an important interview concept.

Suppose we have:

Architecture Blueprint
Server 1 βœ…
Server 2 ❌
Server 3 βœ…

How does the load balancer know Server 2 is unhealthy?

Through health checks.

For example:

http
GET /health

Server responds:

http
200 OK

The load balancer considers it healthy.

If it repeatedly fails:

Architecture Blueprint
500
Timeout
Connection refused

the load balancer can temporarily remove the server from rotation.


12. ASP.NET Core Health Checks

Since you're preparing for .NET interviews, this is particularly relevant.

ASP.NET Core supports health checks.

Conceptually:

csharp
builder.Services.AddHealthChecks();

Then:

csharp
app.MapHealthChecks("/health");

Now an infrastructure component can check:

Architecture Blueprint
GET /health

You can also add checks for dependencies such as databases.

For example:

Architecture Blueprint
Application
    β”‚
    β”œβ”€β”€ API
    β”œβ”€β”€ SQL Server
    β”œβ”€β”€ Redis
    └── External API

A production health strategy may distinguish between:

Liveness

Is the application process alive?

Readiness

Is the application ready to receive traffic?

This distinction becomes very important in containerized environments.


13. What is a Stateless Service?

This is one of today's most important concepts.

A stateless server doesn't rely on local server memory to maintain a user's session between requests.

Imagine:

Architecture Blueprint
Request 1 β†’ Server 1
Request 2 β†’ Server 2
Request 3 β†’ Server 3

The application should still know who the user is.

The server shouldn't depend on:

Architecture Blueprint
Server 1's RAM

for essential session state.


14. Stateful vs Stateless

Stateful

Architecture Blueprint
User
 ↓
Server 1

Session stored in Server 1 memory

Next request:

Architecture Blueprint
User
 ↓
Server 2

❌ Server 2 doesn't know the session

This creates problems when horizontally scaling.


Stateless

Instead:

Architecture Blueprint
User
 ↓
Load Balancer
 ↓
Any Server

State can be stored externally:

Architecture Blueprint
             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
             β”‚ API Servers β”‚
             β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
             β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”
             β”‚             β”‚
           Redis        Database

Now any server can handle the request.


15. JWT and Stateless Authentication

This connects directly with what you've been learning in ASP.NET Core.

With JWT authentication:

Architecture Blueprint
Login
  ↓
Authentication Service
  ↓
JWT
  ↓
Client

The client sends:

http
Authorization: Bearer <token>

with subsequent requests.

Any API instance can validate the token.

Architecture Blueprint
             Load Balancer
             /     |     \
            β–Ό      β–Ό      β–Ό
          API1    API2    API3
            \      |      /
             \     |     /
              Database

This is one reason token-based authentication can work well with horizontally scaled APIs.

Important: "JWT = always stateless" is an oversimplification. If your system maintains server-side session/revocation state, some state still exists. The key interview point is that the API instances don't need to keep the user's primary session in local memory.


16. Session Stickiness

You may hear:

Sticky sessions

or:

Session affinity

This means the load balancer tries to send the same user's requests to the same server.

Architecture Blueprint
User A
  ↓
Load Balancer
  ↓
Server 1

User A's future requests
  ↓
Server 1

This can make stateful applications easier to operate.

But it has disadvantages:

  • Uneven traffic
  • Reduced flexibility
  • Server failure can affect sessions
  • Scaling becomes more complicated

Therefore, for many modern APIs, we prefer:

Stateless application servers + shared external state when state is required.


17. Scaling with External State

Suppose you have:

Architecture Blueprint
API Server 1
API Server 2
API Server 3

and all need access to:

Architecture Blueprint
Session
Cache
Shared data

Don't put it only in:

Architecture Blueprint
API Server 1 memory

Instead:

Architecture Blueprint
                Load Balancer
              /      |      \
             β–Ό       β–Ό       β–Ό
           API1     API2    API3
              \      |      /
               \     |     /
                β–Ό    β–Ό    β–Ό
                  Redis
                    β”‚
                    β–Ό
                 Database

Redis can provide shared in-memory data, while the database provides durable storage.

We'll study Redis properly later.


18. Single Point of Failure

Imagine:

Architecture Blueprint
             Load Balancer
                   β”‚
                   β–Ό
                Server

If the server fails:

Architecture Blueprint
Server ❌

Entire application is unavailable.

That's a single point of failure (SPOF).

A common approach is redundancy:

Architecture Blueprint
             Load Balancer
             /      |      \
            β–Ό       β–Ό       β–Ό
          API1     API2    API3

Now one API server can fail without necessarily bringing down the whole application.

But notice something subtle:

If you have only one load balancer, the load balancer itself could become a single point of failure.

In production systems, infrastructure components are typically designed with redundancy/failover as appropriate.


19. Complete Example

Suppose we have an ASP.NET Core e-commerce API.

A simplified architecture:

Architecture Blueprint
                    Internet
                       β”‚
                       β–Ό
                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚Load Balancerβ”‚
                β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜
                       β”‚
            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
            β–Ό          β–Ό          β–Ό
         API 1       API 2       API 3
            β”‚          β”‚          β”‚
            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”
              β–Ό                 β–Ό
           Redis             SQL Server

Request:

Architecture Blueprint
GET /api/products/100

Flow:

Architecture Blueprint
Client
  ↓
Load Balancer
  ↓
API Server
  ↓
Redis
  β”‚
  β”œβ”€β”€ Cache Hit β†’ Return product
  β”‚
  └── Cache Miss
          ↓
       SQL Server
          ↓
       Store in Redis
          ↓
       Return response

This architecture gives us:

  • Horizontal scalability
  • Load distribution
  • Fault tolerance at the API tier
  • Shared caching
  • Durable database storage

20. Azure Mapping β€” Important for Your Interviews

Because you're targeting .NET + Azure roles, you should learn to map these concepts to Azure services.

Conceptually:

Architecture Blueprint
                 Internet
                    β”‚
                    β–Ό
          Azure Load Balancer /
          Application Gateway
                    β”‚
                    β–Ό
             ASP.NET Core APIs
             /       |       \
            β–Ό        β–Ό        β–Ό
         Instance Instance Instance
                    β”‚
             β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”
             β–Ό             β–Ό
          Azure Cache    Azure SQL
          for Redis

The exact Azure service depends on the architecture and whether you need L4 or L7 routing, WAF, global distribution, etc.

We'll cover Azure-specific system design later rather than memorizing service names now.


🎯 Day 2 Interview Questions

As with DSA and SQL, try these yourself first.

Q1.

What is horizontal scaling and why is it preferred for many large-scale systems?

Q2.

What is the difference between vertical and horizontal scaling?

Q3.

What is a load balancer and why do we need one?

Q4.

What is the difference between Layer 4 and Layer 7 load balancing?

Q5.

Explain Round Robin, Weighted Round Robin, Least Connections and IP Hash.

Q6.

What is a health check? Why is it important?

Q7.

What is the difference between a stateful and stateless service?

Q8.

Why are stateless services easier to scale horizontally?

Q9.

What are sticky sessions? What are their advantages and disadvantages?

Q10.

What is a Single Point of Failure? How would you design a system to avoid it?


πŸ”₯ Bonus Interview Scenario

You have an ASP.NET Core API running on one Windows/Azure VM.

Traffic increases from:

Architecture Blueprint
1,000 requests/sec

to:

Architecture Blueprint
20,000 requests/sec

The interviewer asks:

"How would you scale this application?"

Your thought process should now be:

Architecture Blueprint
Single API server
       ↓
Multiple API instances
       ↓
Load Balancer
       ↓
Stateless APIs
       ↓
Shared Cache / Database
       ↓
Health Checks
       ↓
Auto Scaling

Don't immediately jump to microservices.

A horizontally scaled monolith can be perfectly valid.

That's an important system-design lesson.


🧠 Day 2 Key Takeaways

Remember these 7 points:

Architecture Blueprint
1. Vertical scaling  β†’ Bigger machine

2. Horizontal scaling β†’ More machines

3. Load balancer      β†’ Distributes traffic

4. Health check       β†’ Detects unhealthy instances

5. Stateless API      β†’ Any instance can handle request

6. Sticky session     β†’ Routes user to same instance

7. SPOF               β†’ Component whose failure can
                         bring down the system

and I'll give you the interview-ready answers + common follow-up questions + .NET/Azure examples.

Day 2 Interview Questions & Answers

Real-world verbal answers designed to articulate clearly in high-stakes technical interviews.

Day 2 Flashcard Drill

Practice these 10 questions using 3D interactive flashcards. Click or press Space to flip.

Day 2 Q1 UNMASTERED

Loading question...

Day 2 VERBAL ANSWER

...

Card 1 of 10
Copied to clipboard!