graphql-shield: Performance degradation after applying graphql-shield
Bug report
- I have checked other issues to make sure this is not a duplicate.
Describe the bug
Querying multiple fields for hundreds of rows becomes noticeably slower after applying graphql-shield middleware.
To Reproduce
I’ve created repository reproducing this issue: https://github.com/lynxtaa/graphql-shield-performance
- Without
graphlql-shieldit takes 30-40ms to query all users. - With
graphql-shieldit takes ~260ms.
Notice that I’m not applying any rules for type User.
Is there a way to improve performance for large queries?
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 19 (10 by maintainers)
@maticzav @lynxtaa I tried to do a bit more experimenting with profiling and looking at the garbage collection patterns. I’m no expert in either of these topics but I’m hoping what I found helps. I added a repo here to do the testing.
I setup a GraphQL server running on Express with a basic GraphQL schema that returns a list of
Movieswith 8 attributes. For the tests I randomly generated 100 movies to be returned in the GQL query. I used a resolver that pauses by10sthen returns (my attempt at poor man’s request queueing).I used
vegetato do some load testing. When I tried doing350req/sfor1mI noticed that when Shield was applied, there was twice as much garbage collection as when Shield middleware wasn’t there. I showed the results in the README of the project. Also, it would run out of memory ever so often when Shield was applied.Finally, I used the
v8-profiler-nextto profile the system under load. I looked at the profiles in Chrome’s Javascript Profiler but not too much jumped out at me.This profile shows running
350req/swith the10s. Then I changed the resolver to return after3sand recorded the results with Shield and without Shield. One caveat is that I had to stop the load testing early for Shield so that the NodeJS process didn’t quit on me. I needed to save the profile.From the little I gleaned from the profiles, it confirms that the garbage collection takes longer. Compare with Shield…
To without Shield…
Hope this helps!
@maticzav I think it has something to do with typescript compilation of async functions. After some experimenting I’ve compiled graphql-shield with target:
ESNextintsconfig.jsonand the performance is much better: it takes 108ms on first call, then 59ms on second call.Can you consider dropping Node 6 support and start compiling to
es2017?Thank you both for such profound insights on the performance. I am away for a vacation and will return on Tuesday.