Rush Hour API Latency
An easy SQL interview practice problem on DataDriven. Write the query and run it against a real database, with instant feedback.
- Domain
- SQL
- Difficulty
- easy
- Seniority
- L3
- Asked in
- Lyft
Problem
Across every day in api_calls, what is the average latency in each hour from 15:00 through 17:59, earliest hour first? That table logs only the us-east traffic an on-call engineer is sizing afternoon capacity for.
Rush hour hits the API differently.
Tables
api_calls
Columns: call_id INTEGER, endpoint TEXT, method TEXT, status INTEGER, latency REAL, user_id INTEGER, call_time TEXT, err_msg TEXT
| call_id | endpoint | method | status | latency | user_id | call_time | err_msg |
|---|---|---|---|---|---|---|---|
| 8079 | /api/v1/orders | POST | 200 | 4.2 | 100 | 2026-02-02 01:07:00 | NULL |
| 8158 | /api/v2/products | PUT | 200 | 7.9 | 197 | 2026-03-03 02:14:00 | NULL |
| 8237 | /api/v1/search | DELETE | 201 | 11.6 | 294 | 2026-04-04 03:21:00 | NULL |
| 8316 | /api/v1/auth/login | PATCH | 204 | 15.3 | 391 | 2026-05-05 04:28:00 | NULL |
| 8395 | /api/v1/auth/logout | get | 301 | 19 | NULL | 2026-06-06 05:35:00 | NULL |
| 8474 | /api/v2/analytics | post | 400 | 22.7 | 585 | 2026-07-07 06:42:00 | Not found |
| 8553 | /api/v1/payments | GET | 401 | 26.4 | 682 | 2026-08-08 07:49:00 | Unauthorized |
| 8632 | /api/v1/users/ | POST | 403 | 30.1 | 779 | 2026-09-09 08:56:00 | Rate limit exceeded |
| 8711 | /api/v2/products/ | PUT | 404 | 33.8 | 876 | 2026-01-10 09:03:00 | Internal server error |
| 8790 | /api/v1/users | DELETE | 500 | 37.5 | NULL | 2026-02-11 10:10:00 | Bad gateway |
Expected output
| hour | avg_latency |
|---|---|
| 15 | 326.008 |
| 16 | 348.5103448275862 |
| 17 | 339.4916666666667 |
Worked solution and explanation
What this really is
This is time-of-day bucketing dressed up as capacity planning. call_time is a full timestamp spread over years of traffic, and the question wants three buckets that recur every single day: the 15, 16 and 17 o'clock hours. No contiguous stretch of timestamps is 'the afternoon peak', so any range filter on call_time catches one afternoon or one arbitrary span. The skill is pulling the hour out of each row and letting that one derived value do double duty, as the filter and as the bucket. Get it wrong and capacity gets sized off a single afternoon, or off one blended number that hides how latency climbs through the peak.
Building it
Step 1: Derive the hour from call_time
call_time is stored as text like '2026-06-15 16:01:00'. strftime('%H', call_time) pulls out '16', but as a string. CAST(... AS INTEGER) turns it into a number you can compare against 15 and 17 and that sorts numerically.
Step 2: Filter on the hour, not the timestamp
BETWEEN 15 AND 17 is inclusive on both ends, and because you compare whole hours, 17 already covers 17:00 through 17:59. < 18 says the same thing; <= 18 quietly drags in the 18 o'clock rush.
Step 3: Bucket by that same hour and average
Group on the alias hour and take AVG(latency). Two calls inside the window never recorded a latency; AVG skips those NULLs, which is right, since a missing measurement is not a zero-millisecond call.
Step 4: Read the peak in order
ORDER BY hour lays the three buckets out from 15 to 17, so the climb across the afternoon reads top to bottom.
SELECT
CAST(strftime('%H', call_time) AS INTEGER) AS hour,
AVG(latency) AS avg_latency
FROM api_calls
WHERE CAST(strftime('%H', call_time) AS INTEGER) BETWEEN 15 AND 17
GROUP BY hour
ORDER BY hour- Timestamp range
WHERE call_time BETWEEN '... 15:00:00' AND '... 17:59:59'keeps one contiguous slice of time. On a log spanning years it catches one afternoon and, without a bucket, returns one number.- Hour of day
WHERE CAST(strftime('%H', call_time) AS INTEGER) BETWEEN 15 AND 17keeps the peak hours of every day, and grouping on that hour returns the three rows the planning question needs.
SELECT AVG(latency) AS avg_latency
FROM api_calls
WHERE call_time BETWEEN '2026-06-15 15:00:00' AND '2026-06-15 17:59:59'One day, one blended figure: the shape candidates write when they read the window as a timestamp interval.
Common follow-up questions
- Planning now wants the peak split by day of week, so Monday 16:00 is separate from Saturday 16:00. What changes? (Adds a second derived key to the same bucket.)
- `call_time` is stored in UTC but the peak is defined in Eastern local time. Where does the conversion go? (Time zone shift before extracting the hour.)
- The team wants p95 latency per hour instead of the mean. How do you get it? (Percentiles versus averages on a skewed latency distribution.)