If your Ruby on Rails app feels fast in development and staging, but slows down in production, you’re not imagining it.

Many database performance problems only become visible when real users (and real data volumes) hit your system at the same time.

This article breaks down why N+1 queries slip through, which “quiet” database issues tend to surface only under load, and how to detect and fix them before they become incidents.

 

Why performance looks fine until it suddenly doesn’t

In a typical Rails workflow, you validate correctness first. You run a few page loads, maybe a small smoke test suite, and things “feel” fast. But production behaves differently because:

  • The database has larger, messier, more diverse data.
  • Caches are colder (or invalidated unpredictably).
  • Concurrency is real (multiple web threads, background jobs, cron tasks).
  • Network latency, connection pool limits, and lock contention all matter.

The result is a class of performance bugs that are not obvious from a single request but become severe when multiplied across hundreds or thousands of requests per minute.

 

N+1 queries: the classic multiplier bug

An N+1 query happens when Rails loads a list of records (the “1”), then loads an associated record per item in the list (the “N”). It’s rarely a big deal with 10 records. It’s a major deal with 1,000 records under concurrent traffic.

 

Performance issues that hide until real load

N+1 queries are only one category. Here are other issues that can “pass” testing but fail under production concurrency and data growth.

 

1) Slow queries caused by missing or mismatched indexes.

In small datasets, sequential scans can look fine. In production, they become painful.

Typical symptoms:

  • Latency spikes on specific endpoints
  • High database CPU
  • A few queries dominate total time

Common causes:

  • Filtering on columns without an index
  • Multi-column filters without composite indexes
  • Sorting on large result sets without supporting indexes

 

2) Connection pool exhaustion

Under load, Rails and background workers can collectively exceed database connections.

What it looks like:

  • Requests hang for seconds, then error
  • “could not obtain a database connection” messages
  • Increased queue time even when DB CPU is moderate

 

3) Lock contention and long transactions

A single long transaction can block many short ones, and this effect scales brutally under load.

Frequent causes in Rails apps:

  • Doing network calls inside a transaction block
  • Updating many rows in one transaction during web requests
  • Background jobs that “clean up” data in large batches without careful throttling

 

4) Over-fetching: big payloads you didn’t mean to load

ActiveRecord makes it easy to load entire objects (including text/blob columns) when you only needed IDs or a subset.

Under load, this becomes:

  • Higher memory usage
  • More GC pressure
  • Slower response times due to larger row reads and serialization

Fix patterns include select, pagination, and using pluck for simple data extraction.

 

5) Hidden N+1 in serializers, decorators, and GraphQL

You might fix the controller query, but an API serializer triggers N+1 when it accesses nested associations (especially in JSON:API, GraphQL, or custom presenters).

If it’s “one endpoint is slow” and logs show a storm of similar queries, look at the serialization layer.

 

Where teams usually get stuck

Most Rails teams know about N+1. The hard part is that production performance problems are usually a mix:

  • N+1 plus missing indexes plus pool exhaustion
  • A background job that spikes locks right when traffic peaks
  • A “harmless” admin report that runs a huge query during business hours

That’s why the best approach is systematic observability and load testing, not one-off fixes.

 

How Delta Systems can help

If you’re dealing with Rails performance issues that only appear under real traffic, the fastest path is typically:

  1. Identify your highest-impact endpoints and database queries.
  2. Reproduce the problem under controlled load.
  3. Fix the query patterns (N+1, indexes, transaction scope).
  4. Validate improvements with before/after measurements.

Delta Systems helps teams make performance measurable and actionable, so you can ship features without guessing how production will behave. Book a no-obligation call with our CEO Jake Sheafer to talk out what you need!