Case Study
Five seconds to 1.2, the same day
Profiling and fixing a slow pedigree page in a livestock-management Rails app — and teaching the client the technique.
A founder had one page that was too slow. I got it running locally, found the bottleneck, and fixed it the day I got access. Then I wrote up exactly what I'd done so he could apply the pattern himself.
The company
A small company making herd-management software for cattle ranchers — tracking animals, breeding, and pedigrees, in Rails. The data model centers on an animals table with self-referential parent links, which makes the family-tree rendering the natural place for things to get slow. That's exactly where it was getting slow.
What I did
The presenting problem was a slow page. I got added to the repo, took a MySQL dump of a large real account, worked through the usual environment-setup friction, and isolated the bottleneck to a specific line in one view.
The page was hauling around 40,000 records to render, instantiating a full ActiveRecord object for every one of them. Two changes did it:
- Used Arel's
#selectto pull only the columns the view actually needed, instead of whole rows. - Switched to
connection.select_allso the query came back as arrays directly — no second transform pass, and none of the cost of building and garbage-collecting 40,000 model objects.
That took the page from about five seconds to about 1.2 seconds. Then I wrote a plain-English explanation of the change, because the founder said he had "that type of code in other places" — the fix is worth more when you can reuse it. We also talked through the longer-term tree-storage question: materialized paths versus the parent_id pattern, where the Ancestry gem's LIKE queries cost you, and when combining approaches makes sense.