Case study

Avo

A performance audit across database, memory, and frontend — with numbers.

The engagement

A Rails engine growing fast, needing an external eye on performance

Avo is one of the most popular Ruby on Rails admin panel engines. As their user base grew, the team wanted an independent performance review — someone to systematically read every layer of the stack and find what they'd missed.

This is what a deep performance audit looks like — not a list of suggestions, but a systematic read of every layer of the stack.

Being a library rather than an application adds constraints. General database optimizations are up to the host app. The audit surface is narrower — which makes depth matter more.

At a glance

Client
Avo
Type
Performance audit
Areas
Database / Memory / Frontend
Key result
Response times nearly halved
Lighthouse
81 → 98
Database

N+1 queries hiding behind admin panel routes

Index pages are the usual suspects. The /users, /posts, and /projects routes were inspected for N+1 queries. Avo already had a solid setup for dealing with these — but a closer look revealed two patterns worth fixing.

First: Active Storage attachments. Displaying them on index pages triggered N+1 queries on the associated Attachment and Blob models. The fix used Rails' built-in eager loading scopes — but in a generic admin engine, applying them correctly takes care.

Second: show routes with unloaded associations. A few pages triggered additional queries for related records that should have been eager loaded from the start.

Posts index — before vs. after Active Storage eager loading

Load test comparison showing reduced response times after Active Storage eager loading on the posts index route

Post show — before vs. after association eager loading

Load test comparison showing improved response time consistency after eager loading associations on the post show route
Memory

Allocations that multiplied on every request

For a Rails engine, memory discipline matters — every allocation you add is inherited by every host app. Profiling the more complex resources revealed two patterns worth fixing.

file_hash memoization

A method that read the entire resource file from disk on every request, just to calculate a cache hash. Memoizing the file contents (which don’t change during a deployment) cut the cost immediately.

1.64× less memory1.44× faster

class_name caching

A metaprogramming accessor recomputed on every call. Memoizing it produced the single biggest improvement in the audit.

12.48× less memory7.91× faster
Frontend

Lighthouse 81 → 98

The frontend is where a Rails engine has the most control — decoupled from whatever caching or CDN the host app provides. Lighthouse scans (run through an ngrok tunnel for realistic latency) flagged image handling as the main opportunity.

Two changes made the difference: lazy loading off-screen images while preserving aspect ratios to avoid layout shift, and preloading the hero image so it renders on first paint.

The result: a 17-point jump in the Lighthouse performance score.

Before — Lighthouse performance score: 81

Lighthouse audit showing a performance score of 81

After — Lighthouse performance score: 98

Lighthouse audit showing a performance score of 98
Results

Nearly halved mean response times

With database and memory optimizations combined, mean response times for index routes dropped by almost half. The distribution also tightened — fewer outliers, more consistent performance under load.

Response times — green: mean, yellow: p95. Index route mean nearly halved.

Grafana chart showing response times before and after optimization, with index route mean nearly halved

Combined impact of database and memory optimizations. Note the tighter, lower response times at the right margin.

Grafana chart showing combined database and memory optimization impact, with consistently lower response times

“Julian is exemplary in going deep in the code to find the inefficiencies we overlooked. The fact that Avo is a library where the users have so much control makes this task even more challenging but we are grateful to have him review every aspect of it.”

Adrian Marin

Founder, Avo

See what an audit can find in your codebase.

A 30-minute intro call to understand your codebase and see if we're a good fit. No pitch, no pressure.