Design a rate-limited REST API data collection script

Tests client-side throttling discipline versus reactive 429 handling. Strong answers proactively pace calls using rate-limit headers, cap concurrency, and apply exponential backoff with jitter. Red flag: tight-loop retries or ignoring headers.
What's really being asked
This question tests whether you design client-side systems that respect external constraints proactively rather than reacting to failures. Interviewers want to see that you understand backpressure, can prevent 429 storms, and know how to maximize throughput within a fixed quota without burning the API provider or your own reliability.
The full answer
First, proactive throttling before the server punishes you. You should mention pacing requests to stay safely under the 100 requests per minute limit using a token bucket or a fixed delay of at least 600 milliseconds between calls. Second, header awareness. Parse X-RateLimit-Remaining, X-RateLimit-Reset, or Retry-After to dynamically adjust sleep rather than guessing. Third, concurrency control. Use a bounded worker pool of three to five workers instead of unbounded threads or async tasks that create burst traffic. Fourth, resilient retries. Apply exponential backoff with full jitter when you do receive a 429, cap retries at three to five attempts, and fail gracefully if the limit persists. Fifth, efficiency optimizations. Maximize page size, cache responses where appropriate, and deduplicate requests so you do not waste quota on redundant data.
The mistakes people make
The biggest red flag is suggesting a tight retry loop on 429 without backoff. Another is proposing unlimited parallel connections and hoping the server will throttle you. Arbitrary sleeps like time.sleep(1) without reading headers show a lack of systems thinking. Finally, ignoring pagination or batching and making one call per record wastes the limited budget.
What usually comes next
The interviewer might ask how your design changes if the API returns 429s with no Retry-After header, or how you would distribute the collection across multiple nodes without violating the global limit. They may also probe how you would monitor and alert when you are approaching the threshold, or how to prioritize certain endpoints over others when quota is scarce.
A concrete example
Suppose you need to fetch ten thousand user records. You configure a session with a semaphore limiting you to four concurrent workers. Before each batch, you check X-RateLimit-Remaining. If it drops below ten, you pause until the X-RateLimit-Reset timestamp. Each worker sleeps 650 milliseconds between requests by default. On a 429, the worker sleeps for 2 to the power of attempt seconds times a random jitter factor, up to three retries. If the queue backs up beyond a hundred items, you shed load by deferring non-critical metadata fetches. This keeps you at roughly ninety requests per minute, safely under the cap, while still using concurrency to hide network latency.
Interview question
Which client-side strategy best maximizes throughput for a 100 req/min API without triggering excessive 429 errors?
- a.Limit concurrency to four workers but send requests at full speed, using only reactive exponential backoff and ignoring rate-limit headers.
- b.Bound concurrency to a small worker pool, proactively pace requests using rate-limit headers, and apply exponential backoff with jitter on 429s.Correct
- c.Keep an unbounded number of workers and rely solely on reactive exponential backoff after receiving 429 responses.
- d.Insert a fixed one-second delay after every request and retry 429s with linear backoff while ignoring rate-limit headers.
Why? this is the answer
The correct answer combines proactive throttling, header-aware dynamic pacing, bounded concurrency, and resilient retries as described in the card. Option A is tempting because it limits concurrency, but it still creates burst traffic and ignores headers, relying on the server to punish the client rather than preventing 429s proactively.
Just read this? Test yourself on what you have been reading.
Read the original → lunar.dev
- #rate-limiting
- #api-design
- #client-side-throttling
- #reliability
- #data-engineering
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.
See open roles