System design interviews separate mid-level engineers from senior ones at every product company in India. The same 3-year engineer who breezes through DSA rounds freezes when asked 'Design WhatsApp': not because they lack engineering ability, but because system design requires a different skill: structured thinking about trade-offs at scale. This guide covers the questions most commonly asked in 2026 at Indian product companies (Flipkart, Swiggy, Razorpay, Meesho, Dunzo) and FAANG India (Google, Amazon, Meta, Microsoft), with the frameworks that make answers excellent rather than generic.
How to Structure Every System Design Answer (The Framework)
Before the questions: interviewers evaluate process as much as output. A candidate who jumps straight to a microservices diagram without clarifying requirements fails the interview even if the diagram is technically correct. Use this structure for every question:
Step 1: Clarify requirements (3–5 minutes) Ask these before drawing anything:
- Scale: How many users? DAU? Requests per second?
- Core features to design now vs. out of scope?
- Consistency requirements: strict or eventual consistency acceptable?
- Latency target: real-time (<100ms)? Near-real-time (<1s)? Batch?
- Read/write ratio: mostly reads (cache aggressively), mostly writes (optimise for throughput), or balanced?
Step 2: Capacity estimation (2–3 minutes) Back-of-envelope numbers. Interviewers want to see you can reason about scale:
- Storage: (data size per user) × (users) = total storage
- Throughput: (requests per day) / 86,400 = average RPS; peak = 3–10× average
- Bandwidth: (RPS) × (response size) = MB/s
Step 3: High-level design (5–8 minutes) Start simple: Client → Load Balancer → App Servers → Database Then add components as constraints require: CDN for static assets, cache for read-heavy data, message queues for async processing, separate read replicas for heavy reads.
Step 4: Deep dive on 2–3 critical components (10–15 minutes) Interviewer will guide: 'Tell me more about the database schema' or 'How would you handle the notification delivery?' Go deep on the components that are interesting for this specific system.
Step 5: Scaling and failure scenarios (3–5 minutes)
- What happens when the primary database fails? → Read replica promotion, or primary-secondary failover
- What happens when a cache node fails? → Cache invalidation strategy, fallback to DB
- What happens at 10× the current load? → Horizontal scaling, database sharding, CDN offload
Design a URL Shortener (Bit.ly / TinyURL)
This is the most common entry-level system design question in India: asked at almost every company for 2–4 YOE roles.
Requirements (establish these first):
- Core: Given a long URL, return a short URL. Given a short URL, redirect to original.
- Scale: 100M URLs stored, 1B redirects/month (385 RPS average, ~3000 RPS peak)
- Short URL format: 7-character alphanumeric
Capacity estimation:
- Storage: 100M URLs × 500 bytes average = 50 GB: easily fits on one DB, but replicate for durability
- Redirect RPS: 3000 peak: needs caching since most redirects hit popular URLs
Core design: ``` Client → Load Balancer → URL Service → Postgres (URL mappings) ↓ Redis Cache (hot URLs) ```
Short URL generation: Option 1: MD5/SHA1 hash of long URL, take first 7 chars: risk of collisions, need collision check. Option 2: Base62 encoding of an auto-increment ID: simple, no collisions, but predictable sequence. Option 3: Distributed ID generator (Snowflake): scalable, no coordination needed.
Database schema: ```sql CREATE TABLE urls ( id BIGINT PRIMARY KEY, shortcode VARCHAR(10) UNIQUE NOT NULL, longurl TEXT NOT NULL, userid BIGINT, createdat TIMESTAMP DEFAULT NOW(), expiresat TIMESTAMP ); CREATE INDEX idxshortcode ON urls(shortcode); ```
Caching strategy: Cache shortcode → longurl in Redis with 24h TTL. ~80% of redirects hit cached URLs (hot URLs are few, accessed many times). Cache miss hits Postgres, populates cache.
Follow-up questions interviewers ask:
- 'How do you handle custom aliases?': Add nullable `custom_alias` column, check uniqueness before insert
- 'How do you expire URLs?': TTL column, background job to soft-delete expired rows
- 'How do you handle analytics (click count)?': Don't write to DB on every redirect (blocks on write); write to Redis counter, flush to DB every minute via cron
Design a Food Delivery System (Swiggy / Zomato)
This is the most India-specific system design question: asked regularly at Swiggy, Zomato, and adjacent companies. It demonstrates domain-specific engineering judgment.
Core flows to design:
- User browses restaurants + menus
- User places order
- Restaurant accepts order
- Delivery partner is assigned and picks up order
- User tracks order in real-time
Scale (Swiggy-like):
- 5M orders/day = 58 orders/second average, ~300/second peak (dinner rush)
- 200K active restaurants, 300K delivery partners
- Location updates from delivery partners: 300K × 1 update/5 seconds = 60K location writes/second
High-level architecture: ``` User App → API Gateway → Order Service → Order DB (Postgres) → Restaurant Service → Restaurant DB → Location Service → Redis (partner locations) → Notification Service → FCM/APNs → Real-time tracking → WebSocket servers ```
The hardest part: delivery partner assignment: Naive: query all partners within 5km radius, assign nearest available one. Problem: 60K location updates/second to a relational DB doesn't scale.
Solution: Use a geospatial index. Redis GEOADD stores (lat, long) per partner. GEORADIUS query returns all partners within N km in O(N + log M) time. Filter by availability in application layer. This pattern is production-correct for how Swiggy actually works.
Real-time order tracking: Delivery partner app pushes location every 5 seconds → Location Service → Redis (partner's current position) User app subscribes to order tracking via WebSocket. When delivery partner location updates, push to user via WebSocket. At 300K partners × 1 update/5s, WebSocket servers need to be horizontally scaled with a pub-sub layer (Redis pub-sub or Kafka) between Location Service and WebSocket servers.
Database choices:
- Orders: Postgres (ACID required for payment + order state transitions)
- Restaurant/menu data: Postgres with Redis read-through cache (menu rarely changes)
- Partner locations: Redis (write-heavy, ephemeral, geospatial)
- Order tracking events: Kafka (event stream for analytics + real-time)
- Analytics: ClickHouse or BigQuery (OLAP for dashboards)
System design is a verbal skill: you need to explain your thinking clearly under time pressure, respond to challenges without becoming defensive, and guide the conversation toward the strongest parts of your design. HireStepX's AI interviewer simulates the back-and-forth of a real system design round so you practice the conversation, not just the diagrams.
Practice freeDesign a Rate Limiter
Rate limiter is asked at Razorpay, PhonePe, PayTM, and any company with a public API. It tests knowledge of distributed systems primitives.
Common algorithms:
Token Bucket: A bucket holds N tokens. Each request consumes 1 token. Tokens are added at a fixed rate (refill rate). If bucket is empty, request is rejected. Allows bursts up to bucket capacity. ``` Bucket: capacity=100, refill_rate=10/second Burst of 100 requests: allowed (drains bucket) Request 101: rejected After 10 seconds: 100 more tokens available ```
Fixed Window Counter: Count requests per user per minute. Reject if count > limit. Problem: a burst at :59 and :01 allows 2× the limit across the minute boundary.
Sliding Window Log: Store timestamp of each request in a sorted set. On new request, remove entries older than 1 minute, count remaining. If count < limit, allow and add timestamp. Accurate but memory-intensive.
Sliding Window Counter (production choice): Hybrid of fixed window and sliding log. Uses 2 buckets: ``` currentwindowcount + (previouswindowcount × overlappercentage) ``` Where overlappercentage = how far into current window we are. Accurate enough for rate limiting, memory-efficient.
Distributed rate limiter with Redis: ```python def isratelimited(userid, limit=100, window=60): key = f'rate:{userid}:{int(time.time() // window)}' count = redis.incr(key) if count == 1: redis.expire(key, window * 2) # TTL of 2 windows return count > limit ```
Where to enforce:
- API Gateway (most common for external APIs)
- Middleware in each service (for internal rate limiting)
- A dedicated rate limit service (for complex policies)
Follow-ups:
- 'What if Redis goes down?': Fail open (allow all requests) or fail closed (block all). Fail open is usually correct for customer-facing APIs.
- 'How do you rate limit by IP for unauthenticated requests?': Redis key on hashed IP. Problem: shared IPs (offices, universities): use a higher limit or use user session ID when available.
System Design Salary and Interview Tips for India
When system design interviews start (by company tier):
- FAANG India (Google, Amazon, Microsoft, Meta): from SDE-2 / L4 (3+ years experience)
- Tier-1 Indian product (Flipkart, Swiggy, Razorpay, Meesho): from SDE-2 (2–3 years experience)
- Funded startups: varies: some ask at SDE-1 level (1–2 years), most from SDE-2
- IT services (TCS, Infosys, Accenture): not typically asked in standard interviews
Why Indian system design questions are different: Indian product companies ask systems with Indian-specific constraints:
- 'Design a UPI payment system' (Razorpay, PhonePe)
- 'Design a hyperlocal delivery system for Tier-2 cities with intermittent connectivity' (Meesho, Dunzo)
- 'Design a cricket score aggregation system for 100M concurrent viewers during India vs Pakistan' (Hotstar, Jio)
- 'Design WhatsApp-style group messaging' (any messaging company)
These require real knowledge of Indian infrastructure: Jio's 4G rollout changing mobile data patterns, UPI's 2-factor authentication requirement, GST invoice compliance for orders, NPCI's rate limits.
Resources Indian engineers actually use:
- System Design Primer (GitHub): free, comprehensive
- Designing Data-Intensive Applications (Martin Kleppmann): the definitive book
- ByteByteGo newsletter: weekly system design teardowns
- AlgoMaster.io, Hello Interview: structured prep
What separates PASS from FAIL in Indian system design rounds: Fail: Jumping to microservices immediately. Drawing components without discussing trade-offs. Getting defensive when interviewer challenges a decision. Pass: Asking clarifying questions before designing. Starting simple (monolith first, then 'if we need to scale, here's what we'd change'). Saying 'that's a good point, let me reconsider' when challenged: shows collaborative thinking, which senior engineering requires.
Frequently asked questions
Practice these questions on HireStepX