Slow queries with Prisma + Nexus + GraphQL on Vercel due to lambda cold starts
See original GitHub issueBug description
My Next.js app is deployed to Vercel and uses a lambda route for a GraphQL server (apollo-server-micro) that is configured with Prisma + Nexus. Lambda cold starts on Vercel lead to slow queries that take approximately 7 seconds.
I have reproduced the issue on simple example that shows cold start times of approximately 2,5 seconds. I have not managed to find the influencing factors, but Prisma + Nexus (and the resulting function size) seems to play a role. Here is the deploy output for the serverless functions:
00:04:49.070 | Serverless function size info
-- | --
00:04:49.071 | Serverless Function's page: api/graphql.js
00:04:49.074 | Large Dependencies Uncompressed size Compressed size
00:04:49.074 | node_modules/.prisma/client 47 MB 16.4 MB
00:04:49.074 | node_modules/prettier/parser-typescript.js 3.18 MB 817 kB
00:04:49.074 | node_modules/prettier/index.js 1.72 MB 396 kB
00:04:49.074 | node_modules/prettier/parser-flow.js 3.11 MB 310 kB
00:04:49.074 | node_modules/@prisma/client 1.17 MB 243 kB
00:04:49.074 | node_modules/busboy/deps 618 kB 196 kB
00:04:49.075 | node_modules/micro/node_modules 360 kB 190 kB
00:04:49.075 | node_modules/encoding/node_modules 329 kB 179 kB
00:04:49.075 | node_modules/lodash/lodash.js 544 kB 96.4 kB
00:04:49.075 | All dependencies 63.5 MB 20.2 MB
00:04:49.163 | Created all serverless functions in: 43.168s
I see the cold starts after approx. 10 minutes inactivity, but that could vary.
I put some simple timestamps into the app, both on the client and the server. From those timestamps, you can see that in the case of a cold start the total query time is governed by the waiting time between query initiation and endpoint function invocation (start request
- before fetching
). Only Vercel would be able to debug further into what happens exactly within this time-span.
Some screenshots from the example:
How to reproduce
- Clone project lambda-cold-start and deploy to Vercel
- You can inspect it right away under https://lambda-cold-start.vercel.app (but better deploy yourself, so you can control the inactivity).
Expected behavior
I know that cold starts cannot be fully eliminated, but cold start times of 2 - 7 seconds are a problem for me. I can accept cold start time of roughly 1 second. Thus, I expect the follwoing help from this issue:
- Understand the role Prisma + Nexus plays in building up long cold starts
- Understand the influencing factors (hopefully something can improved)
- Based on the analysis, maybe some ideas for viable remedies (warm-up strategies).
I will also open an issue @Vercel, so hopefully their infra team can also give some insight.
Prisma information
You can find package.json
and prisma schema on the linked repo. Note that the example takes out any calls to the database (all prisma queries are taken out the the GraphQL resolvers). This is to show that we are indeed dealing with a cold start issue and not database latency.
Environment & setup
- Issue only exists when deployed to Vercel
- Also tried to deploy to Netlify but got build errors I was not able to fix (any hints welcome).
Prisma Version
prisma : 2.23.0
@prisma/client : 2.23.0
Issue Analytics
- State:
- Created 2 years ago
- Comments:12 (6 by maintainers)
Top GitHub Comments
@janpio Thanks so much for looking into the issue.
I will make some more tests with adding/removing dependencies along the same lines as you did. If only 0.4 seconds can be attributed to Prisma + Nexus, then this would be acceptable. What still doesn’t add up for me:
Your tests of my reproduction example only show 1.7 sec cold start times vs 2.5 secs which I get consistently: This is already a 0.8 secs difference
I haven’t quite managed to replicate my prod example where I see 7 secs cold starts, so I expect Prisma + Nexus footprint to be larger in real world examples, but I have to show that to you, I know.
Thanks for pointing out Nexus and @nexus/schema deps, I will look into that too.
Can do. We will still try to improve this of course.
One possible aventua: Can you please try the
nApi
preview documented at https://prisma.io/docs/concepts/components/prisma-engines/query-engine#enable-the-n-api-preview with latest version2.24.1
(Runprisma generate
after you enable the flag in your schema.)? This should not really influence the startup time, but seeing results with Node API integration which doesn’t spawn the query engine binary would be interesting still.