RUBY ON RAILS · 11 MIN READ ·

Rack Mini Profiler: Prestatieprofiling voor Rails in Development en Productie

Rack Mini Profiler voor Rails: profileer SQL-queries, partials, geheugen en GC in development en productie. Vind N+1s, trage views en verborgen knelpunten snel.

Rack Mini Profiler: Prestatieprofiling voor Rails in Development en Productie

De pagina laadde in drie seconden. Niet consistent — soms twee, soms vier. Geen errors, niets opvallends in de logs. De applicatie draaide al achttien maanden in productie en dit admin-dashboard was stilletjes onbruikbaar geworden terwijl het team druk was met het uitbrengen van nieuwe features.

Ik vroeg of ze rack-mini-profiler hadden geïnstalleerd. Dat hadden ze niet. Ik voegde het toe, opende de pagina, en binnen dertig seconden hadden we het antwoord: 94 SQL-queries bij één enkele page load. Een klassieke N+1 op een has_many through:-associatie, begraven in een partial die in de loop der tijd zes verschillende modellen was gaan aanraken. De fix was een eager load van twee regels. De fix kostte een middag. De profiler kostte dertig seconden.

Na negentien jaar Rails is rack-mini-profiler nog steeds het eerste gereedschap dat ik erbij pak als iemand me vertelt dat een pagina traag is.

Wat Rack Mini Profiler Je Laat Zien

Rack-mini-profiler is een Rack-middleware die een kleine profiling-toolbar in je HTML-responses injecteert. De toolbar toont de totale requesttijd, de tijd die Rails besteedt aan rendering, en de tijd in de database — uitgesplitst naar aantal SQL-queries en duur.

Dat klinkt eenvoudig. De kracht zit in de details. De toolbar is persistent, per pagina, en verschijnt in de context van de pagina die je aan het debuggen bent — niet in een apart tool waar je het scenario opnieuw moet reproduceren. Je ziet de cijfers terwijl je de applicatie normaal gebruikt.

Klik op de toolbar en je krijgt een query-voor-query-breakdown: elke SQL-statement, de duur ervan, de aanroepende stacktrace, en hoe vaak het werd uitgevoerd. Die stacktrace is hoe je de bronregel vindt die je N+1 veroorzaakt — je hoeft niet te zoeken naar eager load-kandidaten of query-plannen te lezen. De profiler vertelt je precies welke regel Ruby elke query uitvoert.

Installatie en Configuratie

Voeg toe aan je Gemfile:

gem "rack-mini-profiler"
gem "memory_profiler"  # schakelt geheugen-profiling in
gem "stackprof"        # schakelt flamegraph-ondersteuning in

Rack-mini-profiler activeert zichzelf automatisch in development en voegt de toolbar toe aan elke HTML-response. In productie en staging is het standaard stil — de toolbar verschijnt alleen bij geautoriseerde requests.

Basisconfiguratie in een initializer:

# config/initializers/rack_profiler.rb
if Rails.env.development?
  Rack::MiniProfiler.config.start_hidden = false
  Rack::MiniProfiler.config.position     = "bottom-right"
  Rack::MiniProfiler.config.skip_paths   = ["/assets", "/cable"]
end

skip_paths voorkomt dat de profiler draait op asset-requests en Action Cable-pings. Die vervuilen de toolbar-geschiedenis zonder nuttig te zijn voor applicatieprofiling.

Voor Rails-apps met Propshaft of Sprockets integreert de gem automatisch. Geen handmatige middleware-insertie nodig — hij detecteert de Rack-stack en voegt zichzelf op de juiste positie in.

N+1-queries Vinden met Rack Mini Profiler

Dit is het dagelijkse gebruik. Het SQL-tabblad in rack-mini-profiler toont elke query gegroepeerd per aanroeper. Een N+1 verschijnt als een herhalende query met een aantal groter dan één — meestal met een kleine duur per query die optelt tot een significante totaaltijd.

De werkwijze:

  1. Laad de pagina
  2. Klik op de snelheidsbadge in de hoek
  3. Ga naar het SQL-tabblad
  4. Zoek naar queries met een aantal van N, waarbij N evenredig is aan het aantal records op de pagina

Als je 20 orders hebt en je ziet SELECT * FROM line_items WHERE order_id = ? 20 keer staan, heb je je N+1 gevonden. De stacktrace bij elke query-instantie wijst naar de exacte partial of methode die hem aanroept.

De fix:

# Voorheen: N+1 — één query per order
@orders = Order.where(user: current_user).order(created_at: :desc)

# Daarna: eager load line_items in één query
@orders = Order.where(user: current_user)
               .includes(:line_items)
               .order(created_at: :desc)

De N+1-querygids behandelt Bullet-integratie en strict loading naast rack-mini-profiler. Gebruik de profiler om N+1s interactief te vinden; gebruik Bullet om regressies automatisch te onderscheppen in CI. Het zijn complementaire tools, geen alternatieven.

Geheugen Profileren

Met memory_profiler geïnstalleerd, voeg je ?pp=profile-memory toe aan een URL voor een volledig allocatierapport van die request:

http://localhost:3000/admin/orders?pp=profile-memory

De response is een tekstrapport met gealloceerde objecten per gem, per bestand en per regelnummer. Het is uitgebreid, maar de samenvatting Total allocated: bovenaan is je startpunt. Een typische Rails-request alloceert ergens tussen de 50.000 en 300.000 objecten. Requests die meerdere miljoenen objecten alloceren zijn de moeite waard om te onderzoeken.

Het rapport groepeert allocaties per gem, zodat je kunt zien of de druk komt van je eigen applicatiecode, van ActiveRecord, van je templating-laag of van een third-party gem. Een rapport dat 80% van de allocaties toeschrijft aan een serializer-gem is actionable: de gem maakt te veel tussenliggende objecten aan, en de gem moet worden vervangen of de serialisatie moet worden gecachet.

Voor dieper onderzoek naar productie-geheugengroei behandelt de Ruby GC-tuninggids GC.stat-analyse, heap-size-configuratie en ObjectSpace — de juiste tools zodra je hebt bepaald waar de druk vandaan komt.

Flamegraphs

Voeg ?pp=flamegraph toe voor een Speedscope-compatibele flamegraph van de volledige request-callstack:

http://localhost:3000/admin/orders?pp=flamegraph

De flamegraph rendert in de browser via Speedscope. Elk horizontaal blok is een stackframe; de breedte staat voor de tijd. Hoge stacks die je niet verwachtte, of brede blokken op onverwachte plaatsen, vertellen je wat het proces werkelijk aan het doen is — niet wat je aanneemt dat het doet.

De flamegraph is het juiste gereedschap wanneer het SQL-queryaantal er redelijk uitziet maar de pagina toch traag is. Als de databasetijd onder de 50ms blijft maar de totale requesttijd 800ms is, zit de resterende 750ms in Ruby-executie: serialisatie, view-rendering, objectallocatie, reguliere expressies in template-helpers, of een gem die iets duur doet wat je nooit hebt geïnspecteerd. De flamegraph brengt het aan de oppervlakte zonder giswerk.

stackprof moet geïnstalleerd zijn voor ?pp=flamegraph. De request moet in een paar minuten afgerond zijn om de output correct te genereren.

Rack Mini Profiler Inschakelen in Staging en Productie

De toolbar is een beveiligingsrisico als hij zichtbaar is voor niet-geauthenticeerde gebruikers — hij onthult querystructuur, partial-namen en timingdata die een aanvaller kan gebruiken om de internals van je applicatie te begrijpen. Het juiste patroon koppelt het aan je bestaande authenticatie:

# config/initializers/rack_profiler.rb
Rack::MiniProfiler.config.authorization_mode = :allowlist
# app/controllers/admin/base_controller.rb
class Admin::BaseController < ApplicationController
  before_action :authorize_profiler

  private

  def authorize_profiler
    Rack::MiniProfiler.authorize_request if current_user&.admin?
  end
end

Met deze configuratie activeert het bezoeken van een admin-URL als beheerder de profiler-toolbar voor je sessie. Niet-admin-requests zien niets. Dit is veilig om permanent in productie te laten staan — verwaarloosbare overhead voor geprofileerde sessies, nul overhead voor al het andere.

Voor eenmalige onderzoeken op specifieke productiepagina’s geven de parameters ?pp=env en ?pp=profile-gc plain-text responses in plaats van een toolbar te injecteren. Je kunt ze ophalen met curl via een geauthenticeerde sessie:

curl -b "session_cookie=jouw_sessiewaarde" \
  "https://jouwapp.com/admin/trage-pagina?pp=env"

Combineren met EXPLAIN ANALYZE

Rack-mini-profiler toont welke queries traag zijn en hoe vaak ze draaien. Het verklaart niet waarom een individuele query traag is op databaseniveau — daarvoor heb je EXPLAIN ANALYZE nodig.

De werkwijze:

  1. Identificeer trage queries in het SQL-tabblad van de profiler (alles boven 50ms is de moeite waard)
  2. Kopieer de query-tekst
  3. Voer hem uit met EXPLAIN ANALYZE in psql of je databaseclient
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT * FROM orders
WHERE user_id = 42 AND status = 'pending'
ORDER BY created_at DESC;

De Postgres EXPLAIN ANALYZE-gids behandelt het lezen van queryplannen, het herkennen van sequential scans en het kiezen van het juiste indextype. De combinatie — rack-mini-profiler om te bepalen welke query onderzocht moet worden, EXPLAIN ANALYZE om te begrijpen waarom hij traag is — dekt vrijwel elk productie-databaseprestatieprobleem dat ik tegenkom.

Achtergrondtaken Profileren

Rack-middleware onderschept alleen HTTP-requests. Het profileert geen Solid Queue- of Sidekiq-workers. Gebruik voor jobs direct stackprof:

# app/jobs/process_orders_job.rb
class ProcessOrdersJob < ApplicationJob
  def perform
    result = StackProf.run(mode: :wall, raw: true) do
      Order.pending.find_each do |order|
        ProcessOrder.call(order)
      end
    end

    report = StackProf::Report.new(result)
    report.print_text(false, 50) # top 50 frames op self-tijd
  end
end

Voer dit handmatig uit vanuit de Rails-console in development of staging. De output is een plain-text tabel van de zwaarste stackframes — het job-equivalent van een flamegraph, zonder de browserrendering.

Voor doorlopende monitoring van jobprestaties in productie is OpenTelemetry-instrumentatie de betere investering: spans op elke job-executie met databasetijd en wachttijd in de queue automatisch bijgehouden over alle workers heen.

FAQ

Werkt rack-mini-profiler samen met Turbo en Hotwire?

Ja, met een kleine nuance. Turbo Drive onderschept volledige paginanavigaties, waardoor de toolbar tussen pagina’s blijft staan zonder volledige herlaadbeurt — je kunt daardoor een meerstaps-flow profileren zonder eerdere resultaten te verliezen. Turbo Frame-requests zijn afzonderlijke HTTP-requests en verschijnen als individuele vermeldingen in de dropdown-geschiedenis van de toolbar. Als de partial van een Turbo Frame traag is, staat het profiel als de meest recente vermelding in de geschiedenis nadat je het frame hebt getriggerd.

Is het veilig om rack-mini-profiler in productie te draaien?

Met autorisatie ingeschakeld: ja. Zonder autorisatie: nee. De SQL-output onthult je schema, querypatronen en tabelnamen in voldoende detail om een gerichte aanval te informeren. Gebruik de allowlist-autorisatiemodus en koppel toegang aan admin-authenticatie zoals hierboven getoond. De overhead voor niet-geprofileerde requests is één middleware-check — onmeetbaar in productieverKeer.

Hoe profileer ik een trage actie die POST-data vereist?

De parameters ?pp=flamegraph en ?pp=profile-memory werken ook op POST-requests. Voeg ze als queryparameters toe aan de action-URL van het formulier, of aan de fetch-URL als de actie via JavaScript wordt aangeroepen. De profiler koppelt aan de server-side verwerking ongeacht de HTTP-methode.

Hoe verhoudt rack-mini-profiler zich tot APM-diensten zoals Skylight of Scout?

Ze dienen verschillende doelen. Rack-mini-profiler is een per-request debug-tool — interactief, direct beschikbaar, met volledige SQL- en stackdetails voor één request. Skylight en Scout APM zijn productie-monitoringdiensten die prestatiedata over duizenden requests in de loop van de tijd aggregeren en trage endpoints, regressies en trends op fleetschaal zichtbaar maken. Gebruik rack-mini-profiler om specifieke trage pagina’s te diagnosticeren in development; gebruik een APM-dienst om te weten welke pagina’s in de eerste plaats gediagnosticeerd moeten worden. Het zijn geen alternatieven — de best onderhouden Rails-applicaties die ik heb gezien gebruiken beide.

Ben je op zoek naar een prestatieprobleem dat zich niet duidelijk laat zien in je logs? TTB Software profileert Rails-applicaties in development en productie al negentien jaar. We weten welke cijfers we als eerste bekijken en hoe we van een trage pagina naar een gecommitte fix komen in één sessie.

#rack-mini-profiler-rails #rails-performance-profiling #rails-sql-query-profiling #rails-memory-profiler #rails-flamegraph-stackprof #rails-development-performance-tools

Related Articles

Laatste sectie. Bel dan alsjeblieft.

Het is een telefoongesprek. Erger dan dat kan het niet worden.

Geen discovery-deck. Geen 45-minuten "kwalificatiegesprek." 30 minuten, jouw probleem, mijn mening. Als we een fit zijn weet je dat in minuut 12.

Directe lijn — Roger neemt zelf op
+31 6 5123 6132
Ma–vr, 09:00–18:00 CET · Nu beschikbaar

OF
info@ttb.software