Richard Schneeman, a Ruby and Rails engineer formerly at Heroku, writes about Puma, Rails internals, performance and developer life.
Commenters cite his posts on Rails, tutorials and an online master's program, though one says his recent headlines have become clickbaity.
> 2.0.0 means no memory errors
2.1 has a totally new GC setup (generational GC). It is guaranteed to use more memory (expect 3~5%), but be MUCH MUCH MUCH faster. Typically you can trade off running one less Puma worker to decrease memory usage, and the increase in speed may make up for it. Alternatively you can bump up to 2x dynos, and cut the number of dynos you have in half. If you haven't tried 2.1.3 or above do yourself a favor and revisit. The 2.1.3 patch means memory grows much more slowly.
Also if you didn't see my post on memory profiling: http://www.schneems.com/2014/11/07/i-ram-what-i-ram.html (It got over 40 upvotes on reddit, and like 3 on HN, again...HN what is going on? I've had much less substantial posts make it front page). That post shows you how to remove ~30% starting RAM (by bumping mail version to 2.6.3+) and shows you can profile and remove libraries that are using a ton of memory in your app.
You can also use something like puma_worker_killer (or unicorn_worker_killer) to tame your memory growth if it only balloons over 512mb after a while, but ultimately those two solutions are bandaids.
Ruby 2.0 isn't going to be supported forever and the generational GC is definitely here to stay. Maybe try the 2.2.0 preview (it's on Heroku), it has 3 generations (total) which means much less retained memory and you still get speed performance improvements.
I see most of the bigger production apps using 2.1+ fwiw.
Thanks for the fast reply! For some background:
Rundoc is a tool for writing tutorials such that the author is guaranteed the outcome is valid (if a command fails, the tutorial fails) and for helping users see the exact output they would expect (instead of a static output). The tool has website integration that allows you to take screenshots and navigate a webpage.
Recently I wrote this tutorial https://schneems.com/2023/06/14/its-dangerous-to-go-alone-pub-mod-use-thisrs/ which makes heavy use of vscode extension shortcuts and hover over tips. I would love to be able to keep that tutorial up to date by scripting the tooltips to make sure the options don’t change and the suggested commands like CMD+. Continue to work.
Slightly off-topic digression:
Would WAS compilation help solve the ruby / rails timeout problem?
https://devcenter.heroku.com/articles/h12-request-timeout-in-ruby-mri
> H12 - Request Timeout in Ruby (MRI)
> Rack-timeout limitations
> Due to the design of the Ruby programming language’s Thread#raise API, which timing out code depends on, there is a known bug with rack-timeout that can put your app into a bad state if rack-timeout fires too frequently.
(Other related URLs)
https://github.com/ankane/the-ultimate-guide-to-ruby-timeouts
https://headius.blogspot.com/2008/02/rubys-threadraise-threadkill-timeoutrb.html
https://www.schneems.com/2017/02/21/the-oldest-bug-in-ruby-why-racktimeout-might-hose-your-server/
The other answer is correct I believe, but I think the most common recommendation I've seen for rails boils down to "Use Timeout, and then kill and restart the process" (ref: [0], [1]), which obviously doesn't feel great for performance when a timeout in one thread can cause all other threads to need to be killed.
[0] https://www.schneems.com/2017/02/21/the-oldest-bug-in-ruby-why-racktimeout-might-hose-your-server/
[1] https://github.com/zombocom/rack-timeout (c.f. term_on_timeout)
I've been entertaining the idea of going through this course as well. I graduated 2 years ago, BS in CS, and part of me misses being in school. Plus my employer has a decent tuition reimbursement program.
Would anyone who works full time and gone through this program care to share their thoughts?
Edit: Just found this great article from another comment
https://schneems.com/2017/07/26/omscs-omg-is-an-online-masters-right-for-you/
(note: I use both Elixir & Ruby, for different reasons)
You can most of the time rely on object.method(:blank?).source_location to quickly determine where a specific method is defined.
More useful debugging tips can be found here:
https://www.schneems.com/2016/01/25/ruby-debugging-magic-cheat-sheet.html