This view shows you how your requests spend their time. How much of it is spent in the DB, how much in rendering views? By clicking on individual traces you can find out detailed information. ### Flamegraphs Rails Mini Profiler automatically records Flamegraphs for profiled requests. To enable this feature, add [Stackprof](https://github.com/tmm1/stackprof) to your Gemfile: ```ruby gem 'stackprof' ``` For convenience, Flamegraphs are recorded for every request. This may incur a significant performance penalty. To change the default behavior see [Configuration](#Configuration). Flamegraphs are rendered using [Speedscope](https://github.com/jlfwong/speedscope). See [Troubleshooting](#Troubleshooting) if Flamegraphs are not rendering correctly. ## Configuration Rails Mini Profiler provides a wide array of configuration options. You can find details below. For an example configuration check `initializers/rails_mini_profiler.rb` (or [the template file](https://github.com/hschne/rails-mini-profiler/blob/main/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.rb.erb)). | Option | Default | Description | | ------------------------ | ---------------------------- | ----------------------------------------------------------------------------------------------- | | `enabled` | `true` (dev)/ `false` (prod) | Whether or not RMP is enabled | | `badge_enabled` | `true` | Should the hedgehog 🦔 badge be injected into pages? | | `badge_position` | `'top-left'` | Where to display the badge. Options are `'top-left', 'top-right', 'bottom-left, 'bottom-right'` | | `flamegraph_enabled` | `true` | Should flamegraphs be recorded automatically? | | `flamegraph_sample_rate` | `0.5` | The flamegraph sample rate. How many snapshots per millisecond are created. | | `skip_paths` | `[]` | An array of request paths that should not be profiled. Regex allowed. | | `storage` | `Storage` | Storage configuration. See [Storage](#Storage) | | `user_provider` | `Rack::Request.new(env).ip` | How to identify users. See [Users](#Users) | ### Request Configuration You may override the configuration by sending request parameters. The following parameters are available: | Option | Description | | ---------------- | ------------------------------------------------------------------------------------------- | | `rmp_flamegraph` | Overrides `flamegraph_enabled` If set to `true` will redirect to the flamegraph immediatly. | ### Storage Rails Mini Profiler stores profiling information in your database per default. You can configure various details of how traces and requests are stored. | Configuration | Default | Description | | ------------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------- | | `database` | `nil` | Set a custom database to be used for storing profiler information. Uses `connect_to` for profiler records | | `profiled_requests_table` | `rmp_profiled_requests` | The table to be used to store profiled requests. | | `flamegraphs_table` | `rmp_flamegraphs` | The table to be used to store flamegraphs. | | `traces_table` | `rmp_traces` | The table to be used to store traces. | Rails Mini Profiler does not offer an automatic way to clean up old profiling information. It is recommended you add a sweeper job to clean up old profiled requests periodically (e.g. using [clockwork](https://github.com/adamwiggins/clockwork). For example, with ActiveJob: ```ruby # Clockwork every(1.month, 'purge rails mini profiler' do ProfiledRequestCleanupJob.perform_later end # ActiveJob class ProfiledRequestCleanupJob < ApplicationJob queue_as :default def perform RailsMiniProfiler::ProfiledRequest.where('created_at < ?', 1.month.ago).destroy_all end end ``` ### Users Profiling information is segregated by user ID. That means users cannot see each other's profiled requests. Per default, individual users are identified by their IP address. You may change this by setting a custom user provider: ```ruby config.user_provider = proc { |env| Rack::Request.new(env).ip } ``` You may also explicitly set the user from the application itself: ```ruby class ApplicationController < ActionController::Base before_action do RailsMiniProfiler::User.authorize(current_user.id) end end ``` Note that you **must** set the current user when running Rails Mini Profiler in production. No profiles will be saved otherwise. ### Profiling in Production Rails Mini Profiler is not intended for performance reporting. There are other tools for that ( [Skylight](https://www.skylight.io/), [New Relic](https://newrelic.com/), [DataDog](https://www.datadoghq.com/)...). However, you can still use it in production to profile specific requests. Since profiling impacts performance, it is recommended that you limit which requests are being profiled: ```ruby RailsMiniProfiler.configure do |config| config.enabled = proc { |env| env.headers['RMP_ENABLED'].present? } end ``` Only requests by explicitly set users will be stored. To configure how individual users are identified see [Users](#Users) ## Why Rails Mini Profiler? Improving the performance of any application is a 3-step process. You have to answer these questions: 1. What is slow? 2. Why is it slow? 3. Did my solution fix the slowness? I'm a huge fan of [rack-mini-profiler](https://github.com/MiniProfiler/rack-mini-profiler), and AMP tools such as [Skylight](https://www.skylight.io/) or [Scout APM](https://scoutapm.com), and each of these tools has its place. APM tools are excellent for profiling your app in production - aka. they show you what is slow - and offer _some_ hints as to what causes the slowdown. `rack-mini-profiler` can do some sampling in production, but excels at providing detailed insight into _why_ something is slow, using Flamegraphs and detailed query information. Rails Mini Profiler improves upon `rack-mini-profiler` in the latter regard. It is a developer tool, rather than a monitoring tool, and sets a big focus on developer experience. Simply put, it aims to be the best tool available to help you figure out _why_ specific requests are slow. As such, compared to `rack-mini-profiler`, it does not support non-Rails apps (e.g. Sinatra) or production sampling, but provides a much better user experience and better supports API-only applications. ## Troubleshooting ### Upgrading Rails Mini Profiler is in early development. As such, breaking changes may still be introduced on a regular basis. While Rails Mini Profiler is in pre-release we do not offer upgrade migrations. If an upgrade to Rails Mini Profiler breaks your application, we recommend that you drop the offending tables and re-run migrations for the latest version: ``` rails rails_mini_profiler:install:migrations rails db:migrate ``` ### Support for API-Only Apps Rails Mini Profiler supports API-only apps, but you have to make some small adjustments to use it. At the top of `application.rb` add [Sprockets](https://github.com/rails/sprockets-rails): ``` require "sprockets/railtie" ``` Then, modify `application.rb`: ``` module ApiOnly class Application < Rails::Application config.api_only = true # Either set this to false config.middleware.use ActionDispatch::Flash # Or add this end end ``` **Note: Sprockets and flash are currently required for some of Rails Mini Profiler's UI features. These modifications may no longer be needed in the future. ### No Flamegraphs are being recored? Make sure you have added [StackProf](https://github.com/tmm1/stackprof) to your Gemfile. ```ruby gem 'stackprof' ``` ### Flamegraphs are not rendering? Flamegraphs are loaded into [Speedscope](https://github.com/jlfwong/speedscope) using an Iframe and URI Encoded blobs (see [source](https://github.com/hschne/rails-mini-profiler/blob/main/app/views/rails_mini_profiler/flamegraphs/show.html.erb)) If your browser gives you warnings about blocking content due to CSP you _must_ enable `blob` as default source: ```ruby Rails.application.config.content_security_policy do |policy| policy.default_src :self, :blob ... end ``` ### Some requests have no Flamegraphs attached? [StackProf](https://github.com/tmm1/stackprof), which is used for recording Flamegraphs, does not work on concurrent requests. Because of this, concurrent requests may skip recording a Flamegraph. It is recommended that you resend _only_ the request you wish to build a Flamegraph for. ## Credit This project was heavily inspired by projects such as [rack-mini-profiler](https://github.com/MiniProfiler/rack-mini-profiler) and [rack-profiler](https://github.com/dawanda/rack-profiler). [Skylight](https://www.skylight.io/) was also a huge influence. [Lena Schnedlitz](https://github.com/LenaSchnedlitz) designed the Logo and provided great support. Without her supreme CSS skills this project would not have been possible 🙌 ## Contributing See [Contributing](CONTRIBUTING.md) ## License This gem is available as open source under the terms of the [MIT License](LICENSE).