Search code examples
performanceruby-on-rails-3herokuruby-on-rails-4memory-leaks

Rails 3.2 -> 4.2 Emergency upgrade, memory leak on Heroku


with the May 1st deprecation of the Heroku-18 stack, I needed to update a very old Rails app to the minumum version required. It was though, but I got it working.

I have a completely new version to deploy soon based rails 6, but for the time being, I need to run this old app. I noticed the memory footprint almost doubled (on 3.2 it was avg 90-120% of 512mb ram) and my immediate stop gap solution is to update the dynos to 2x 1gb ram, however, I would like to pinpoint the isse.

2023-05-01T17:46:12.209506+00:00 heroku[web.1]: Process running mem=990M(188.0%)
2023-05-01T17:46:12.211046+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2023-05-01T17:46:33.107262+00:00 heroku[web.1]: Process running mem=990M(188.0%)
2023-05-01T17:46:33.111875+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2023-05-01T17:46:54.224029+00:00 heroku[web.1]: Process running mem=990M(188.0%)
2023-05-01T17:46:54.227886+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2023-05-01T17:47:15.327098+00:00 heroku[web.1]: Process running mem=990M(188.0%)
2023-05-01T17:47:15.328612+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2023-05-01T17:47:36.150757+00:00 heroku[web.1]: Process running mem=990M(188.0%)
2023-05-01T17:47:36.152131+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)
2023-05-01T17:47:57.287322+00:00 heroku[web.1]: Process running mem=990M(188.0%)
2023-05-01T17:47:57.289241+00:00 heroku[web.1]: Error R14 (Memory quota exceeded)

The old app used memcachd, the new app is using in-memory caching, which can surely be one of the issues. Can I switch to file-base caching? Should I look into Redis caching or any other solution that I have not considered?

This app is also using Unicorn, all my newer apps are using Puma. Is this worth looking into?


Solution

  • This is an old question, but may still benefit new users for a while.

    Two solutions here:

    1. Switch to using jemalloc instead for memory allocation, this is amazing for older versions of rails. Basically, it allows your memory to go down rather than just always going up over time, you can read the docs and such for more. I recently used it to get an app that required four $50/mo dynos to need just one hobby dyno. This can be handled just via adding a buildpack to heroku, no change to the code needed. https://prathamesh.tech/2021/05/23/adding-jemalloc-to-rails-apps-on-heroku/
    2. To get the rails app to deploy, it needs to be running (the newest) ruby 2.7.X on heroku-20. I've had success with 2.7.8 to name a specific version. Of course, you may have gems that aren't compatible with that version.

    However, it should be noted that I don't think Rails 4.2 will still be able to deploy on heroku after heroku-20 is no longer available (April 2025). https://devcenter.heroku.com/articles/heroku-20-stack