Vercel has recently launched Fluid Compute. It brings costs down and make serverless/edge functions faster by reducing cold start.
But you may find that it breaks your app in a very unexpected way:
This week I've been working on a project where we've had Firebase/GCP Cloud Functions calling API endpoints on a Next.js project deployed to Vercel. If the previous sentence sounds odd and suspicions, then well, that's why this chapter is called 'Story from the trenches' 😂.
Occasionally, the Cloud Functions would fail because the Vercel endpoint would return 405 method unallowed
. That was odd as hell because other requests were succeeding and they were sent almost at the same time.
Upon investigation I've noticed that there were logs for the endpoint in question saying the following:
Node.js process exited with exit status: 1.
The logs above can help with debugging the issue.
While contiuning investigation, I decided to reach out the Vercel support. The behaviour of the system was really suspicous, so why not reach to support while keep digging myself?
The guys were from Vercel were really helpful and helped to point out that:
On traditional serverless compute, the isolation boundary refers to the separation of individual instances of a function to ensure they don't interfere with each other. This provides a secure execution environment for each function.
...
Fluid compute uses a different approach to isolation. Instead of using a microVM for each function invocation, multiple invocations can share the same physical instance (a global state/process) concurrently. This allows functions to share resources and execute in the same environment, which can improve performance and reduce costs.
This helps to reduce costs and cold starts, but it removes isolations between different functions. So anything that leads to a process termination in one function can kill another one.
And that's what what was happening in my case!
Why did we have an unhandled exception in the first place?
Actually, we were throwing that exception ourselves. Loosely speaking the code was like this:
const item = await fetchItem();
if (!item) {
console.error('No item found');
throw Error('No item found');
}
res.send(item);
It didn't seem like there was a massive reason to handle it. We were logging an error. And the endpoint was returning 500
anyway.
However in Next.js 13 (and possibly previous versions) deployed to Vercel such unhandled exceptions result in process.exit(1)
.
Well, there are multiple ways to fix that:
Well, the last one is a nuclear options, but the first two should definitenely be done.
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way. My personal thoughts tend to change, hence the articles in this blog might not provide an accurate reflection of my present standpoint.
© Mike Borozdin