
Security News
Scaling Socket from Zero to 10,000+ Organizations
Socket CEO Feross Aboukhadijeh shares lessons from scaling a developer security startup to 10,000+ organizations in this founder interview.
vernier
Advanced tools
Next-generation Ruby 3.2.1+ sampling profiler. Tracks multiple threads, GVL activity, GC pauses, idle time, and more.
Livestreamed demo: Pairin' with Aaron (YouTube)
Overview at RubyKaigi 2024 (YouTube)
Sidekiq jobs from Mastodon (time, threaded) : https://share.firefox.dev/44jZRf3
Puma web requests from Mastodon (time, threaded) : https://share.firefox.dev/48FOTnF
Rails benchmark - lobste.rs (time) : https://share.firefox.dev/3Ld89id
require "irb" (retained memory)
: https://share.firefox.dev/3DhLsFa
Vernier requires Ruby version 3.2.1 or greater and a Unix-like operating system.
gem "vernier", "~> 1.0"
The output can be viewed in the web app at https://vernier.prof, locally using the profile-viewer gem (both lightly customized versions of the Firefox profiler frontend which profiles are compatible with), or by using the vernier view command in the CLI.
The easiest way to record a program or script is via the CLI:
$ vernier run -- ruby -e 'sleep 1'
starting profiler with interval 500 and allocation interval 0
#<Vernier::Result 1.001589 seconds, 1 threads, 1 samples, 1 unique>
written to /tmp/profile20240328-82441-gkzffc.vernier.json.gz
$ vernier run --interval 100 --allocation-interval 10 -- ruby -e '10.times { Object.new }'
starting profiler with interval 100 and allocation interval 10
#<Vernier::Result 0.00067 seconds, 1 threads, 1 samples, 1 unique>
written to /tmp/profile20241029-26525-dalmym.vernier.json.gz
Vernier.profile(out: "time_profile.json") do
some_slow_method
end
Vernier.profile(out: "time_profile.json", interval: 100, allocation_interval: 10) do
some_slow_method
end
Alternatively you can use the aliases Vernier.run and Vernier.trace.
Vernier.start_profile(out: "time_profile.json", interval: 10_000, allocation_interval: 100_000)
some_slow_method
# some other file
some_other_slow_method
Vernier.stop_profile
You can also use Vernier::Middleware to profile a Rack application:
# config.ru
require "vernier"
use Vernier::Middleware
run ->(env) { [200, { "Content-Type" => "text/plain" }, ["Hello, Profiling World!"]] }
If you're using Rails, you can add the middleware to your config/application.rb:
config.middleware.use Vernier::Middleware, permit: ->(env) { env["PATH_INFO"].start_with?("/api") }
You can then enable profiling and configure options with query parameters:
curl http://localhost:3000?vernier=true&vernier_interval=100&vernier_allocation_interval=10
Record a flamegraph of all retained allocations from loading irb:
ruby -r vernier -e 'Vernier.trace_retained(out: "irb_profile.json") { require "irb" }'
[!NOTE] Retained-memory flamegraphs must be interpreted a little differently than a typical profiling flamegraph. In a retained-memory flamegraph, the x-axis represents a proportion of memory in bytes, not time or samples The topmost boxes on the y-axis represent the retained objects, with their stacktrace below; their width represents the percentage of overall retained memory each object occupies.
Hooks automatically add markers to profiles based on application events:
Vernier.profile(hooks: [:activesupport, MyHook]) do
# code to profile
end
:activesupport (:rails) - ActiveSupport notifications:memory_usage - Memory usage trackingDefine a class with initialize(collector), enable, and disable methods:
class MyHook
def initialize(collector)
@collector = collector
end
def enable
# Set up event listeners
end
def disable
# Clean up
end
end
For Firefox profiler integration, add firefox_marker_schema or firefox_counters methods (see Firefox profiler docs for format details):
def firefox_marker_schema
[{
name: "my_event",
display: ["marker-chart", "marker-table"],
tooltipLabel: "{marker.data.name}",
data: [
{ key: "name", format: "string" }
]
}]
end
def firefox_counters
{
name: "my_counter",
category: "Custom",
description: "My custom counter",
samples: {
time: [0, 1000, 2000],
count: [10, 20, 30],
length: 3
}
}
end
See examples/custom_hook.rb for a complete example.
| Option | Middleware Param | Description | Default (Middleware Default) |
|---|---|---|---|
mode | N/A | Sampling mode: :wall, :retained, or :custom. | :wall (:wall) |
out | N/A | File to write the profile to. | N/A (Auto-generated) |
interval | vernier_interval | Sampling interval (µs). Only in :wall mode. | 500 (200) |
allocation_interval | vernier_allocation_interval | Allocation sampling interval. Only in :wall mode. | 0 i.e. disabled (200) |
gc | N/A | Run full GC cycle before profiling. Only in :retained mode. | true (N/A) |
metadata | N/A | Metadata key-value pairs to include in the profile. | {} (N/A) |
Vernier offers some optional hooks:
:rails / :activesupport - Adds selected Active Support event markers to the Firefox output
:memory_usage - Adds a memory usage counter to the Firefox output
Usage example:
Vernier.profile(out: "time_profile.json", hooks: [:rails, :memory_usage]) do
# ...
end
After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/jhawthorn/vernier. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
The gem is available as open source under the terms of the MIT License.
Everyone interacting in the Vernier project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.
FAQs
Unknown package
We found that vernier demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket CEO Feross Aboukhadijeh shares lessons from scaling a developer security startup to 10,000+ organizations in this founder interview.

Research
Socket Threat Research maps a rare inside look at OtterCookie’s npm-Vercel-GitHub chain, adding 197 malicious packages and evidence of North Korean operators.

Research
Socket researchers identified a malicious Chrome extension that manipulates Raydium swaps to inject an undisclosed SOL transfer, quietly routing fees to an attacker wallet.