Skip to content

Instantly share code, notes, and snippets.


Mike Perham mperham

View GitHub Profile
mperham / Benchmark.rb
Last active Nov 6, 2020
Leaky bucket limiter usage with Sidekiq Enterprise
View Benchmark.rb
require 'benchmark'
require 'sidekiq-ent/limiter'
COUNT = 10_000
Benchmark.bmbm(30) do |x|"leaky") do
COUNT.times do |count|
lmt = Sidekiq::Limiter.leaky("leaky_#{count%100}", 10, 10, wait_timeout: 0, policy: :skip)
lmt.within_limit do
View output.txt
❯ make runruby
./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -- --disable-gems ./test.rb
<internal:ractor>:38: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
#<Thread:0x00007fadd701fa90 run> terminated with exception (report_on_exception is true):
<internal:ractor>:124:in `take': thrown by remote Ractor. (Ractor::RemoteError)
from ./test.rb:11:in `<main>'
./test.rb:5:in `logger': can not access instance variables of classes/modules from non-main Ractors (RuntimeError)
from ./test.rb:10:in `block in <main>'
make: *** [runruby] Error 1
mperham / aj.txt
Created May 8, 2020
AJ vs Sidekiq backtraces
View aj.txt
2020-05-08T15:52:22.241Z pid=10710 tid=2me WARN: RuntimeError: boom
2020-05-08T15:52:22.241Z pid=10710 tid=2me WARN: /Users/mikeperham/src/sidekiq/myapp/app/jobs/some_job.rb:5:in `perform'
/Users/mikeperham/.gem/ruby/2.7.1/gems/activejob-6.0.3/lib/active_job/execution.rb:40:in `block in perform_now'
/Users/mikeperham/.gem/ruby/2.7.1/gems/activesupport-6.0.3/lib/active_support/callbacks.rb:112:in `block in run_callbacks'
/Users/mikeperham/.gem/ruby/2.7.1/gems/i18n-1.8.2/lib/i18n.rb:313:in `with_locale'
/Users/mikeperham/.gem/ruby/2.7.1/gems/activejob-6.0.3/lib/active_job/translation.rb:9:in `block (2 levels) in <module:Translation>'
/Users/mikeperham/.gem/ruby/2.7.1/gems/activesupport-6.0.3/lib/active_support/callbacks.rb:121:in `instance_exec'
/Users/mikeperham/.gem/ruby/2.7.1/gems/activesupport-6.0.3/lib/active_support/callbacks.rb:121:in `block in run_callbacks'
/Users/mikeperham/.gem/ruby/2.7.1/gems/activesupport-6.0.3/lib/active_support/core_ext/time/zones.rb:66:in `use_zone'
View gist:12ca6ff49ed0b665fd971fbada546ea5
~/src/sidekiq (master *=)$ bundle exec bin/sidekiqload
ruby 2.6.0preview3 (2018-11-06 trunk 65578) [x86_64-darwin17]
2018-11-06T18:17:06.966Z 34703 TID-ovsoikzhj INFO: Booting Sidekiq 5.2.3 with redis options {:db=>13, :id=>"Sidekiq-server-PID-34703", :url=>nil}
2018-11-06T18:17:10.046Z 34703 TID-ovsoikzhj ERROR: Created 100000 jobs
2018-11-06T18:17:11.058Z 34703 TID-ovsofju03 ERROR: RSS: 56880 Pending: 94926
2018-11-06T18:17:12.067Z 34703 TID-ovsofju03 ERROR: RSS: 57084 Pending: 89629
2018-11-06T18:17:13.080Z 34703 TID-ovsofju03 ERROR: RSS: 57104 Pending: 84563
2018-11-06T18:17:14.093Z 34703 TID-ovsofju03 ERROR: RSS: 57104 Pending: 79536
2018-11-06T18:17:15.105Z 34703 TID-ovsofju03 ERROR: RSS: 57104 Pending: 74438
2018-11-06T18:17:16.117Z 34703 TID-ovsofju03 ERROR: RSS: 57108 Pending: 69405
mperham / frag.rb
Last active Feb 8, 2021
memory fragmentation on ruby 2.5.1
View frag.rb
This script attempts to reproduce poor glibc allocator behavior within Ruby, leading
to extreme memory fragmentation and process RSS bloat.
glibc allocates memory using per-thread "arenas". These blocks can easily fragment when
some objects are free'd and others are long-lived.
Our script runs multiple threads, all allocating randomly sized "large" Strings between 4,000
and 40,000 bytes in size. This simulates Rails views with ERB creating large chunks of HTML
to output to the browser. Some of these strings are kept around and some are discarded.
View bulk_bug_test.go
package storage
import (
mperham / gist:544327d176f9693df05d4d60548b0b16
Last active Sep 8, 2016
Fast counters with Redis, persisting to DB
View gist:544327d176f9693df05d4d60548b0b16
class Counter
include Sidekiq::Worker
# I'd use a separate Redis instance from Sidekiq
REDIS = 5) { }
# Call this API in your Rails app code to increment counters
# as the user does things.
def self.incr(name, amount=1)
key = "counter-#{name}-#{current_window}"
View gist:399f0ed0eca321aeaf9ee20cf104a849
~/src/ent/myapp (master *=)$ bundle exec derailed bundle:objects
Measuring objects created by gems in groups [:default, "production"]
Total allocated: 4246025 bytes (34726 objects)
Total retained: 437421 bytes (4179 objects)
allocated memory by gem
1348174 puma-3.6.0
749251 sidekiq/lib
538517 pro/lib
require "./src/sidekiq"
`redis-cli flushdb`
class LoadWorker
include Sidekiq::Worker
perform_types Int64
def perform(idx)
mperham / locktest.rb
Created Apr 23, 2016
Distributed Locking with Redis and Ruby
View locktest.rb
require 'benchmark'
require 'sidekiq-ent'
require 'redis-lock'
require 'redis-semaphore'
require 'ruby_redis_lock'
# monkey patch to remove exponential backoff in pmckee11-redis-lock,
# otherwise this benchmark does not complete successfully.
class Redis
class Lock