Debugging CPU & Memory usage in Rails app
Photo by Isaac Smith on Unsplash

For the past few weeks, we were facing issue with the digital ocean machine hitting more than 90 % CPU limit for 5 mins continuously (We have set up monit to trigger a notification to our Telegram channel for it) and it is really annoying to see these many messages in telegram,

Monit alerts in the telegram

So in this post, I will log the approaches taken to debug the issue.

System configurations

Digital Ocean machine with 1 GB RAM, 25 GB Disk storage Debian box. Currently, everything is running here. Nginx for web server, Puma for app server (Rails), Postgresql database.

Figuring out the slow queries

Our first thought was to check how the database is performing. And we used pghero to see the number of queries executed and how long it is taking.

Pghero for analysing postgres queries

As you can see the topmost slow query is taking an average of 25 ms and it is the search query on profiles. According to our system specs, we felt that it is in acceptable limit.

Debug the memory usage

We want to take a look at memory usage because from htop we saw that most of the memory is taken and swap memory is also mostly full.

htop — mem & swap are mostly full

get_process_mem gem allows us to check the memory usage of particular piece of code and using GC object in ruby we can see how garbage collection is being done. Eg: you can see below which uses 641 MB of memory,

Profile memory

And you can see how much total objects are allocated and how much objects are freed after GC,

GC freed, allocated objects

We found the gem derailed_benchmarks which does all this for us. It can statically check how much is the memory used & objects allocated by the gems used in our project.

bundle exec derailed bundle:mem

We found that sprockets-rails gem occupies 2 MB, even though we are using the rails only for backend API. Apart from this, it is not of great use to us.

Object allocation per request

We integrated scoutapm to see which request allocates the most number of objects.
[]
['Memory Improvement', 'Monitoring', 'Ruby on Rails', 'Performance Tuning', 'Cpu']