Script Valley
System Design: APIs, Caching & Scalability
Scalability Patterns/Assessment

Practice & Assessment

Test your understanding of Scalability Patterns

Multiple Choice Questions

6
1

A user updates their avatar and immediately refreshes. They see the old avatar. The app uses a read replica for profile fetches. What is the cause?

2

Why is IP hash load balancing an anti-pattern for horizontally scaled stateless services?

3

Which CDN caching directive allows the CDN to cache with a different TTL than the browser?

4

A payment service receives the same POST /payments request twice due to a client retry. How should the service handle this without charging the user twice?

5

Your application stores user sessions in server memory. You add a second server behind a load balancer. What breaks immediately?

6

When should you choose sharding over adding read replicas?

Coding Challenges

1
1

Build a stateless session middleware with Redis

Implement Express middleware that stores sessions in Redis instead of memory. Each session has a UUID session ID stored in a signed cookie. On each request read the session from Redis using the cookie value. Implement POST /login storing username in Redis session, GET /me returning user data if session exists (401 if not), and POST /logout deleting the Redis key. Input: JSON body with username on /login. Output: 200 with user data on /me if session valid, 401 if not found. Session TTL: 30 minutes, refreshed on each request. Estimated time: 25 minutes.

Medium

Mini Project

1

Horizontally Scalable API with Load Balancing

Using Docker Compose, run 3 instances of a Node.js Express API behind an Nginx load balancer using round-robin. The API exposes GET /whoami returning instance ID from env var, POST /login creating a Redis session, GET /me reading the Redis session, and DELETE /logout. Sessions must persist across instances via shared Redis store. Add GET /health on each instance. Configure Nginx to skip unhealthy instances using proxy_next_upstream on error. Add GET /stats returning which instance served each of the last 10 requests stored in a Redis list. Demonstrate that removing one container does not break the session for a logged-in user.

Hard