#reduce function invocations

1 messages · Page 1 of 1 (latest)

torn inlet
#

Currently, majority of my requests are made on the client user server actions for GET. my app has only existed for a month and i've used 1.2million function invocations. how can i reduce these? (using next.js v14 app router)

knotty zodiacBOT
#

Hi @torn inlet. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

There are several strategies you can use to reduce function invocations in your Next.js application:

  1. Caching: You can cache your responses using edge caching and Cache-Control headers. This can help reduce the number of invocations that your functions receive and makes responses faster for users. In your Next.js application, you can fetch and tag your data with a cache key. The response from fetch will be cached and not re-fetched on the next deployment. To revalidate the data and purge the cache, you can use revalidateTag (source (https://vercel.com/guides/share-vercel-cache-across-deployments-nextjs#example)).
// Fetch and tag your data with a cache key
async function Blog() {  
  const res = await fetch('<https://api.vercel.app/blog',> {    
    next: { tags: ['blogs'] }  
  });  
  const blogs = await res.json();   
  return '...';
}

// Revalidate the data and purge the cache
'use server' 
import { revalidateTag } from 'next/cache' 
export default async function action() {  
  revalidateTag('blogs')
}
  1. Incremental Static Regeneration (ISR): If 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 (source (https://vercel.com/guides/how-can-i-reduce-my-serverless-execution-usage-on-vercel#incremental-static-regeneration)).
#
// `app` directory
 
async function getPosts() {
  const res = await fetch(`<https://.../posts`,> { next: { revalidate: 60 } })
  const data = await res.json()
 
  return data.posts
}
 
export default async function PostList() {
  const posts = await getPosts()
 
  return posts.map((post) => <div>{post.name}</div>)
}
  1. Static Site Generation (SSG): If your page can use SSG instead of Server-Side Rendering (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 (source (https://vercel.com/guides/how-can-i-reduce-my-serverless-execution-usage-on-vercel#static-site-generation)).

  2. Optimizing Function Invocations: Use the Projects option to see the total number of invocations for each project within your team. This can help you identify which projects are using the most invocations and where you can optimize (source (https://vercel.com/docs/pricing/edge-functions#managing-functions-invocations)).

Remember to always monitor your function invocations and adjust your strategies as needed.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@torn inlet Kapa.ai is still learning and improving, please let me know how I did by reacting below.

torn inlet
#

@knotty zodiac caching the fetch wont do much if you've already called the server action, therefore making a function invocation. im using this on the client using react-query

knotty zodiacBOT
#

Let me check the knowledge base for you again. Give me one moment! :books:

#

You're correct that caching the fetch response won't prevent the initial server action invocation. However, it can significantly reduce the number of invocations over time by serving cached responses for subsequent requests, instead of invoking the server action each time.

Since you're using react-query, you can leverage its caching and automatic background updates features to minimize unnecessary server action invocations. Here's how you can do it:

  1. Caching: By default, react-query caches the data fetched by your queries. This means that if you try to fetch the same data again (using the same query key), react-query will first return the cached data and then run the fetch function in the background to update the cache.

  2. Automatic Background Updates: react-query automatically refetches your queries in the background when you refocus your app or reconnect to the internet. You can control this behavior using the refetchOnWindowFocus and refetchOnReconnect options.

  3. Stale Time and Cache Time: You can configure how long react-query should consider data fresh (and not refetch it) using the staleTime option. Similarly, you can control how long inactive data should be kept in the cache using the cacheTime option.

Here's an example of how you can use these features:

import { useQuery } from 'react-query'

function MyComponent() {
  const { isLoading, error, data } = useQuery('todos', fetchTodoList, {
    staleTime: 1000 * 60 * 5, // data is fresh for 5 minutes
    cacheTime: 1000 * 60 * 30, // data is deleted from cache after 30 minutes
    refetchOnWindowFocus: false,
  })

  // ...
}

In this example, react-query will only invoke fetchTodoList if there's no fresh data in the cache. This can significantly reduce the number of server action invocations in your app.