The title is misleading. The post doesn't discover any dark sides of GraphQL. The post is about a potential performance problem with a library that implements the GraphQL spec. There might be a problem with the library itself. There might be a problem with the use of said library. The author states that it takes 19ms to fetch 20 recipes from a postgres database. This looks really suspicious. Why does it take so long to fetch 20 indexed rows? Maybe there's some general performance problem with the application?
You focus on and make assumptions it's indexed rows and that ~20ms average for a database call is "suspicious" but you're not concerned about the 400ms flamechart for graphql-js doing validation shown in the thread?
graphql-js is the reference implementation of GraphQL, so it's not any random library.
I hear your point and it's true that you can't point the finger at GraphQL qua GraphQL, but that's sort of by definition since gql in itself is, as you say, just a spec. But, and I'm not saying this is the case, if every implementation of gql has major issues, it's not really fair to say "but but the spec itself is fine". As programmers, we aren't working with the spec.
Reading the thread, this isn't a "dark side of GraphQL" but a "dark side of not understanding how to debug/improve performance in my software dependency".
Not sure why you are getting downvoted. The person actually states that they don't know how to debug, "honestly, I'm not 100% sure the best way to debug from here." They are just looking at Datadog stats and not finding the root cause. They could do some basic JS debugging of the open source library to figure out the issue. Blaming Apollo would be a stretch (which may not even be the issue since they haven't done any debugging), but the protocol of graphql is way too far.
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.
> 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.
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.
I guess I still don't quite get most GraphQL designs or why a lot of people jump to implement it... I have always thought the big idea behind GraphQL is you already have endpoints (likely rest) which are cached/optimized? And then GraphQL becomes a layer over the top to map/reduce client requests for more optimized request/response cycles for clients (and I guess decouple some business logic)?
Which then makes me wonder why this is the "dark side" of GraphQL? Isn't this just not optimizing a query somehow or using a cache effectively? Is it really the nature of GraphQL that's causing this to be slow or just programmer error [1]?
I've used GraphQL in production services as an alternative to a rest endpoint (which I didn't care for) and I don't think sheer the nature of the validations ever caused that much slow down or rather, more plainly put that GraphQLs design would not necessarily cause such poor performance on such a small set of data.
/shrug I dunno, if this were me, I'd just assume I had written a bad query or validation somewhere. And to be fair to the author, they only made a post on twitter to reflect on their problem, not to say GQL has a dark side (at least from what I read in the thread).
[1] We all have made programmer errors, are likely making some "now," and will for sure make more in the future. No reason to feel bad about it, we're all human :) Mistakes are just a part of life no matter how "good" at things we are.
It seems that the graphql library is performing a lot of validation, and that's slowing things down. I expect validation to be a pure-compute task, and this is Javascript, so I suspect this is really a "working with large amounts of data in Javascript is slow" issue - but that's just at a glance.
Sounds to me like an issue that comes with coupling of validation with serialization. A lot of these API frameworks combine the two, with a the goal of automating validation when receiving data from clients, but then also do that validation when serializing response data, which should already be validated if it's sitting in your database.
I've ran into similar issues with FastAPI and DRF when dealing with really large payloads.
Quite strange, GQL server source code is literally just walking by fields and resolving promises, very simple and straightforward.
We had something like this in our backend, but this long times is usually meant that something wastes event loop and just blocks everything from execution.
It could be anything for example it could be async hooks that makes ~1000 times slower if you are using a lot of promises (since resolving fields often are just promises) since overhead is per promise. In general in latest nodejs you can do huge amount of promises and they have little to no overhead, but, again - something wrong with nodejs setup, some library populate event loop or something deeper in nodejs internals. It is not an issue with gql itself since if you have gql performance issues that means that your server is super slow in processing like anything. Our team was shocked by performance and it turns out that NodeJS is super fast and it is some libraries (like sequelize) that kills the performance, but gql is not one of them.
I’ve seen similar issues in graphql-ruby. Even if I hardcode the data in my resolvers, it takes hundreds to thousands of ms to render a list with some moderate nesting.
I've built fairly complex GQL backends using CPython + Graphene and never seen something like this - if we had slowness it was because we were yet to implement dataloader in some places.
We faced similar issues at Zalando when trying to use Graphql at scale and to mitigate this we built https://github.com/zalando-incubator/graphql-jit. Try it for your usecase and let us know how it affects the performance
Checkout Super Graph it's a GraphQL to SQL compiler and API service in GO. In production mode it uses prepared statments so no compiling hence very latency. https://github.com/dosco/super-graph
Forgive me if this sounds a bit “hindsight 20/20”, but I feel like performance was always a lower consideration when it came to utilizing graphql. The win is in reducing overhead around providing new endpoints.
Like react, it eschews performance for the sake of enterprise level scaling. This shouldn’t come as a surprise to anyone, being both of these came from one of the largest dev organizations in the world.
Eschew performance isn't the right way to put it. React allows you to do 90% of UI work in performant ways. It has good predictable performance for the majority of work and allows you to move through a lot of simple UI tasks quickly. And spend time focusing on the performance in parts of your app that matter. The situations where you really need performance tuning are going to be unique to your specific app and data.
> performance was always a lower consideration when it came to utilizing graphql
That's strange, because I thought the main selling point was to consume only the data you need. The client specifies exactly which fields it wants. Then it doesn't over-fetch. To make things higher performance.
While it’s certainly true performance can be a trade off... 400ms+ response times are annoyingly slow. I’m not sure a trade off is worth it unless it’s some really exotic endpoint you’ve created
Hmmmm... if anything the performance of a graphql query should generally outshine REST in nearly any category of performance. From the sound of things, the performance issue doesn't make any sense. He's using Dataloader, and he is certain it's not related to dataloader anyway. So maybe some dependency he's using is the wrong version.
Can you elaborate? I find it hard to believe that you can't build a REST API that's faster than GraphQL given all of the bells and whistles that GraphQL tacks on and that you could hand write the perfectly optimized REST endpoint. What am I missing?
[+] [-] jensneuse|6 years ago|reply
[+] [-] ctvo|6 years ago|reply
graphql-js is the reference implementation of GraphQL, so it's not any random library.
[+] [-] xwowsersx|6 years ago|reply
[+] [-] unknown|6 years ago|reply
[deleted]
[+] [-] unknown|6 years ago|reply
[deleted]
[+] [-] CharlesW|6 years ago|reply
[+] [-] lasdfas|6 years ago|reply
[+] [-] tessting|6 years ago|reply
[+] [-] picardo|6 years ago|reply
[+] [-] viraptor|6 years ago|reply
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.
[+] [-] sergiotapia|6 years ago|reply
In Elixir with Absinthe we can resolve to the specific fields we need and we don't load the entire records then slim down.
[+] [-] benawad|6 years ago|reply
but I do think it's related to my nested object https://twitter.com/benawad/status/1212407236284338176
[+] [-] greenpizza13|6 years ago|reply
[+] [-] np_tedious|6 years ago|reply
[+] [-] city41|6 years ago|reply
[+] [-] rubyn00bie|6 years ago|reply
Which then makes me wonder why this is the "dark side" of GraphQL? Isn't this just not optimizing a query somehow or using a cache effectively? Is it really the nature of GraphQL that's causing this to be slow or just programmer error [1]?
I've used GraphQL in production services as an alternative to a rest endpoint (which I didn't care for) and I don't think sheer the nature of the validations ever caused that much slow down or rather, more plainly put that GraphQLs design would not necessarily cause such poor performance on such a small set of data.
/shrug I dunno, if this were me, I'd just assume I had written a bad query or validation somewhere. And to be fair to the author, they only made a post on twitter to reflect on their problem, not to say GQL has a dark side (at least from what I read in the thread).
[1] We all have made programmer errors, are likely making some "now," and will for sure make more in the future. No reason to feel bad about it, we're all human :) Mistakes are just a part of life no matter how "good" at things we are.
[+] [-] staticassertion|6 years ago|reply
'Slow response times for large documents'
https://github.com/graphql/graphql-js/issues/723#issuecommen...
It seems that the graphql library is performing a lot of validation, and that's slowing things down. I expect validation to be a pure-compute task, and this is Javascript, so I suspect this is really a "working with large amounts of data in Javascript is slow" issue - but that's just at a glance.
[+] [-] m_ke|6 years ago|reply
I've ran into similar issues with FastAPI and DRF when dealing with really large payloads.
[+] [-] ex3ndr|6 years ago|reply
We had something like this in our backend, but this long times is usually meant that something wastes event loop and just blocks everything from execution.
It could be anything for example it could be async hooks that makes ~1000 times slower if you are using a lot of promises (since resolving fields often are just promises) since overhead is per promise. In general in latest nodejs you can do huge amount of promises and they have little to no overhead, but, again - something wrong with nodejs setup, some library populate event loop or something deeper in nodejs internals. It is not an issue with gql itself since if you have gql performance issues that means that your server is super slow in processing like anything. Our team was shocked by performance and it turns out that NodeJS is super fast and it is some libraries (like sequelize) that kills the performance, but gql is not one of them.
[+] [-] hamandcheese|6 years ago|reply
[+] [-] mattbillenstein|6 years ago|reply
[+] [-] addityasingh|6 years ago|reply
[+] [-] gsvclass|6 years ago|reply
[+] [-] dclowd9901|6 years ago|reply
Like react, it eschews performance for the sake of enterprise level scaling. This shouldn’t come as a surprise to anyone, being both of these came from one of the largest dev organizations in the world.
[+] [-] nbardy|6 years ago|reply
[+] [-] toomim|6 years ago|reply
That's strange, because I thought the main selling point was to consume only the data you need. The client specifies exactly which fields it wants. Then it doesn't over-fetch. To make things higher performance.
[+] [-] spamizbad|6 years ago|reply
[+] [-] tuananh|6 years ago|reply
[+] [-] ggmartins|6 years ago|reply
[+] [-] coding123|6 years ago|reply
[+] [-] fastest963|6 years ago|reply
[+] [-] shantly|6 years ago|reply
I'd love an explanation for why you'd think this to be generally true, and for any category.