ballerina-platform / ballerina-library

The Ballerina Library
https://ballerina.io/learn/api-docs/ballerina/
Apache License 2.0
136 stars 64 forks source link

Fix Ballerina GraphQL slowness #6190

Open JIshanRandika opened 7 months ago

JIshanRandika commented 7 months ago

service.bal for REST service:

service / on new http:Listener(9090) {
    resource function get opportunitiesArr()
        returns types:Opportunity[]|error? {
        return database:loadOpportunityArrData({}, 10, 0);
    }
}

service.bal for GraphQL service:

service /graphql on new graphql:Listener(9090) {
    function init() {
        log:printInfo("GraphQL service started.");
    }
    resource function get opportunitiesArr()
        returns types:Opportunity[]|error? {
        return database:loadOpportunityArrData({}, 10, 0);
    }
}

Both of the above services calling the same function. Retrieving the 10 records through the REST API results in a response time of 941ms, whereas GraphQL takes 3.4s (same size - 24.06KB). This discrepancy in response time persists and worsens with an increase in the number of records queried via GraphQL.

Number of Records REST Service Responce Time GraphQL Service Responce Time Size
10 941ms 3.4s 24.06KB
100 1301ms 5.93s 238.59KB
1000 2.79s 53.79s 2.33MB

Note: No delay to retrieve data from the database. Delay becomes when pushing the data to somewhere (such as UI or Postman) after retrieved the data from database.

ThisaruGuruge commented 7 months ago

Hi,

There are a couple of concerns here.

  1. There is a slowness in GraphQL execution and response formatting (GraphQL needs response formatting after fetching the data to match the client's request). Both these operations seem to be taking more time than expected. There are a couple of suspected culprits, we are analyzing further to avoid this issue.
  2. The GraphQL API which observed this behavior was also not quite optimized. To explain this further, the response contains more than 1000 elements within an array, each with more than 50 fields. This results in the response of over 50000 fields. This isn't an optimal way of handling data in our view. Ideally, we should use pagination to retrieve data as chunks.

So, as a quick fix, we can reduce the time by reducing the amount of data returned from this API. We (the Ballerina Library Team) can help you to implement the pagination as well if required.

The performance issue is related (but not limited) to https://github.com/wso2-enterprise/internal-support-ballerina/issues/626 as well.

I will update here when we have more information about this and the possible fixes.