Next.js Tutorials · Tutorial · React Development Tips

How I Made My Next.js App Resilient After Vercel's API Fetching Time Limits

Sandipan Das
Sandipan Das · full-stack developer, Kolkata, IndiaPublished · Updated · 5 min read
How I Made My Next.js App Resilient After Vercel's API Fetching Time Limits — cover image

A few months ago I was working on a Next.js project for a client, well before Vercel's API fetching time limits became my problem. Everything was going smoothly — pages were loading fast, data arrived when it was supposed to, and my API calls were rock solid. Or so I thought.

One morning, I woke up to a frantic message:

"Hey! The app isn’t loading data properly. It’s just… blank. Clients are complaining. Please check it ASAP!"

That’s when the nightmare started.

The Root of the Problem: API Fetching Time Limits

After digging into the logs, I noticed several API calls failed due to intermittent server issues. Usually, these calls would self-correct after a page refresh or two, but this time, they weren't.

What made things worse? Vercel had recently introduced stricter time limits on API requests. You were out of luck if your API call didn't return within a specific window. Boom. Failure. No retries, no second chances.

And, of course, this happened on the day the API I was using was acting up.

The "Aha!" Moment

I knew I couldn't keep relying on a "hope-it-works" strategy. I needed a way to make my API calls more resilient. What if, instead of immediately failing when an API call hit a bump, my app could pause, retry, and try again?

That's when the idea for fetchWithRetry was born—a simple function that would give my app the power to recover from transient API failures without breaking a sweat.

Building fetchWithRetry: A Resilient API Fetcher

I sat down, brewed a strong cup of coffee, and got to work. My mission? To create a function that could:

  1. Retry failed API calls a specific number of times.
  2. Wait a few seconds between retries to give the server a chance to recover.
  3. Throw an error only after all retries have been exhausted.

After a few hours of tinkering, I had this:

const fetchWithRetry = async (
    fetchFunction: () => Promise<any>,
    maxRetries: number = 3,
    delay: number = 4000
): Promise<any> => {
    let retries = maxRetries;
    while (retries > 0) {
        try {
            return await fetchFunction(); // Try the API call
        } catch (error) {
            retries -= 1; // Reduce the retry count
            if (retries === 0) {
                // All retries failed
                throw new Error("Failed to fetch data after multiple retries.");
            }
            console.warn(
                `Fetch failed. Retrying... (${maxRetries - retries}/${maxRetries})`
            );
            // Wait before retrying
            await new Promise((resolve) => setTimeout(resolve, delay));
        }
    }
};
export { fetchWithRetry };


How It Saved My App

I plugged this function into my Next.js project. The first test was in getServerSideProps, where the app fetched data for server-side rendering.

The New getServerSideProps

import { fetchWithRetry } from "./utils/fetchWithRetry";


export const getServerSideProps = async () => {
    try {
        const data = await fetchWithRetry(async () => {
            const res = await fetch("https://api.example.com/data");
            if (!res.ok) throw new Error("Failed to fetch");
            return res.json();
        });
        return { props: { data } };
    } catch (error) {
        console.error("Error fetching data:", error.message);
        return { props: { data: null } };
    }
};

The difference was night and day. If an API call fails once, the app will try again. And again. And—if necessary—a third time. The data loaded without a hitch if the server recovered within those attempts. There are no blank screens. No angry clients.

A Real-Life Scenario

Let me walk you through how this works in practice.

Imagine your app calls an API to fetch weather data for a user's location. The API server might return an error or timeout on a bad day due to high traffic. Without retry logic, your app would fail immediately, leaving users stuck.

With fetchWithRetry, here's what happens:

  1. First Attempt: The app makes the API call. The server is unresponsive—result: Retry #1.
  2. Second Attempt: The server is still struggling, but it's starting to recover—result: Retry #2.
  3. Third Attempt: The server responds successfully, and the app loads the data. Result: Problem solved without the user noticing a thing.

Lessons Learned

Here's what I realised after implementing fetchWithRetry:

  1. Retry Logic is Essential; downtime or missing data can impact your users in production apps.
  2. Delays Make a Difference: Giving the server a moment to recover often resolves transient failures.
  3. Exponential Backoff is Next-Level: For even better results, you can increase the delay with each retry (e.g., 2 seconds, then 4 seconds, then 8 seconds).

What I would change before you copy it

Two things, and the first one matters more than the retry count:

  • Do not retry every error. As written it retries anything that throws — including a missing page or a rejected key, which will fail identically three times and just make the user wait. Retry the transient cases: a timeout, a refused connection, a server-side failure. Return the rest immediately.
  • Fixed delays are a blunt instrument. A constant wait is fine for one flaky call and bad for many at once, because they all retry together. Increasing the delay each round spreads them out.

Retries hide the symptom. If a call needs three attempts every time, the retry is not the fix — it is the alarm telling you where to look.

The Payoff

Thanks to this simple function, my Next.js app became much more resilient. The blank screens disappeared, my client was happy, and I could finally sleep at night knowing my app could handle hiccups gracefully.

If you're building a Next.js app and you're worried about API failures—especially with Vercel's time limits—give fetchWithRetry a try. It might just save you a frantic call from your client one day.

Final Thoughts

Have you ever faced challenges with API failures in your apps? Share your story with me by scheduling a meeting, and let's talk about how we can build stronger, more reliable applications together. 🚀

Questions

Questions this post answers

What do Vercel's API fetching time limits actually do to a request?

If your API call does not return within a specific window it fails, with no retries and no second chances. Calls that used to self-correct after a page refresh or two stop doing so.

Should fetchWithRetry retry every failed call?

No, and this matters more than the retry count. As written it retries anything that throws — including a missing page or a rejected key, which will fail identically three times and just make the user wait. Retry the transient cases: a timeout, a refused connection, a server-side failure. Return the rest immediately.

Is a fixed delay between retries good enough?

A constant wait is fine for one flaky call and bad for many at once, because they all retry together. Increasing the delay each round spreads them out.

If retries fix the blank screens, is the problem solved?

Not really. If a call needs three attempts every time, the retry is not the fix — it is the alarm telling you where to look.

Share:X·LinkedIn·Email

Related

  • Article

    ISR in Next.js: The Perfect SEO & Performance Strategy

    ISR in Next.js came out of a project I was working on once — a dynamic blog where content was king. It had great design, engaging posts, and an audience hungry for fresh updates. But something wasn’t right. I noticed…

    · 3 min read · by Sandipan Das
  • Next.js Tutorials

    Fix typescript error: Unexpected any and empty object issues

    To fix typescript error messages on a new project, start here. Two ESLint errors show up on every fresh Next.js and TypeScript project: Unexpected any , and the warning that {} allows any non-nullish value. Both come from next/typescript .…

    · 2 min read · by Sandipan Das
  • React Development Tips

    SHIFT + ENTER in React Quill to create a new line 100% working

    Shift + Enter in React Quill does not give you a plain line break out of the box — press Enter and you get a whole new paragraph instead. This post shows how to rebind it: disable the default Enter…

    · 3 min read · by Sandipan Das

If you'd rather not do it yourself

Everything above works. You just need the time for it.

Follow the steps and fix it yourself. Or send the site to the team and get on with your day.

900+ projects completed since 2017, from Kolkata, India.