| Users | System State | Changes |
|---|---|---|
| 100 users | Legacy monolith handles all requests | Minimal load, no new microservices yet |
| 10,000 users | Initial microservices start replacing parts of monolith | Routing layer added, some services extracted, moderate traffic |
| 1,000,000 users | Most features served by microservices, monolith shrinks | API gateway scales horizontally, microservices scale independently |
| 100,000,000 users | Monolith fully replaced, large microservices ecosystem | Advanced service mesh, global load balancing, data sharding |
Strangler fig pattern in Microservices - Scalability & System Analysis
Start learning this pattern below
Jump into concepts and practice - no test required
At small scale, the legacy monolith is the bottleneck because it handles all requests and is hard to scale horizontally.
As traffic grows, the routing layer and API gateway can become bottlenecks if not scaled properly.
Eventually, database access shared by monolith and microservices can limit throughput.
- Incremental migration: Gradually replace monolith features with microservices to reduce risk.
- API Gateway: Use a scalable gateway to route requests to microservices or legacy system.
- Horizontal scaling: Add more instances of microservices and gateway to handle load.
- Caching: Cache common responses to reduce load on backend services.
- Database strategies: Use read replicas, sharding, or separate databases per microservice.
- Service mesh: Manage microservice communication efficiently at large scale.
Assuming 1M users generate 10,000 requests per second total:
- Requests per second: ~10,000 QPS
- API Gateway instances: 3-5 servers (each handles ~2000-3000 QPS)
- Microservices: scaled independently, each 1-3 servers depending on load
- Database: read replicas to handle ~10,000 QPS, write capacity scaled or sharded
- Bandwidth: 10,000 QPS * 1 KB/request = ~10 MB/s (well within 1 Gbps network)
- Storage: depends on data retention, but microservices can use separate DBs to optimize
Start by explaining the legacy monolith and its limitations.
Describe how the strangler fig pattern incrementally replaces parts with microservices.
Discuss bottlenecks at each stage and how to scale routing, services, and data.
Highlight trade-offs between risk, complexity, and scalability.
Your database handles 1000 QPS. Traffic grows 10x. What do you do first?
Answer: Add read replicas and implement caching to reduce database load before scaling writes or sharding.
Practice
Strangler fig pattern in microservices architecture?Solution
Step 1: Understand the pattern's purpose
The Strangler fig pattern is designed to replace legacy systems gradually, not all at once.Step 2: Compare options with the pattern goal
To gradually replace parts of a legacy system with new services matches the gradual replacement approach, while others describe different strategies.Final Answer:
To gradually replace parts of a legacy system with new services -> Option DQuick Check:
Gradual replacement = B [OK]
- Thinking it replaces the whole system at once
- Confusing it with parallel running without integration
- Assuming it merges services into one
Solution
Step 1: Identify routing strategy in Strangler fig
The pattern routes requests gradually from old to new components, not all at once or randomly.Step 2: Match options with routing approach
Route requests step-by-step from the legacy system to new microservices describes step-by-step routing, which fits the pattern best.Final Answer:
Route requests step-by-step from the legacy system to new microservices -> Option CQuick Check:
Step-by-step routing = A [OK]
- Routing all requests to legacy until full switch
- Routing requests randomly causing inconsistency
- Stopping legacy before new system ready
Legacy system handles requests for features A, B, C. New microservice replaces feature A. Requests for A go to new service; B and C go to legacy. What happens when a request for feature B arrives?
Solution
Step 1: Analyze routing rules for features
Only feature A is replaced by the new microservice; B and C remain in legacy.Step 2: Determine routing for feature B request
Requests for B still go to legacy system as it is not replaced yet.Final Answer:
It is routed to the legacy system since B is not replaced yet -> Option BQuick Check:
Feature B not replaced = legacy route = C [OK]
- Routing all requests to new service regardless of feature
- Assuming missing features cause errors
- Dropping requests instead of routing properly
Solution
Step 1: Identify issue with premature routing
Routing all requests early means new service may not handle all features yet.Step 2: Understand impact on system behavior
This causes inconsistent or failed responses for unsupported features.Final Answer:
It leads to inconsistent behavior as new service lacks some features -> Option AQuick Check:
Premature routing = inconsistent behavior = A [OK]
- Thinking early routing improves performance always
- Assuming legacy can be stopped immediately
- Ignoring feature support gaps
Solution
Step 1: Prioritize critical feature migration
Feature X requires zero downtime, so migrate it first carefully.Step 2: Apply gradual routing for feature X only
Route requests for X to new microservice while Y and Z remain on legacy to reduce risk.Step 3: Avoid full switch or stopping legacy abruptly
The other options risk downtime or complexity by switching all features at once.Final Answer:
Replace feature X first with a new microservice and route only X requests there, keep Y and Z on legacy -> Option AQuick Check:
Gradual critical feature migration = D [OK]
- Trying to replace all features at once
- Stopping legacy before new system ready
- Delaying critical feature migration
