Clean Cache CDN Edges
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
- Airbnb
Problem
The reliability team is auditing which assets keep failing to serve from the CDN. List the unique request paths whose responses came back with an error status of 400 or above.
Cached, clean, error-free edges.
Tables
cdn_logs
Columns: log_id INTEGER, edge_loc TEXT, req_path TEXT, status INTEGER, bytes INTEGER, cache_hit INTEGER, served_at TEXT
| log_id | edge_loc | req_path | status | bytes | cache_hit | served_at |
|---|---|---|---|---|---|---|
| 537 | SFO | /js/app.min.js | 200 | 1437 | 0 | 2026-02-02 01:07:13 |
| 574 | LHR | /css/main.css | 200 | 2774 | 0 | 2026-03-03 02:14:26 |
| 611 | NRT | /images/hero.jpg | 206 | 4111 | 1 | 2026-04-04 03:21:39 |
| 648 | SIN | /api/v1/data | 301 | 5448 | 0 | 2026-05-05 04:28:52 |
| 685 | FRA | /fonts/roboto.woff2 | 304 | NULL | 0 | 2026-06-06 05:35:05 |
| 722 | SYD | /video/intro.mp4 | 403 | 8122 | NULL | 2026-07-07 06:42:18 |
| 759 | GRU | /favicon.ico | 404 | 9459 | NULL | 2026-08-08 07:49:31 |
| 796 | IAD | /assets/logo.png?v=2 | 500 | 10796 | NULL | 2026-09-09 08:56:44 |
| 833 | SFO | /js/app.min.js | 503 | 12133 | NULL | 2026-01-10 09:03:57 |
| 870 | LHR | /assets/logo.png | 200 | 13470 | 0 | 2026-02-11 10:10:10 |
Expected output
| req_path |
|---|
| /video/intro.mp4 |
| /favicon.ico |
| /assets/logo.png?v=2 |
| /js/app.min.js |
Worked solution and explanation
What this really asks
Strip the CDN framing and this is a set question asked over a log: which paths appear at least once among the failing responses? The log does not hand you paths, it hands you requests, and each path here sits on 20 of them, so the 80 rows with a status of 400 or above name just four assets. Anyone writes the filter. What separates candidates is remembering that the answer is the set, not the rows, and leaving the paths exactly as logged: trim them and the padded '/js/app.min.js ' that actually failed turns into '/js/app.min.js', which never failed once.
Walk it through
Step 1: Keep only the failing rows
WHERE status >= 400 keeps every 4xx and 5xx response and drops the 2xx and 3xx traffic. The cutoff is inclusive because 400 Bad Request is already a failure. On this log the lowest failing code happens to be 403, but a production log is full of 400s, and status > 400 would quietly lose them.
Step 2: Collapse requests into paths
Each surviving path still appears 20 times, once per failed request. SELECT DISTINCT req_path turns those 80 rows into the four paths the audit is about. Skip it and the reliability team scrolls through the same asset over and over.
Step 3: Leave the paths as logged
req_path holds '/js/app.min.js' and '/js/app.min.js ' (trailing space) as separate values. Only the padded one ever failed. The question is which logged paths failed, so no cleanup belongs in this query.
The solution
SELECT DISTINCT req_path
FROM cdn_logs
WHERE status >= 400- Filter only
SELECT req_path FROM cdn_logs WHERE status >= 400returns 80 rows: each of the four failing paths 20 times.- Filter, then collapse
- Adding
DISTINCTreturns four rows, one per failing path, and that is the audit list.
Common follow-up questions
- How would you list the failing paths by how many times they failed? (Swap `DISTINCT` for `GROUP BY req_path` with `COUNT(*)`, then sort that count descending.)
- Which failures are the CDN's fault versus the client's? (Split 4xx from 5xx with two ranges on `status`; server errors are usually the on-call priority.)
- How would you scope this to just the last hour of traffic? (Add a window predicate on `served_at`, the partition key, so the engine prunes every other day.)