One query per house
Two commits, a week apart, with the same shape: the Builds screen was fetching one row at a time, and listing a company’s houses ran a query per house.
Neither was slow enough to notice while a test company owned four houses. Both were obvious the moment one owned forty.
This is the oldest performance bug there is, and the reason it keeps happening is that the code reads better in its broken form. Asking for each house’s details where you need them is clearer than assembling a batch up front and threading it through. The loop looks like the domain. The fix looks like plumbing.
What made it visible here was not profiling. It was the simulation tool — a hundred days of a new company, run end to end — which exists to answer design questions like whether crowding a region hurts, and incidentally puts enough data through the app that an N+1 stops being theoretical.
That has turned out to be the more valuable half of building it. The simulator was written to tune the game, and it has caught at least as many engineering problems as design ones, because it is the only thing that routinely creates a company with a realistic amount of history behind it.
A test fixture has four of everything because four is enough to prove the logic. A player has four hundred, and every query you wrote per-item is waiting for them.