Ruby on Rails Module 12
Caching and performance interview questions
Interview questions on caching and performance: short warm-ups, then what each harder question tests, the first step of a good answer and its follow-ups.
Warm-up questions
Short questions with short answers, each answered in full.
-
Fresher
What does
touch: trueon abelongs_todo for nested fragment caches? -
Fresher
Why does the test environment use the
:null_storecache? -
Fresher
What does the Server-Timing header show, and why is it on in development only?
Questions with model answers
What each question tests, the first step of a good answer and the follow-ups to expect.
-
Mid to senior
After a caching change shipped, one teacher reports seeing another teacher's dashboard figures. Walk through how you would confirm the leak, find its cause, and fix it so it cannot return.
- What it tests
- Diagnosing a cross-user cache leak from a shared key, keying entries by the user or tenant, and adding a check that fails on the shared key.
- First step
- Reproduce it with two accounts: sign in as each and compare the cached figures. Then read the cache key the change introduced. A leak like this almost always comes from a key that names the data but not the viewer, so two users share one entry; the fix is to put the user or tenant in the key.
- Follow-ups
-
- Where in the key does the user or tenant belong, and what breaks if you add it to only some of the app's cache calls?
- The leak is in a fragment cache, not a low-level fetch. How does the record in the cache block decide the key, and how can it still leak across users?
- How would you write a test that fails on the shared-key version and passes once the key names the user?
- The leaking value is cached inside a background job. Why is the current user unreliable there, and what do you pass instead?
From the lesson Caching with Rails and Solid Cache
Model answer, Pro. Model answers open with any pass; prices are in the notice on this page.Opening the model answers with your pass…
Model answers open with any MySmartCoPilot pass.
- Pro pass · 1 week₹79$2.99
- 30 days₹179$5.99
- 1 year₹1,699$45
One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.
Passes can’t be bought right now, so the model answers can’t be opened at the moment. If you have a pass, enter your licence key.
It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).
In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
At 9:00 a cached class timetable expires and about 2,000 students open it in the same minute. The database spikes and some requests time out. Explain the cause and how you would prevent it.
- What it tests
- Naming a cache stampede, using race_condition_ttl so one request rebuilds while others read the stale value, and spreading a shared expiry time.
- First step
- Name the pattern: a cache stampede. One popular entry expired, every request missed at once, and each ran the expensive rebuild, so the database took the full uncached load in one burst. The first move is to stop the whole crowd from rebuilding: let one request recompute while the rest read the just-expired value.
- Follow-ups
-
- How does race_condition_ttl bound the number of rebuilds, and what do the other readers get while one rebuilds?
- Why does lowering expires_in make the problem worse rather than better?
- The timetable is the same for every student. How could a single shared expiry time cause a synchronised miss, and how would you spread it?
- If the rebuild itself is slow, what else could you precompute so the 9:00 burst never reaches the database?
From the lesson Caching with Rails and Solid Cache
Model answer, Pro.In the answer:
- Model answer
- Common mistakes
- Rubric
- Variants
- about 3 minutes
-
Mid to senior
The Kaksha timetable page's p95 doubled from 180 ms to 360 ms the morning after a deploy. The pull request touched the view, a serialiser and a before action. Walk through how you would find which change doubled the time, from the Rails log to a sampling profiler.
- What it tests
- Reading the Rails log and Server-Timing to narrow where the time went, then profiling the slow request to name the method, before changing any code.
- First step
- Compare like with like before reading any code: the Completed lines of the same request on the old and the new build. Total, Views and ActiveRecord with its query count show which part grew; in development, the Server-Timing header then splits that part by notification name.
- Follow-ups
-
- Which Server-Timing entries would grow for a slow serialiser, and which for a slow before action?
- When do you reach for Vernier rather than the Rails log, and which part of its report do you read first?
- Why can a sampling profiler run against production traffic, and when would you still profile in development?
- Which test stops the same regression from reaching production again?
From the lesson Profiling and tuning a Rails app
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Mid to senior
A new four-core server runs the Kaksha API. Measured on the current workload, requests spend about forty percent of their wall time waiting on PostgreSQL. Choose Puma threads, Puma workers and the Active Record pool size for one server, and defend the numbers.
- What it tests
- Sizing threads for I/O wait, workers for cores and the pool for the threads of one worker, with the failure of each wrong choice named.
- First step
- Separate what each setting buys before picking numbers. Workers are the only way to use more than one core; threads only fill the time a request spends waiting, here 40 %. Write down the cores, the waiting share and the memory each worker needs, then choose workers, threads and the pool in that order.
- Follow-ups
-
- What happens if the same server runs one worker with twenty threads?
- Why should the pool size read RAILS_MAX_THREADS rather than a fixed number?
- When do you stop adding threads and add workers instead?
- Which exception does a thread raise when the pool is one connection short, and what does the user see?
From the lesson Profiling and tuning a Rails app
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
-
Senior to staff
After YJIT went on in production, each Kaksha API worker's memory rose from 480 MB to about 530 MB and p95 fell from 110 ms to 82 ms. The 8 GB server runs four workers, and a memory alert fired. Would you keep YJIT on or turn it off, and what would you measure next?
- What it tests
- Weighing a measured speed-up against a measured memory cost, naming the setting that caps YJIT's memory, and planning the measurement that decides.
- First step
- Put the two measurements side by side as shares: the memory YJIT added across all workers against the server's RAM, and the p95 it removed against the old p95. Then ask what the alert protects: memory running out, or a threshold set before YJIT was on.
- Follow-ups
-
- What does --yjit-mem-size limit, and how would you choose its value here?
- When would you call RubyVM::YJIT.enable after boot instead of enabling YJIT at start-up?
- What kind of application gains little from YJIT, even on a large server?
- Where does Rails 8.1 turn YJIT on, and how do you pass YJIT options through Rails?
From the lesson Profiling and tuning a Rails app
Model answer, Pro.In the answer:
- Model answer
- Follow-up answers
- Common mistakes
- Rubric
- Variants
- about 4 minutes
All Ruby on Rails interview questions · The Ruby on Rails track