Existem muitas maneiras diferentes de melhorar o desempenho do seu aplicativo. Você já está fazendo um, otimizando. Especialmente se você começar a otimizar consultas (ou seja, corrigindo n + 1 consultas). Existem outras 3 áreas em que eu também procuraria. Escala verticalmente & dimensionamento horizontal ( link ) e o intérprete.
Eu gosto de escalar horizontalmente primeiro, pelo menos um pouco. Ter dois servidores de aplicativos e um balanceador de carga aumentará o número de solicitações que você pode manipular, e eu gosto dessa abordagem inicialmente porque um servidor de aplicativos é um ponto único de falha. Embora nessa situação o balanceador de carga se torne um único ponto de falha. Você poderia executar 2 LBs para redundância, mas isso é um pouco fora do escopo da sua pergunta.
Depois disso, eu escalaria verticalmente. Se você estiver executando VMs como as instâncias do AWS EC2, isso é tão simples quanto passar de um m1.small para um c1.medium. Muitos outros provedores de nuvem têm maneiras diferentes de migrar para servidores maiores. Se você estiver executando em seu próprio hardware, faça um benchmark de seu aplicativo e veja onde está o gargalo (provavelmente você deve fazer isso independentemente e fazer isso primeiro). Se o gargalo é memória, basta atualizar a memória no seu servidor e testá-lo novamente. Então você pode achar que o próximo gargalo é a CPU, então você precisa atualizá-lo.
A outra área que você deve considerar é o interpretador Ruby que você está usando. Se você estiver usando MRI (o interpretador padrão do ruby), você está deixando muito desempenho na tabela. A ressonância magnética é ótima para o desenvolvimento, mas em um site pesado de tráfego, eu não a usaria se pudesse evitá-la. A ressonância magnética usa um Global Interpreter Lock (GIL), que basicamente faz com que seu aplicativo seja único. Eu posso estar errado, mas pelo que entendi, todo processo precisa de sua própria cópia do aplicativo na memória. Portanto, se você tiver oito funcionários atendendo a solicitações, seu aplicativo ocupará 8 vezes a memória.
Existem vários outros intérpretes de Ruby por aí como JRuby e Rubinius. Eu não sei muito sobre o Rubinius, mas pelo que sei, ele acaba com o GIL e é uma ótima alternativa para a ressonância magnética do ponto de vista do desempenho.
Eu sou um grande fã do JRuby. Se você ainda não adivinhou, o JRuby é um interpretador Ruby escrito em Java e Ruby. É muito estável e aproveita a JVM, portanto, você obtém concorrência nativa. E se você optar pelo Java 7, invokedynamic pode chamar métodos inline depois que a JVM se aquecer e aumentar o desempenho das linguagens da JVM da mesma forma que faria com o código Java nativo. Com o JRuby, em vez de precisar de uma nova cópia do aplicativo na memória para cada processo, ele usa encadeamentos que compartilham uma única cópia do aplicativo na memória.
Se você decidir usar o JRuby, procure no Torquebox, que é um ótimo servidor de aplicativos criado sobre o JBoss. Os principais desenvolvedores do JRuby foram recentemente contratados pela Red Hat, que já empregou os desenvolvedores do JBoss e Torquebox, então imagino que há muita comunicação entre esses 3 grupos.
Benchmarks genéricos são praticamente inúteis, mas todos os benchmarks reais que eu vi e ouvi falar sobre aplicativos reais de produção comparando MRI a JRuby, o aumento de desempenho é um absurdo. Não sei se você obterá os mesmos ganhos do Rubinius, mas pode ser mais fácil migrar para o Rubinius do que o JRuby.