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 #select to pull only the columns the view actually needed, instead of whole rows.
  • Switched to connection.select_all so 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.

Facing a similar problem? Let's talk about it.

Contact Me