This add-on is operated by Bear Metal
Automatic Ruby Garbage Collection tuning
TuneMyGC
Last updated July 28, 2023
This article is a work in progress, or documents a feature that is not yet released to all users. This article is unlisted. Only those with the link can access it.
The TuneMyGC add-on is currently in beta.
Table of Contents
TuneMyGC is an add-on for tuning the Ruby garbage collector (GC) in an optimal way.
The Ruby garbage collector has been flagged as the crux of Ruby performance and memory use for a long time. It has improved a lot over the years, but there’s still a lot to tune and control. The default configuration is not suitable and optimal for most applications, and neither is there a one-size-fits-all set of tuned parameters that would suit every app. However, hand-tuning the GC parameters is difficult to navigate for most developers.
TuneMyGC requires a lightweight agent that syncs with a web service when your application restarts. This add-on allows for scheduling measurements and applying optimal garbage collector configurations to your Heroku application.
Provisioning the add-on
TuneMyGC can be attached to a Heroku application via the CLI:
A list of all plans available can be found here.
$ heroku addons:create tunemygc
-----> Adding tunemygc to sharp-mountain-4005... done, v18 (free)
Once TuneMyGC has been added a RUBY_GC_TOKEN
setting will be available in the app configuration and will contain the canonical reference used to identify your application in the TuneMyGC service. This can be confirmed using the heroku config:get
command.
$ heroku config:get RUBY_GC_TOKEN
d739119e4abc38d42e183d1361991818
After installing TuneMyGC the application should be configured to fully integrate with the add-on.
Using with Rails 3.x and 4.x
Ruby on Rails applications will need to add the following entry into their Gemfile
specifying the TuneMyGC agent library.
gem 'tunemygc'
Update application dependencies with bundler.
$ bundle install
Thats it! The TuneMyGC add-on handles scheduling GC measurements and applying garbage collector configurations to your application. All reports and insights are visible to you from there as well.
Monitoring & Logging
TuneMyGC activity can be observed within the Heroku log-stream by filtering like this:
$ heroku logs -t | grep 'tunemygc'
Dashboard
The TuneMyGC dashboard allows you to:
- Stop and start GC measurements
- Apply suggested garbage collector configurations to your application
- Filter through measurements and introspect program memory usage and garbage collection activity
The dashboard can be accessed via the CLI:
$ heroku addons:open tunemygc
Opening tunemygc for sharp-mountain-4005…
or by visiting the Heroku Dashboard and selecting the application in question. Select TuneMyGC from the Add-ons menu.
Tuning workflows
We’ve broken down the tuning process into a few simple states.
Start measuring
Start measuring enables the agent, collects data points and syncs them with the TuneMyGC services when the application terminates or restarts.
Your application will restart.
Sets the following variables to your environment:
RUBY_GC_SPY
- The type of processing to spy on. For example, ActionController for a web dyno.RUBY_GC_TUNE
- Tuning duration, the number of requests to spy on (per process).
End measuring
End measuring disables the agent and prevents it from collecting and syncing any data to TuneMyGC.
Your application will restart.
Removes the following variables from your environment:
RUBY_GC_SPY
- The type of processing to spy on eg. ActionController for a web dyno.RUBY_GC_TUNE
- Tuning duration, the number of requests to spy on (per process).
Apply configuration
Apply configuration applies a selected garbage collector configuration to your application.
Your application will restart.
Sets the following variables to your environment:
RUBY_GC_HEAP_INIT_SLOTS
- The initial number of slots Ruby allocates on its heap.RUBY_GC_HEAP_FREE_SLOTS
- The minimum number of free slots that should be available after a GC run.RUBY_GC_HEAP_GROWTH_FACTOR
- The factor by which the size of the heap grows when it needs to be expanded.RUBY_GC_HEAP_GROWTH_MAX_SLOTS
- The maximum number of slots Ruby can add to its heap at once.RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR
- The factor by which Ruby increases old object and shady object limits.RUBY_GC_MALLOC_LIMIT
- The minimum value for malloc limits that would trigger a minor GC.RUBY_GC_MALLOC_LIMIT_MAX
- The maximum value the malloc limit can grow to. It changes dynamically by a growth factor.RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR
- The growth factor by which malloc limits is resized before every sweep.RUBY_GC_OLDMALLOC_LIMIT
- The old generation counterpart to RUBY_GC_MALLOC_LIMIT. The minimum value for oldmalloc limits that would trigger a major GC.RUBY_GC_OLDMALLOC_LIMIT_MAX
- The maximum value the oldmalloc limit can grow to. It changes dynamically by a growth factor.RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR
- The growth factor by which oldmalloc limits is resized before every sweep.
Removes the following variables from your environment:
RUBY_GC_SPY
- The type of processing to spy on. For example, ActionController for a web dyno.RUBY_GC_TUNE
- Tuning duration, the number of requests to spy on (per process).
Remove configuration
Remove configuration removes a previously applied garbage collector configuration from your application.
Your application will restart.
Removes the following variables from your environment:
RUBY_GC_SPY
- The type of processing to spy on. For example, ActionController for a web dyno.RUBY_GC_TUNE
- Tuning duration, the number of requests to spy on (per process).RUBY_GC_HEAP_INIT_SLOTS
- The initial number of slots Ruby allocates on its heap.RUBY_GC_HEAP_FREE_SLOTS
- The minimum number of free slots that should be available after a GC run.RUBY_GC_HEAP_GROWTH_FACTOR
- The factor by which the size of the heap grows when it needs to be expanded.RUBY_GC_HEAP_GROWTH_MAX_SLOTS
- The maximum number of slots Ruby can add to its heap at once.RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR
- The factor by which Ruby increases old object and shady object limits.RUBY_GC_MALLOC_LIMIT
- The minimum value for malloc limits that would trigger a minor GC.RUBY_GC_MALLOC_LIMIT_MAX
- The maximum value the malloc limit can grow to. It changes dynamically by a growth factor.RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR
- The growth factor by which malloc limits is resized before every sweep.RUBY_GC_OLDMALLOC_LIMIT
- The old generation counterpart to RUBY_GC_MALLOC_LIMIT. The minimum value for oldmalloc limits that would trigger a major GC.RUBY_GC_OLDMALLOC_LIMIT_MAX
- The maximum value the oldmalloc limit can grow to. It changes dynamically by a growth factor.RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR
- The growth factor by which oldmalloc limits is resized before every sweep.
There’s thus some fluctuation in your application environment. The RUBY_GC_TOKEN
config var is constant and the canonical link between your application and TuneMyGC.
Removing the add-on
TuneMyGC can be removed via the CLI.
This will destroy all associated data and cannot be undone! Given the nature of the service is performance and memory tuning, there may also be resource implications as the configuration is reverted.
$ heroku addons:destroy tunemygc
-----> Removing tunemygc from sharp-mountain-4005... done, v20 (free)
Support
All TuneMyGC support and runtime issues should be submitted via one of the Heroku Support channels. Any non-support related issues or product feedback is welcome at tunemygc@bearmetal.eu.