How we struggled with performance issues at Redmine. Who is to blame and how to help?

    Of course, the article is not quite correctly named. In pure Redmine there are no particularly big performance problems. But we, in the process of developing a large number of plug-ins, introduced these problems with ease.

    Therefore, the article will tell you how to figure out what is the reason for the slow operation of a particular function of the Redmine plugin and what tools can help with this. Many tips, of course, may apply not only to Redmine itself, but also to Rails applications in general.

    The symptom of performance problems is always one - this is an angry user, screaming, cursing your software and possibly you personally.

    Rack mini profiler

    Most often, problems with the long opening of a page are associated with SQL queries. It can be just long-running SQL queries or circular queries caused by the features of the Active Record mechanism in ROR. In any case, the Rack Mini Profiler is a mega-useful thing for analyzing performance problems in Redmine.

    Rack Mini Profiler is a small gem that installs in a couple of commands and in near real-time mode shows which requests were executed during the page loading process and how much time was spent for each request. For analyzing performance issues, this thing is simply indispensable.

    In the early stages of Rails programming, I had a strong feeling that Ruby on Rails was such a well-thought-out framework that, using the Active record, I simply selected the data I needed, thinking that the developers of the framework took care of the rest.

    As a result? I spawned a large bunch of circular SQL queries. With the increase in the number of users, some pages began to open for a very long time.

    Rack Mini Profiler allows you to very quickly find the reason for a long page opening for a particular user. Here's how, for example, it might look if you don't add “includes” to the “active record” construct.

    The total number of SQL queries in itself is suspicious:

    If you look at more detailed statistics, you can understand that when you open the page, cyclic SQL queries are generated and this problem needs to be fixed.

    Even after a deeper understanding of the Active record in Rails came in, from time to time, looping requests crawled to the production server. Therefore, we decided that the tester, checking the task, must necessarily analyze the information from the Rack Mini Profiler for the presence of long and cyclical queries.

    Plugin for Redmine - “RmPlus DevTools”

    Rack Mini Profiler is enabled by default in the development environment and disabled in production. But often it is necessary to analyze the performance situation in the production environment and for a particular user, so we wrote a small plugin for Redmine that connects the Rack Mini Profiler to the Redmine production environment and allows you to connect profiling only for a specific user - Redmine Dev Tools .

    Also, this plugin connects the Oink jam (I'll talk about it a little later) and makes it possible to conduct more convenient development of plugins for Redmine in the development environment: there is no need to restart the web server so that changes in JS files are applied on the page.


    Oink is another super-useful jam for analyzing performance issues. It helped a lot when memory began to leak on our working server. One of the Rails processes, for unknown reasons, eats up more than a gigabyte of RAM and hangs the entire Remine.

    As a result: a bunch of phone calls, goosebumps and a slight sense of powerlessness.

    Oink lets you analyze which Rails controllers and actions are eating memory by setting a threshold value. These statistics shed light on the source of the problem, after which eliminating the source of the problem becomes more trivial.

    oink --threshold 50 /usr/share/srv-redmine/redmine-2.5/log/oink.log

    Something like that! I hope my article will be helpful. She would be very useful to me in due time.

    Also popular now: