Top 10 Slowest Endpoints
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
- L4
- Asked in
- ESPN
Problem
List every endpoint whose peak single-request latency in api_calls is among the ten highest peaks of 2026, with that peak and its place on the list, slowest first. The on-call lead reading it wants no endpoint cut for sharing a peak with another, even when that pushes the list past ten rows.
The ten endpoints nobody wants to call.
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
| endpoint | max_latency | rnk |
|---|---|---|
| /api/v1/search | 1713.7 | 1 |
| /api/v2/products | 1696.4 | 2 |
| /api/v1/orders | 1679.1 | 3 |
| /api/v1/users | 1661.8 | 4 |
| /api/v1/auth/logout | 1644.5 | 5 |
Worked solution and explanation
Ten places, not ten rows
This is a top-N over distinct values dressed up as a latency review. Everyone gets the easy part right: filter call_time to 2026, take MAX(latency) per endpoint. What separates candidates is reading "the ten highest peaks" as ten places rather than ten rows. Write the sort-and-cut-at-ten reflex and you drop whichever endpoint tied at the boundary, which is the endpoint the review was convened to catch.
Build it in three moves
Step 1: Scope the calls to 2026
call_time is stored as text, so strftime('%Y', call_time) = '2026' keeps only this year's calls. Both sides are text, so no implicit cast decides whether a row matches.
Step 2: Reduce each endpoint to its peak
GROUP BY endpoint with MAX(latency) AS max_latency collapses each endpoint to its single worst request. The aggregate keeps one running value per endpoint, so a hundred endpoints cost a hundred slots of memory no matter how many calls there were.
Step 3: Number the places, then keep the first ten
DENSE_RANK() OVER (ORDER BY MAX(latency) DESC) can sit in the same SELECT as the GROUP BY because the window runs after aggregation. Tied peaks get one place and the next peak takes the next number. Wrap it, keep rnk <= 10, and sort by rnk with endpoint breaking ties so the output is stable.
The solution
SELECT endpoint, max_latency, rnk FROM (
SELECT endpoint, MAX(latency) AS max_latency,
DENSE_RANK() OVER (ORDER BY MAX(latency) DESC) AS rnk
FROM api_calls
WHERE strftime('%Y', call_time) = '2026'
GROUP BY endpoint
) ranked
WHERE rnk <= 10
ORDER BY rnk ASC, endpoint ASC- Cut at ten rows
- Sorting the peaks descending and keeping ten rows with
LIMIT 10stops at a row count. Two endpoints tied at the cutoff means one vanishes, and a tie higher up means the tenth distinct peak never appears. - Cut at ten places
DENSE_RANK()hands tied peaks one sharedrnk, andrnk <= 10keeps every endpoint holding one of the ten highest peaks, even if that is twelve rows.
Common follow-up questions
- How would you make this cheap on the full 150M-row table? (Filter `call_time` by range so partitions prune, or keep a daily rollup of peak latency per `endpoint`.)
- What if the review wanted p99 latency instead of the single worst request? (One outlier dominates `MAX(latency)`; a percentile per `endpoint` is the steadier signal.)
- How would you show which endpoints entered or left the list since last year? (Compare two yearly lists on `endpoint` and decide what an endpoint present in only one year means.)