| Scale | Users | Requests per Second (RPS) | Data Storage | System Changes |
|---|---|---|---|---|
| Small | 100 users | ~10 RPS | Few MBs (policy rules, logs) | Single server, simple DB, no caching |
| Medium | 10,000 users | ~1,000 RPS | GBs (policy versions, user requests) | DB read replicas, caching, load balancer |
| Large | 1,000,000 users | ~50,000 RPS | TBs (logs, audit trails, refunds) | Sharded DB, distributed cache, microservices |
| Very Large | 100,000,000 users | ~5,000,000 RPS | Petabytes (archived data, analytics) | Multi-region deployment, CDN, event-driven architecture |
Cancellation and refund policy in LLD - Scalability & System Analysis
Start learning this pattern below
Jump into concepts and practice - no test required
At small to medium scale, the database becomes the first bottleneck. This is because all cancellation and refund requests require consistent reads and writes to policy data and transaction records. The DB must handle many concurrent queries and updates, especially during peak refund periods.
- Database Scaling: Use read replicas to distribute read load. Implement connection pooling to manage DB connections efficiently.
- Caching: Cache static policy rules and frequently accessed refund statuses to reduce DB hits.
- Horizontal Scaling: Add more application servers behind a load balancer to handle increased request volume.
- Sharding: Partition the database by user ID or region to distribute write load and improve performance.
- Event-Driven Architecture: Use message queues to process refunds asynchronously, reducing synchronous DB load.
- Multi-Region Deployment: Deploy services closer to users to reduce latency and distribute traffic.
- At 10,000 users with ~1,000 RPS, assuming each request is 1 KB, bandwidth needed is ~1 MB/s.
- Storage for policy data and logs grows from MBs to GBs as users increase.
- Refund processing requires additional compute resources; asynchronous processing reduces peak load.
- Database must handle up to 1,000 QPS at medium scale; plan for replicas and sharding accordingly.
Start by identifying key components: user requests, policy data, refund transactions. Discuss expected load and data growth. Identify bottlenecks early, usually the database. Propose scaling solutions step-by-step: caching, read replicas, horizontal scaling, sharding, and asynchronous processing. Always justify why each solution fits the bottleneck.
Your database handles 1,000 QPS. Traffic grows 10x to 10,000 QPS. What do you do first?
Answer: Add read replicas to distribute read queries and implement caching for static policy data to reduce database load before considering sharding or more complex solutions.
Practice
Solution
Step 1: Understand the role of cancellation policies
Cancellation and refund policies set clear rules about when and how users can stop services and get money back.Step 2: Eliminate unrelated options
Options about pricing, login times, or backups do not relate to cancellation or refunds.Final Answer:
To define rules for stopping services and returning money -> Option AQuick Check:
Cancellation policy = service stop rules [OK]
- Confusing cancellation policy with pricing strategy
- Thinking it manages user authentication
- Assuming it handles technical backups
Solution
Step 1: Identify relevant data for cancellation policy
The allowed cancellation time defines until when a user can cancel and get a refund.Step 2: Exclude unrelated fields
User password, product price, and login attempts are unrelated to cancellation timing.Final Answer:
allowed_cancellation_time: datetime -> Option DQuick Check:
Cancellation policy needs cancellation time [OK]
- Including unrelated user or product fields
- Confusing cancellation time with login data
- Using incorrect data types for time
if cancellation_time <= allowed_cancellation_time:
refund_amount = full_price
else:
refund_amount = 0
print(refund_amount)What will be printed if cancellation_time is after allowed_cancellation_time?
Solution
Step 1: Analyze the condition
If cancellation_time is after allowed_cancellation_time, the else branch runs.Step 2: Determine refund amount
In else, refund_amount is set to 0, so 0 will be printed.Final Answer:
0 -> Option CQuick Check:
Late cancellation = zero refund [OK]
- Assuming refund is full regardless of time
- Expecting an error due to condition
- Confusing variable names
def calculate_refund(cancellation_time, allowed_time, price):
if cancellation_time > allowed_time:
refund = price
else:
refund = 0
return refundSolution
Step 1: Understand refund logic
Refund should be given if cancellation_time is before or equal to allowed_time.Step 2: Check condition logic
Current code gives refund if cancellation_time is after allowed_time, which is incorrect.Final Answer:
Refund is given after allowed time instead of before -> Option BQuick Check:
Refund condition reversed = bug [OK]
- Reversing the refund condition
- Ignoring return statement
- Misusing price variable
Solution
Step 1: Consider user trust
Partial refunds based on cancellation timing show fairness and flexibility, building trust.Step 2: Consider system scalability
Partial refund rules can be implemented with clear logic and scale well without manual intervention.Step 3: Evaluate other options
Full refund anytime is costly; no refunds reduce trust; strict cutoff is less flexible.Final Answer:
Allow partial refund based on how close cancellation is to booking time -> Option AQuick Check:
Partial refund balances trust and scalability [OK]
- Choosing no refund which harms user trust
- Allowing full refund anytime which is costly
- Using strict cutoff without flexibility
