January 04 • 1 Min Read
In this part of the series, we will take a look at how we went about measuring and speeding up our newly implemented GraphQL API. We did not put much emphasis on optimizing for performance while we were initially building the api because we had no real data on how it would be used in production. The best thing we could do in the beginning was to integrate Apollo Engine to collect the data and later provide us with insights on how we can improve performance.
Apollo Engine is an easy to integrate cloud service that provides deep insights into GraphQL APIs. Engine utilizes GraphQL’s primary advantages to provide features like caching, query execution tracing, and field-level error tracking. To gather insights on how our API is performing, we used the query tracing feature.
With query tracing, we can see what is slowing down our queries on a per-resolver level:
This tells us exactly which part of our query is taking the longest to execute and how much time it added to the overall response time.
We noticed that every query request was initially taking a long time to react the first resolver:
This accounted for an average of ~30% of the wait time of each query. This was because we were authenticating the user and fetching some basic user information from the database each time an api call was made.
This gives us a huge opportunity for us to speed up the response time for every query request hitting our api.
Since we were using JSON Web Tokens (JWTs) for authenticating and managing user sessions, we can use one of its key features to our advantage— the payload. We can encode the user data we were previously getting for each api request as part of the JWT payload at the time of generating the auth token. This way, our backend can use this information instead of fetching from the database for each request.
We were able to speed up the response time of every query request by an average of 30%.
This was just one simple way we were able to find an opportunity to improve user experience using Apollo Engine. Since then, we were able to identify a few other queries which had very long response times and were able to split them up into smaller, faster queries. Gaining insights like this for REST APIs was very difficult because the implementation is different for each api and would require a lot of time to implement.