Seu SQL é rápido, mas a API é lenta

Suas consultas ao banco de dados são rápidas. Seu cache funciona. Seus jobs em segundo plano estão funcionando bem.

No entanto, sua API ainda está lenta. O uso de CPU está alto.

O problema não é o seu banco de dados. O problema é a camada Ruby.

O gargalo geralmente ocorre depois que os dados saem do banco de dados e entram na sua aplicação. Isso acontece devido a três problemas principais:

  • Serialização inflada
  • Alocação excessiva de objetos
  • Computação repetida

Aqui está como corrigi-los.

  1. Pare com a serialização inflada

Muitos desenvolvedores transformam modelos inteiros em JSON.

render json: @shipments

Se um envio tem 40 colunas, mas seu frontend precisa de apenas 5, você desperdiça ciclos de CPU. Você também corre o risco de vazar dados privados, como chaves de API ou custos.

A solução: retorne apenas os campos de que você precisa.

render json: @shipments.as_json(only: [:id, :tracking_no, :status])

Para uma velocidade ainda melhor, use pluck para buscar os dados como arrays. Isso evita completamente a construção de objetos ActiveRecord pesados.

  1. Reduza a alocação de objetos

Cada objeto que o Ruby cria custa memória. Criar milhares de objetos durante uma única requisição força o Garbage Collector (GC) a trabalhar mais. Isso retarda todo o seu sistema.

Evite construir novos hashes ou strings dentro de loops.

Ruim: @shipments.map do |s| { label: "#{s.tracking_no} - #{s.status.upcase}" } end

Bom: Mova dados estáticos para fora do loop. Faça mais trabalho no banco de dados em vez de fazer no Ruby.

  1. Evite computação repetida

Se você chamar o mesmo método várias vezes em uma única requisição, você desperdiça tempo.

Exemplo: def total_weight shipments.sum(&:weight) end

Se sua view, helper e serializer chamarem isso, você calculará a soma três vezes.

A solução: use memoization.

def total_weight @total_weight ||= shipments.sum(&:weight) end

Isso garante que o cálculo ocorra apenas uma vez por requisição.

Tabela de Resumo:

  • Serialização inflada: Retorne apenas os campos necessários ou use pluck.
  • Alta alocação: Construa menos objetos em loops.
  • Computação repetida: Use memoization para reutilizar resultados.

Otimização de banco de dados significa pedir menos dados. Otimização de aplicação significa fazer menos trabalho desnecessário uma vez que você já tem os dados.

Fonte: https://dev.to/danewu/your-sql-is-fast-but-the-api-is-slow-its-the-ruby-layer-2fno