window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster already exists') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() How to Increase Rails Performance - The Codest
The Codest
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Industries
    • Fintech & Banking
    • E-commerce
    • Adtech
    • Healthtech
    • Manufacturing
    • Logistics
    • Automotive
    • IOT
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
Back arrow GO BACK
2022-02-17
Software Development

How to Increase Rails Performance

Konstanty Koszewski

Despite its numerous advantages, Ruby on Rails is still considered to be a relatively slow web framework. We all know that Twitter has left Rails in favor of Scala. However, with a few cleaver improvements you can run your app significantly faster!

Ruby First

Ruby is a heavily object-oriented language. In fact, (almost) everything in Ruby is an object. Creating unnecessary objects might cost your program a lot of additional memory usage, so you need to avoid it.

To measure the difference, we will use a memory_profiler gem and a built-in Benchmark module to measure time performance. 

Use bang! methods on strings

require "memory_profiler"

report = MemoryProfiler.report do
data = "X" * 1024 * 1024 * 100
data = data.downcase
end

report.pretty_print

In the listing below, we created a 100MB string and downcased each character contained therein. Our benchmark gives us the following report:

Total allocated: 210765044 bytes (6 objects)

However, if we replace line 6 with:

data.downcase!

Read files line by line

Supposedly, we need to fetch a huge data collection of 2 million records from a csv file. Typically, it would look like this:

require 'benchmark'

Benchmark.bm do |x|
x.report do
File.readlines("2mrecords.csv").map! {|line| line.split(",")}
end
end
user     system      total        real

12.797000   2.437000  15.234000 (106.319865)

It took us more than 106 seconds to fully download the file. Quite a lot! But we can speed up this process by replacing the map! method with a simple while loop:

require 'benchmark'

Benchmark.bm do |x|
x.report do
file = File.open("2mrecords.csv", "r")
while line = file.gets
line.split(",")
end
end
end
user     system      total        real

6.078000   0.250000   6.328000 (  6.649422)

The runtime has now dropped drastically since the map! method belongs to a specific class, like Hash#map or Array#map, where Ruby will store every line of the parsed file within the memory as long as it is executed. Ruby’s garbage collector will not release the memory before those iterators are fully executed. However, reading it line by line will GC it to relocate the memory from the previous lines when not necessary.

Avoid method iterators on larger collections

This one is an extension of the previous point with a more common example. As I mentioned, Ruby iterators are object methods and they won’t release the memory as long as they’re being performed. On a small-scale, the difference is meaningless (and methods such as map seems more readable). However, when it comes to larger data sets, it is always a good idea to consider replacing it with more basic loops. Like on the example below:

numberofelements = 10000000
randoms = Array.new(numberofelements) { rand(10) }

randoms.each do |line|
#do something
end

and after refactoring:

numberofelements = 10000000
randoms = Array.new(numberofelements) { rand(10) }

while randoms.count > 0
line = randoms.shift
#do something
end
“`

Use String::<< method

This is a quick yet particularly useful tip. If you append one string to another using the += operator behind the scenes. Ruby will create additional object. So, this: 

 a = "X"
 b = "Y"
 a += b

Actually means this:

 a = "X"
 b = "Y"
 c = a + b
 a = c

Operator would avoid that, saving you some memory:

 a = "X"
 b = "Y"
 a << b

Let’s talk Rails

The Rails framework possesses plenty of “gotchas” that would allow you to optimize your code quickly and without too much additional effort. 

Eager Loading AKA n+1 query problem

Let’s assume that we have two associated models, Post and Author:

class Author < ApplicationRecord
has_many :posts
end

class Post < ApplicationRecord
belongs_to :author
end

We want to fetch all the posts in our controller and render them in a view with their authors:

controller

def index
@posts = Post.all.limit(20)
end

view

<% @posts.each do |post| %>
<%= post %>
<%= post.author.name %>
<% end %>

In the controller, ActiveRecord will create only one query to find our posts. But later on, it will also trigger another 20 queries to find each author accordingly – taking up an additional time! Luckily enough, Rails comes with a quick solution to combine those queries into a single one. By using the includes method, we can rewrite our controller this way:

 def index
     @posts = Post.all.includes(:author).limit(20)
 end

For now, only the necessary data will be fetched into one query. 

You can also use other gems, such as bullet to customize the whole process.

Call only what you need

Another useful technique to increase ActiveRecord speed is calling only those attributes which are necessary for your current purposes. This is especially useful when your app starts to grow and the number of columns per table increase as well.

Let’s take our previous code as an example and assume that we only need to select names from authors. So, we can rewrite our controller:

 def index
     @posts = Post.all.includes(:author).select("name").limit(20)
 end

Now we instruct our controller to skip all attributes except the one we need.

Render Partials Properly

Let’s say we want to create a separate partial for our posts from previous examples:

 <%
  @posts.each do |post| %>
  <%= render 'post', post: post %>
 <% end %>

At first glance, this code looks correct. However, with a larger number of posts to render, the whole process will be significantly slower. This is because Rails invokes our partial with a new iteration once again. We can fix it by using the collections feature:

 <%= render @posts %>

Now, Rails will automatically figure out which template should be used and initialize it only once.

Use background processing

Every process which is more time-consuming and not crucial for your current flow might be considered a good candidate for background processing, e.g. sending emails, gathering statistics or providing periodical reports. 

Sidekiq is the most commonly used gem for background processing. It uses Redis to store tasks. It also allows you to control the flow of your background process, split them into separate queues and manage memory usage per each one of them.

Write less code, use more gems

Rails came up with an enormous number of gems which not only make your life easier and accelerate the development process, but also increase the performance speed of your application. Gems such as Devise or Pundit are usually well-tested regarding their speed and work faster and more securely than code custom-written for the same purpose.

In case of any questions to improving Rails performance, reach The Codest engineers out to consult your doubts.

Ruby Developer Offer

Read more:

Pros and cons of Ruby software development

Rails and Other Means of Transport

Rails Development with TMUX, Vim, Fzf + Ripgrep

Related articles

Software Development

Build Future-Proof Web Apps: Insights from The Codest’s Expert Team

Discover how The Codest excels in creating scalable, interactive web applications with cutting-edge technologies, delivering seamless user experiences across all platforms. Learn how our expertise drives digital transformation and business...

THECODEST
Software Development

Top 10 Latvia-Based Software Development Companies

Learn about Latvia's top software development companies and their innovative solutions in our latest article. Discover how these tech leaders can help elevate your business.

thecodest
Enterprise & Scaleups Solutions

Java Software Development Essentials: A Guide to Outsourcing Successfully

Explore this essential guide on successfully outsourcing Java software development to enhance efficiency, access expertise, and drive project success with The Codest.

thecodest
Software Development

The Ultimate Guide to Outsourcing in Poland

The surge in outsourcing in Poland is driven by economic, educational, and technological advancements, fostering IT growth and a business-friendly climate.

TheCodest
Enterprise & Scaleups Solutions

The Complete Guide to IT Audit Tools and Techniques

IT audits ensure secure, efficient, and compliant systems. Learn more about their importance by reading the full article.

The Codest
Jakub Jakubowicz CTO & Co-Founder

Subscribe to our knowledge base and stay up to date on the expertise from the IT sector.

    About us

    The Codest – International software development company with tech hubs in Poland.

    United Kingdom - Headquarters

    • Office 303B, 182-184 High Street North E6 2JA
      London, England

    Poland - Local Tech Hubs

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Warsaw, Poland

      The Codest

    • Home
    • About us
    • Services
    • Case Studies
    • Know How
    • Careers
    • Dictionary

      Services

    • It Advisory
    • Software Development
    • Backend Development
    • Frontend Development
    • Staff Augmentation
    • Backend Developers
    • Cloud Engineers
    • Data Engineers
    • Other
    • QA Engineers

      Resources

    • Facts and Myths about Cooperating with External Software Development Partner
    • From the USA to Europe: Why do American startups decide to relocate to Europe
    • Tech Offshore Development Hubs Comparison: Tech Offshore Europe (Poland), ASEAN (Philippines), Eurasia (Turkey)
    • What are the top CTOs and CIOs Challenges?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Copyright © 2025 by The Codest. All rights reserved.

    en_USEnglish
    de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek en_USEnglish