Fix the design · Incident triage
Unbounded Load: The Search That Loads Every Row Into Memory
An admin user search that filters in application memory works on a small development database but freezes in QA once the table grows to about ten thousand rows.
In a low-level design interview, the interviewer opens searchUsers() and notes that it works on a laptop with a small database, then asks what breaks in QA when the dataset is much larger.
We need your help. Identify what breaks when the dataset grows, then fix the path from “search query” → “matching users” so each request only loads a bounded page of work instead of the whole table.
Problem
Fix the team’s existing admin user search — it already finds users by a fragment of an email address by loading rows from the database and filtering them in application code.
Incident summary
- The search feels fine on a small development database with a few hundred users.
- In QA with about ten thousand users, the heap spikes and the UI freezes.
- Logs show a query that selects all users with no limit.
- The developer preferred filtering in application code because SQL felt harder to read.
Assumptions made by the team
- The product will never have more than a few thousand users.
- Filtering in application memory is easier to read than writing the filter in SQL.
- Pagination can be added later if anyone needs it.
- Database indexes are not needed for an internal admin search.
Impacted services
- Admin search (critical) — Unbounded read every request.
- JVM heap (critical) — Loads full user table into memory.
- Database (degraded) — Full table scan on each search.
- QA realism (degraded) — Bug hidden on small dev datasets.
Triage questions
- What performance issue do you notice when the user table keeps growing?
- How would you bound the search — DB filter, pagination, or both?
- Why does this look fine with a few hundred rows, but break when the table is much larger?
- If they want an export-all button, what do you do — and when is loading the whole table still okay?