Skip to content

API GrapeRouteHelpers seem to be a major performance bottleneck

In the process of profiling some API endpoints for a large customer, I notice that something like 80% of lots of API calls is spent within GrapeRouteHelpers. This is an abandoned gem that hasn't been modified since Dec 2016, and we've even had to bring a few critical fixes into a monkey patch because of this.

A lot of the issue seems to be the creation of a ton of ActiveSupport::HashWithIndifferentAccess objects. I ran the profile below on a rather small dev instance calling the /api/v4/groups/:id endpoint and it took 21 seconds.

  • HashWithIndifferentAccess#initialize and #update were called 90,000 times each
  • HashWithIndifferentAccess#convert_value was called 375,000 times!
  • Various other HashWithIndifferentAccess methods were called tens of thousands of times.

This seems like a major bottleneck. What can we do about it?

Of note, we seem to get into this mess only in the presentation portion of the API. That is, when we have quite a few objects to render into JSON via the Grape expose for entities. Remember, this profile was taken on a dev instance with not that many groups or projects so we're not even talking about a ton of data here. Imagine how exponential it is when more data.

Screen_Shot_2018-04-24_at_9.46.16_AM

cc/ @toon @mdelaossa @oswaldo I noticed you all opened issues in grape-route-helpers at some point so maybe you have some knowledge here about our options?