Your SQL Is Fast But the API Is Slow
Your database queries are fast. Your caching works. Your background jobs are fine.
Yet, your API is still slow. Your CPU usage is high.
The problem is not your database. The problem is the Ruby layer.
The bottleneck often happens after the data leaves the database and enters your application. This happens through three main issues:
- Bloated serialization
- Excessive object allocation
- Repeated computation
Here is how to fix them.
- Stop Bloated Serialization
Many developers turn entire models into JSON.
render json: @shipments
If a shipment has 40 columns but your frontend only needs 5, you waste CPU cycles. You also risk leaking private data like API keys or costs.
The fix: return only the fields you need.
render json: @shipments.as_json(only: [:id, :tracking_no, :status])
For even better speed, use pluck to fetch data as arrays. This avoids building heavy ActiveRecord objects entirely.
- Reduce Object Allocation
Every object Ruby creates costs memory. Creating thousands of objects during a single request forces the Garbage Collector (GC) to work harder. This slows down your entire system.
Avoid building new hashes or strings inside loops.
Bad: @shipments.map do |s| { label: "#{s.tracking_no} - #{s.status.upcase}" } end
Good: Move static data outside the loop. Do more work in the database instead of in Ruby.
- Avoid Repeated Computation
If you call the same method multiple times in one request, you waste time.
Example: def total_weight shipments.sum(&:weight) end
If your view, helper, and serializer all call this, you calculate the sum three times.
The fix: use memoization.
def total_weight @total_weight ||= shipments.sum(&:weight) end
This ensures the math happens only once per request.
Summary Table:
- Bloated serialization: Return only needed fields or use pluck.
- High allocation: Build fewer objects in loops.
- Repeated computation: Use memoization to reuse results.
Database optimization means asking for less data. Application optimization means doing less busywork once you have the data.
Source: https://dev.to/danewu/your-sql-is-fast-but-the-api-is-slow-its-the-ruby-layer-2fno
