[Support Guide] Why is my function taking long or timing out?

In this guide, we’ll be talking about synchronous functions. We won’t be covering Edge Functions or Background Functions since those are not bound by the same limits as standard synchronous functions or Scheduled Functions are.

Netlify Functions are a core feature of our product. By delegating your server-side logic to them, you leverage serverless functions that are version-controlled, built, and deployed along with the rest of your Netlify site.

However, there are some limitations on function execution, with the 10 second execution limit being one of the most critical factors to have in mind when designing your serverless code.

Function crashing

If your function takes longer than the allowed execution time, you’ll most likely be presented with this message:

That would be the error displayed when you directly visit the function URL. However, if you’re calling the function from your frontend using APIs like fetch or libraries like axios, you most likely won’t see this page. In that case, you’d have to check the dev tools in your browser and inspect the Network tab to check for that request. You could then see the above message in the “Response” tab.

Let’s dive into a few scenarios where this happens and how we can take the first steps towards mitigating them…

Everything was running smooth… What happened?

Your site was running fine and everything working great. You’re already thinking about the next cool feature to roll out when you notice that someone DM’s you :this: that :this: screenshot from your production site.

Well this is strange! That isn’t supposed to happen. First thing you do is open your site immediately and try to reproduce the case…

… but it’s working fine now :thinking:

Why am I not able to replicate this? Why is it only happening sometimes?

Typically reasons for this issue may include, but are not limited to:

  • Your code is taking longer to execute due to some condition we (or even you for that matter) cannot predict or control (e.g. slow third-party API response);
  • Your code may have been running at its limit before (near the limit of execution time) and all it took was a small delay to cause the failure. Maybe your code is not optimized enough or is too complex for a one function to handle.
  • Your code does not reliably exit - perhaps you have a code path that will never complete somewhere in your function?

My function never worked! It’s always timing out! What is wrong?

You’re excited on making your first step towards the future of web development. You’re either starting a new project or thinking about migrating an existing site over to Netlify but are already running into some roadblocks along the way.

No worries, we’re here to help. You’ve set up your Netlify Function properly and followed every instruction “by the book” but your code is still timing out.

Typically reasons for this issue may include, but are not limited to:

  • Guess what? Basically the same as above. Maybe slightly different but the root cause is most likely related to the same causes (slow APIs, extensive code, etc.)

My site uses a framework such as Gatsby or Nextjs. What is happening?!

Gatsby related functions

To support Gatsby Functions and SSR/DSG render modes, the Essential Gatsby build plugin automatically generates Netlify Functions called __api , __ssr , __dsg , and __ipx.

If you are using Gatsby version >=5.12.0 , gatsby-adapter-netlify will be installed automatically, and provide support for Gatsby Functions.

Next.js related functions

When using the Essential Next.js Build Plugin, it creates three Netlify functions that handle requests that haven’t been pre-rendered. These are ___netlify-handler (for SSR and API routes), ___netlify-odb-handler (for ISR and fallback routes), and _ipx (for images).

So… What’s happening?

If the function that is timing out is one of the framework-related ones, it’ll probably boil down to the same reasons. However, these functions have additional logic to sustain their execution that uses part of the allowed execution time.

How to mitigate all scenarios

Take a closer look at your code.

Is it relying on any third-party service? Is that service working properly (might be a good thing to check their statuspage or logs)? Presumably, running the function locally will show the same behavior around the speed of API calls/responses so you can more easily debug.

If you have a framework-related function, is it timing out only for a particular page request? If so, what makes this page different than the others?

Try breaking-down your function into smaller parts. Instead of making 10 requests in the same API call, try splitting it into 2 functions with 5 calls each. Or, consider doing the “synchronous” part of the work in a function (verify credit card here), and the asynchronous part (place order with warehouse here) in a background function, which can run for up to 15 minutes. Note that you can call a background function from a normal function; it will not block the primary function’s execution.

Sometimes, region also makes a difference. Netlify Functions, by default run in us-east-1 (N. Virginia) region. So, if you are making API calls to services who have their servers located in the other end of the world, the responses will take longer. If you have a Pro or higher account, our staff can adjust the region of your functions for you per site or account wide to most AWS regions that are capable of running lambdas.

A few times, you might be missing something simple. You might have made all the necessary optimizations, but missing the final return statement to actually send the response back to the client. For example:

export async function handler(event, context) {
  const data = await doStuff()
  return {
    body: JSON.stringify(data)
    statusCode: 200
  }
}

In the above example, if you’re missing the return statement, the function will execute the doStuff() function and keep on waiting forever even after successfully retrieving data from that function. Your Function code might not always be this simple, so you might need to make sure that your Function is actually firing the return statement at the correct time.

Logging execution time

The best way to see how long your Function is taking for a particular task is by logging its execution time. The best way to do that is by using console.time(). Here’s an example:

export async function handler(event, context) {
  console.time('doStuff')
  const data = await doStuff()
  console.timeEnd('doStuff')
  return {
    body: JSON.stringify(data)
    statusCode: 200
  }
}

In your Function console, you’d see something like: doStuff: # seconds. This will show how long your doStuff() call took. Again, depending on your Function code - for instance if it is using features like async/await statements, Promises, etc. you might have to adapt the above to correctly calculate those timings.

Once you know what piece of code is acting as a bottleneck in your Function, you can work on changing that.

4 Likes

Hey @gualter , we’re facing this same issue with our Next.js app as well, but ours takes longer – ~18-22 seconds on pages with SSR. It’s important to note, that this does not happen everytime, it only happens after some stale time. We’ve reached to Netlify support, and told us it’s something on our end. My experiment, however, says something different.

Note: We don’t have any complex logic in any of the SSR functions. And even if we have an SSR function where we just return static data, we still have that ~18 seconds TTFB.

What I did:

  • Add logging to SSR function, and the whole SSR func only runs for about 200 ms.
  • Deployed the same app to Heroku, and the SSR func in Heroku also runs for 200ms.
  • In netlify, after some stale time, TTFB is ~18 seconds. SSR execution ~200ms.
  • In heroku, TTFB is ~1-3 seconds. SSR exectuion ~200ms.

If it’s on our end, wouldn’t we experience something similar with Heroku as well? Or are we just missing something? Thanks a lot!

Hi thanks for writing into our Forums! :+1:t6: I see we are working with you in our helpdesk. Please refer to ticket # 229087