← Back to Interview Prep
Interview · Lesson 2
System Design for Rails Interviews
Most senior Rails roles have one system-design round. It looks open-ended; it isn't. Interviewers are scoring on five specific things.
The frame interviewers use
Most senior Rails system-design rounds score on the same five axes. Knowing the axes is half the battle.
- Requirements clarification. Did you ask what scale, what reads vs writes, what consistency model, what's in scope vs out.
- Data model. What tables, what relationships, what indexes, what to denormalize and why.
- Request lifecycle. What happens end-to-end when a user does the thing. Where the work happens (synchronous vs background), where the bottlenecks are.
- Trade-offs named. Every design choice has a cost. Did you name it without being asked.
- Failure modes. What happens when the cache is down, when the queue backs up, when the database is at 95% CPU, when a retry happens.
The common prompts (and what they're really testing)
- "Design a URL shortener." Testing: do you know about ID generation strategies (auto-increment vs base62-encoded UUID vs hash), read-heavy caching, and what a write-amplification looks like.
- "Design a notification system." Testing: synchronous vs async dispatch, fan-out (in-memory vs database vs queue-per-user), at-least-once vs exactly-once delivery, deduplication.
- "Design a rate limiter." Testing: token bucket vs sliding window vs fixed window, where state lives (Redis vs database), what happens when the rate-limit store is down (fail open vs fail closed).
- "Design a multi-tenant SaaS." Testing: row-level vs schema-level isolation, how authorization is scoped, how migrations work across tenants, how billing is modeled.
- "Design X for Rails specifically." Testing: do you reach for the framework's idioms (ActiveJob, ActiveRecord, Hotwire) or treat Rails like a generic web framework. The former scores higher.
The structure that works
# 5 min: clarify requirements
# "Reads: how many per second? Writes? Latency target?"
# "What's in scope? Auth? Analytics? Multi-region?"
# "How long does the system have to live? Hours? Years?"
#
# 5 min: data model
# Draw the tables. Name the indexes. Call out denormalizations.
# "users(id), short_urls(id, code, target_url, user_id),
# clicks(id, short_url_id, ip, timestamp)"
#
# 10 min: request lifecycle
# GET /a1b2: hot path. Redis cache by code → target_url.
# Cache miss: DB lookup, populate cache. Async-record the click.
# POST /shorten: generate code, INSERT, return.
#
# 5 min: trade-offs and failure modes
# "If Redis is down, fall back to DB. Slower but correct."
# "If the click-recorder queue backs up, we lose analytics but
# not redirects. That's the right priority."
# "At 100x scale, the bottleneck moves to the DB. Read replicas
# next, then maybe a NoSQL store for clicks specifically." Trade-offs that come up over and over
- Synchronous vs background job. "The user doesn't need to see this complete" goes to a job.
- Cache vs query every time. Read-heavy data with tolerable staleness goes to cache. Show you know about cache stampede and TTL jitter.
- Strong vs eventual consistency. Money strong, analytics eventual.
- Database vs Redis vs S3. Right tool for the shape. Don't store images in the database. Don't store transactions in Redis without a durable backup.
- Vertical vs horizontal scale. Bigger box vs more boxes. Bigger box wins until ~50K req/min for most Rails apps; after that, you start sharding.