As Rails developers, we’ve all been there – your application starts slowing down as data grows, pages take longer to load, and memory usage spikes. Before you blame Rails itself or consider rewriting your entire application, you should profile your app to understand what’s really happening behind the scenes.
Most of the time, the issue lies in how the app is written: unnecessary SQL queries, excessive object allocations, or inefficient code patterns. Before you think about rewriting your app or switching frameworks, profile it.
That’s where Rails Debugbar shines— It helps you identify bottlenecks like slow database queries, excessive object allocations, and memory leaks – all from a convenient toolbar at the bottom of your development environment.
🤔 What is Rails Debugbar?
Rails Debugbar is a browser-integrated dev tool that adds a neat, powerful panel at the bottom of your app in development. It helps you answer questions like:
- How long is a request taking?
- How many SQL queries are being executed?
- How many Ruby objects are being allocated?
- Which parts of my code are slow?
It’s like a surgeon’s X-ray for your app—giving you visibility into internals without needing to dig into logs or guess. Get a better understanding of your application performance and behavior (SQL queries, jobs, cache, routes, logs, etc)
⚙️ Installation & Setup (Rails 8)
Prerequisites
- Ruby on Rails 5.2+ (works perfectly with Rails 8)
- A Ruby version supported by your Rails version
1. Add it to your Gemfile:
group :development do
gem 'debugbar'
end
Then run:
bundle install
2. Add the Debugbar layout helpers in your application layout:
In app/views/layouts/application.html.erb, just before the closing </head> and </body> tags:
<%= debugbar_head if defined?(Debugbar) %>
...
<%= debugbar_body if defined?(Debugbar) %>
That’s it! When you restart your server, you’ll see a sleek Debugbar docked at the bottom of the screen.
You can see ActionCable interacting with debugbar_channel in logs:
[ActionCable] Broadcasting to debugbar_channel: [{id: "xxxx-xxxx-xxxx-xxxx", meta: {controller: "ProductsController", action: "show", params: {"controller" => "products", "action" => "show", "id" => "3"}, format: :html, method: "GET", path: "/products/3", status: 200, view_runtime: 10.606000004219823, db_runtime: 0.44599999819...
23:47:17 web.1 | Debugbar::DebugbarChannel transmitting [{"id" => "xxxx-xxxx-xxxx-xxxx", "meta" => {"controller" => "ProductsController", "action" => "show", "params" => {"controller" => "products", "action" => "show", "id" => "3"}, "format" => "html", "method" => "GET", "path" => "/products/3", "status" => 200, "view_runtime" => 10.6... (via streamed from debugbar_channel)
23:47:17 web.1 | Debugbar::DebugbarChannel#receive({"ids" => ["xxxx-xxxx-xxxx-xxxx"]})
23:47:17 web.1 | [ActionCable] Broadcasting to debugbar_channel: []
23:47:17 web.1 | Debugbar::DebugbarChannel transmitting [] (via streamed from debugbar_channel)
📚 Official links for reference:
🔍 Exploring the Debugbar Tabs
Rails Debugbar includes several tabs. Let’s go through the most useful ones—with real-world examples of how to interpret and improve performance using the data.
1. Queries Tab
This tab shows all SQL queries executed during the request, including their duration in milliseconds.
Example:
You see this in the Queries tab:
SELECT * FROM users WHERE email = 'test@example.com' (15ms)
SELECT * FROM products WHERE user_id = 1 (20ms)
SELECT * FROM comments WHERE product_id IN (...) (150ms)
You realize:
- The third query is taking 10x more time.
- You’re not using eager loading, and it’s triggering N+1 queries.
How to Fix:
Update your controller:
@products = Product.includes(:comments).where(user_id: 1)
This loads the comments in a single query, reducing load time and object allocation.
2. Timeline Tab
Gives you a timeline breakdown of how long each part of the request takes—view rendering, database, middleware, etc.
Example:
You notice that rendering a partial takes 120ms, way more than expected.
<%= render 'shared/sidebar' %>
How to Fix:
Check the partial for:
- Heavy loops or database calls
- Uncached helper methods
Move the partial to use a fragment cache:
<% cache('sidebar') do %>
<%= render 'shared/sidebar' %>
<% end %>
Another Example Problem:
If you notice view rendering takes 800ms for a simple page.
Solution:
Investigate partials being rendered. You might be:
- Rendering unnecessary partials
- Using complex helpers in views
- Need to implement caching
# Before
<%= render @products %> # Renders _product.html.erb for each
# After (with caching)
<% @products.each do |product| %>
<% cache product do %>
<%= render product %>
<% end %>
<% end %>
3. Memory Tab
Tracks memory usage and object allocations per request.
Example:
You load a dashboard page and see 25,000+ objects allocated. Yikes.
Dig into the view and see:
<% User.all.each do |user| %>
...
<% end %>
That’s loading all users into memory.
How to Fix:
Use pagination or lazy loading:
@users = User.page(params[:page]).per(20)
Now the object count drops dramatically.
4. Environment & Request Info
See request parameters, environment variables, session data, and headers.
Example:
You’re debugging an API endpoint and want to confirm the incoming headers or params—Debugbar shows them neatly in this tab.
It can help identify:
- Wrong content-type headers
- CSRF issues
- Auth headers or missing cookies
💡 Debugbar Best Practices
- Use it early: Don’t wait until your app is slow—profile as you build.
- Watch out for hidden N+1 in associations, partials, or background jobs.
- Keep an eye on object counts to reduce memory pressure in production.
- Use fragment and Russian doll caching where needed, based on render timelines.
- Regularly review slow pages with Debugbar open—it’s a development-time lifesaver.
💭 Final Thoughts
Rails Debugbar offers an easy, visual way to profile and optimize your Rails 8 app. Whether you’re debugging a slow page, inspecting a query storm, or chasing down memory leaks, this tool gives you insight without friction.
So before you overhaul your architecture or blame Rails, fire up Debugbar—and fix the real issues.
to be modified.. 🚀