Skip to content

How can I reduce my Serverless Execution usage on Vercel?

When deploying a project to Vercel, it is critical to abide by the Fair Use Policy or your Enterprise agreement (email your Customer Success Manager for further information). The Usage Dashboard is the most important page to check the usage of your projects. Another useful tool to monitor requests and detect spikes is Log Drains since it can show low-level and bulk data about Serverless Executions.

Definitions

Before we outline possible solutions for high usage of Serverless Functions, we need to define a few concepts that are relevant.

  • Serverless Invocation: When a Serverless Function is triggered by an event. Those events are typically requests that will be processed by the function.
  • Serverless Execution: The process of executing a Serverless Function, which is triggered by an invocation.
  • Serverless Function memory: The size of the memory allocated to the function. For further information, you can refer to the Configuration Reference.
  • GB-Hrs: The unit of measurement for Serverless Execution. If one function with 1024MB allocated takes one second to process a request, we can conclude it used 1GB-Seconds, which is (1/3600)GB-Hrs. For further information, check the article "What are GB-Hrs for Serverless Function Execution?" .

Tracking Usage

Vercel provides several ways to track your usage. One of them is the Usage Dashboard. You can access it by going to the homepage of your team and then clicking Usage. For a detailed overview of how to use the Usage page, go to How to Use the Usage Page.

If you need access to low-level data, you can use Log Drains to forward all Serverless Execution metrics from Vercel to the provider of your choice. As an example, with Logflare, you can setup a dashboard using Google Data Studio.

Example of usage dashboard using data from Logflare

With Next.js

Next.js is a framework that gives your team the flexibility to choose between different rendering methods:

  • Static Site Generation: When your code generates a page at build-time by using getStaticProps.
  • ISR: When you use getStaticProps and the revalidate argument to trigger a revalidation of the content being served.
  • Server-Side Rendering: When getServerSideProps is used in a page at build-time by using getStaticProps.

We will show how you can reduce your Serverless Function usage with all methods above. Even API routes can use the Vercel CDN to cache responses and serve content directly from the edge for optimal speed.

Static Site Generation

If your page can use SSG instead of SSR, it is recommended that you implement this approach to lower the usage of Serverless Executions. The page will be generated a single time at build-time, and it is not possible to regenerate it or replace its content after the build. Since your app will no longer execute a function for every page request, which is true for uncached SSR pages, the amount of Serverless Executions for pages using SSG is 0 GB-Hrs.

Incremental Static Regeneration

In case a specific page needs to be regenerated periodically due to dynamic data, you can use ISR to lower the number of Serverless Executions performed by your app. With this strategy, your pages will be statically generated and cached in the Vercel CDN. A Serverless Function will be triggered after a certain interval to refresh the content of the cache. By using ISR, you will lower the amount of Serverless Executions used by your app in comparison with uncached SSR pages. Your users will also benefit from the speed improvements that ISR will give since your deployment will serve content directly from the Vercel CDN.

CDN Caching and stale-while-revalidate

If you are unable to implement ISR or SSG, you can use caching headers to store SSR pages in the Vercel CDN. One of the best headers is stale-while-revalidate, which is used to serve stale content while the cache is refreshed in the background. You can see an example of the header being used in a Next.js SSR page below. Do notice you can also use this header for Next.js API routes. If you need to apply the header to multiple paths, using the Next.js headers configuration is also an option.

export async function getServerSideProps(context) { const res = await fetch(`https://...`) const data = await res.json() context.res.setHeader('Cache-Control', 's-maxage=600, stale-while-revalidate=30') // set caching header return { props: {}, // will be passed to the page component as props } }

A Next.js page using stale-while-revalidate.

export default function handler(req, res) {
  res.setHeader('Cache-Control', 's-maxage=600, stale-while-revalidate=30') // set caching header
  res.status(200).json({ name: 'John Doe' })
}

A Next.js API route using stale-while-revalidate.

// next.config.js module.exports = { async headers() { return [ { source: '/example/:id', headers: [ { key: 'cache-control', value: 's-maxage=600, stale-while-revalidate=30', }, ], }, ] }, }

Applying a cache-control header to a path by using the Next.js headers configuration.

In the example above we are telling the Vercel CDN the content is fresh for 600 seconds, and it may continue to be served stale for up to an additional 30 seconds while an asynchronous validation is attempted by triggering a Serverless Function. If validation is inconclusive, or if there is not traffic that triggers it, after 30 seconds the stale-while-revalidate function will cease to operate, and the cached response will be "truly" stale (i.e., the next request will block and be handled normally).

Generally, you may want to use a combination of s-maxage and stale-while-revalidate to the longest total potential freshness lifetime that they can tolerate. For example, with both set to 600, the server must be able to tolerate the response being served from cache for up to 20 minutes. Since asynchronous validation will only happen if a request occurs after the response has become stale, but before the end of the stale-wile-revalidate window, the size of that window and the likelihood of a request during it determines how likely it is that all requests will be served without delay. If the window is too small, or traffic is too sparse, some requests will fall outside of it, and block until the deployment can validate the cached response.

The text above was inspired by RFC5681.

With Serverless Functions in /api

If you are not using Next.js, you can still implement some strategies to lower the amount of resources used by your deployment.

CDN Caching and stale-while-revalidate

If your API is returning data that can be shared publicly (without authorization headers or cookies), you can use caching headers to cache the response of the function in the Vercel CDN. One header that we can highlight is stale-while-revalidate.

module.exports = (req, res) => {
  res.setHeader('Cache-Control', 's-maxage=600, stale-while-revalidate=30') // set caching header
  res.status(200).json({ name: 'John Doe' })
}

An API Serverless Function with caching headers applied.

Configuring your Serverless Functions

It is possible to customize the amount of memory used by your Serverless Functions. If your function is I/O bound and needs to wait on upstream providers often, lowering the memory size allocated to it is a good strategy to reduce the overall GB-Hrs used by your deployment. Do notice that the CPU power of your Serverless Executions is directly related to the amount of memory configured to your functions. Therefore, for processing-intensive functions, lowering the memory size is not advised.

Another important configuration is the Regions for your Serverless Functions. If you don't deploy close to upstream dependencies or providers, it is possible that the response time of your functions is being affected by latency. By deploying closer to your Database or API, you will observe that your functions will take lower to process a request, reducing your Serverless Executions usage overall.

You can read more about how to configure your functions in the Configuration Reference.

{
  "functions": {
    "api/example.js": {
      "memory": 128,
      "maxDuration": 10
    }
  }
}

A Serverless Function using 128MB of memory and timing out after 10 seconds.

Moving APIs to serverful providers

Using Vercel for API-intensive work may not be a good strategy. Depending on your workload and other variables associated with your application, hosting only the frontend on Vercel can help you reduce your Serverless Execution usage.

Couldn't find the guide you need?