News for hackers. Stuff that matters.
Re:The dark side of GraphQL: performance by picardo on Wednesday January 01, 2020 @03:30PM (#21930398)
I'm not sure if this is mentioned in the thread, but one of the reason it takes so long for the requests to return is when GQL initializes the entire record in memory and then reduces it back to only the fields you wanted. This can be a big problem if you have a deeply nested data model, and potentially many results. The memory consumption can hit the roof. I find that the best approach in those cases is to create a one-off REST endpoint (or to create a field higher up the GQL hierarchy) and handroll the SQL query.
Re:The dark side of GraphQL: performance by viraptor on Wednesday January 01, 2020 @03:59PM (#21930589)
> when GQL initializes the entire record in memory

GQL is an idea not an implementation. I don't believe there's anything preventing actual software from optimising this case. Or am I missing something here? The query defines what you're asking for so extra data does not necessarily need to be fetched.

Re:The dark side of GraphQL: performance by xtagon on Wednesday January 01, 2020 @04:15PM (#21930705)
You're correct. It's common for GraphQL API implementations to batch all the parent record's fields up front, but it's not the only way. One alternative method is to traverse the whole query object and generate one big query to your database (SQL, graph database, what have you) instead of batching queries per table/object. This has trade-offs. Sometimes it's more performant, especially for smaller queries, but for larger queries it can actually be slower because joining lots of tables into one query causes some duplicated data and transfer overhead (assuming you're using SQL). I have a feeling that this method would perform very well if your GraphQL data was backed by an actual graph database though.
Re:The dark side of GraphQL: performance by sergiotapia on Wednesday January 01, 2020 @05:41PM (#21931240)
I'm positive there's a way to only load the relevant data in your stack.

In Elixir with Absinthe we can resolve to the specific fields we need and we don't load the entire records then slim down.

Re:The dark side of GraphQL: performance by picardo on Wednesday January 01, 2020 @05:50PM (#21931301)
I never used Absinthe, but if you're initializing an ORM in your resolver, loading the entire record into memory is unavoidable. How does Absinthe get around that? (Sounds like it generates the SQL?)
Re:The dark side of GraphQL: performance by nivertech on Thursday January 02, 2020 @02:54PM (#21939093)
Absinthe does some dumb things by default too. You need to manually optimize your resolvers.

One annoying thing Absinthe did by default I noticed was fetching entire object from DB, even though the GraphQL query only returns it's ID. For example query below would fetch each person from a DB, even though we already had a list of person IDs on the friends level:

  {
    friends {
      person {
        id
      }
    }
  }
Re:The dark side of GraphQL: performance by sergiotapia on Wednesday January 01, 2020 @06:39PM (#21931626)
you point it to a resolver, in your resolver your resolve, in other words write the query
Re:The dark side of GraphQL: performance by benawad on Wednesday January 01, 2020 @05:11PM (#21931082)
I thought it could have been a memory problem too, but VPS didn't show any signs of anything spiking https://twitter.com/benawad/status/1212404379371917313

but I do think it's related to my nested object https://twitter.com/benawad/status/1212407236284338176

Re:The dark side of GraphQL: performance by greenpizza13 on Wednesday January 01, 2020 @03:38PM (#21930457)
Things have matured quite a bit. With Apollo Server it's possible to fully understand which fields are being requested before creating and running, for example, and SQL query. Fetching only the requested data for a given query reduces in-memory footprint. Most people get the whole data object and then allow GQL to select the subset of fields the user asked for, but for cases where performance is a problem there is another solution.
Re:The dark side of GraphQL: performance by picardo on Wednesday January 01, 2020 @03:53PM (#21930549)
I haven't used Apollo Server lately. But the way you describe it doesn't address the core issue, which is the initialization of the intermediate objects in-memory. So just to give an example, if I wanted to query for the projects of listings of my company, I can write it this way in GQL:

   me { company { listings { projects { id name } } } }
This will initialize: a User, a Company, Listings and Projects of all listings.

I can also write this in SQL using a couple of joins and return an array. The memory consumption is trivial in comparison to the original request.

Re:The dark side of GraphQL: performance by klarstrup on Thursday January 02, 2020 @09:46AM (#21935705)
You can implement your GraphQL server to do either of those, it's not inherent.
Re:The dark side of GraphQL: performance by andrewem on Wednesday January 01, 2020 @03:41PM (#21930477)
You say "problem there is another solution" - what is the other solution? (I'm guessing it involves somehow telling Apollo Server which fields/related objects you will need?)
Re:The dark side of GraphQL: performance by np_tedious on Wednesday January 01, 2020 @03:38PM (#21930455)
How deeply do you mean "entire record"? I am pretty sure that this concern only applies to those fields which have the same resolver
Re:The dark side of GraphQL: performance by city41 on Wednesday January 01, 2020 @04:55PM (#21930998)
It's also possible to look at what fields were requested in the GraphQL query and use them to aid what gets fetched.