> This page is for Developer.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.bigcommerce.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.bigcommerce.com/_mcp/server.

# Protect a Vercel Storefront from Traffic Spikes

> Prepare a Catalyst storefront hosted on Vercel for high-demand product launches and bot traffic with Vercel bot protection, rate limiting, BotID, and caching.

When you launch something people really want, such as a limited-edition drop, a flash sale, or a restock, bots show up alongside your shoppers. They refresh product pages, fill carts, and start checkouts much faster than any person can. All of that traffic reaches your Vercel deployment first, and a lot of it turns into requests to BigCommerce.

This guide covers the Vercel settings and the small code changes in your Catalyst project that keep that traffic from taking your storefront down. It's worth setting these up before your next launch, not during it.

> **Info**
>
> This guide is for Catalyst storefronts hosted on Vercel. [Storefront Hosting](/developer/docs/storefront/catalyst/deployment/storefront-hosting/overview) runs on BigCommerce infrastructure and doesn't use these settings.

## How a Catalyst storefront handles traffic

Catalyst reads cookies on every route under `[locale]`, which means pages render on demand. Each page request runs a Vercel Function, because the CDN doesn't have a stored copy to serve.

Data is a different story. Catalyst caches anonymous catalog queries in the [Data Cache](/developer/docs/storefront/catalyst/development/caching#data-cache) for `DEFAULT_REVALIDATE_TARGET` seconds, which is 3,600 unless you change it. Variant inventory is the exception and revalidates every 60 seconds. Cart updates, signed-in requests, and form submissions skip the cache and go straight to BigCommerce.

With that in mind, carts, sign-in, registration, search, and checkout are the routes that need the most protection.

## Enable bot protection

Vercel's bot protection ruleset challenges traffic that doesn't behave like a browser, and it lets [verified bots](https://vercel.com/docs/bot-management#verified-bots) such as Googlebot through. It's available on every plan, but it's off until you turn it on.

1. In the Vercel dashboard, open your project and go to **Firewall > Rules**.
2. Under **Bot Management**, set **Bot Protection** to **Log**. Select **Review Changes**, then **Publish**.
3. Look at **Firewall > Traffic** to see what was flagged. If it looks like automation, switch to **Challenge** and publish again.

Start in **Log** mode well before the launch. A flagged request isn't always a bot, and a few days of logs will show you whether your uptime monitors or partner integrations would get caught. If a trusted client does get challenged, add a [custom rule with a bypass action](https://vercel.com/docs/vercel-firewall/firewall-concepts#bypass) for it. Keep a rate limit on that traffic too, since user agents are easy to fake.

The **AI Bots** ruleset in the same section can log or deny AI crawlers. Denying it also blocks AI agents that shop on behalf of your customers, so decide whether you want that traffic before you turn it on.

## Rate limit expensive routes

Bot protection catches clients that don't act like browsers. A script that drives a real browser gets past it, so you also need [rate limits](https://vercel.com/docs/vercel-firewall/vercel-waf/rate-limiting) on the routes that cost the most. Here's what to cover:

| Route                  | Why it matters                                                                                                                                                                                                 |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Product pages (`POST`) | Add to cart is a Server Action, which is a `POST` to the URL of the page that holds the form. Product URLs come from your catalog, so there's no fixed path to match. Every call reaches BigCommerce uncached. |
| `/cart` (`POST`)       | Quantity, coupon, and shipping updates are uncached Server Actions.                                                                                                                                            |
| `/checkout`            | Each request calls a BigCommerce mutation to create the hosted checkout redirect URL.                                                                                                                          |
| `/login`, `/register`  | Uncached, and a common target for credential stuffing.                                                                                                                                                         |
| `/search`              | Queries vary too much to cache well.                                                                                                                                                                           |
| `/graphql`             | Carries wallet requests from the BigCommerce checkout SDK.                                                                                                                                                     |

To create a rule, open the **Firewall** overview page, select **Configure**, then **+ New Rule**.

1. Add **If** conditions that match the route. For Server Actions, match the `POST` method and the `Next-Action` request header. If you use locale prefixes, such as `/fr/cart`, the path condition needs to match the prefixed URL too.
2. Set **Then** to **Rate Limit**. Choose a **Time Window** and **Request Limit** that a real shopper won't reach, and key the limit on IP address.
3. Keep the default `429` response. You can pick **Log** at first to see what the rule would catch.
4. Select **Save Rule**, then **Review Changes** and **Publish**.

Keep a couple of limitations in mind. Vercel counts requests per region, so a source that spreads its traffic across regions can get past your limit. The number of rules, the counting keys, and the window lengths also depend on your plan.

If you test a rule with `curl`, bot protection may answer with a challenge instead of a `429`. Test from a browser session, or set Bot Protection to **Log** while you test.

## Verify high-value actions with BotID

[BotID](https://vercel.com/docs/botid) is an invisible check that tells people from automation without showing a CAPTCHA. Basic checks work on every plan. Deep Analysis costs extra and is available on Pro and Enterprise plans.

BotID has a client half and a server half, and you need both. If a Server Action calls `checkBotId()` for a route the client hasn't registered, the check fails.

Start by installing the package:

```bash showLineNumbers={false}
pnpm add botid
```

Next, create `instrumentation-client.ts` at the project root. This file is separate from `instrumentation.ts`, which sets up OpenTelemetry. List the pages that host the actions you want to protect:

**`instrumentation-client.ts`**

```ts title="instrumentation-client.ts" showLineNumbers={false}
import { initBotId } from 'botid/client/core';

initBotId({
  protect: [
    // Pages that host Server Actions, such as add to cart on product pages.
    { path: '/*', method: 'POST' },
  ],
});
```

Then call `checkBotId()` at the top of each Server Action you want to protect. This example goes in `app/[locale]/(default)/product/[slug]/_actions/add-to-cart.tsx`:

**`add-to-cart.tsx`**

```ts title="add-to-cart.tsx" showLineNumbers={false}
import { checkBotId } from 'botid/server';

export const addToCart = async (prevState: State, payload: FormData) => {
  const verification = await checkBotId();

  if (verification.isBot) {
    return {
      lastResult: { status: 'error', error: { '': ['Request blocked.'] } },
      fields: prevState.fields,
    };
  }

  // ...existing action code
};
```

After you redeploy, check **Firewall** for BotID events.

In local development, `checkBotId()` always reports `isBot: false`. In production, BotID blocks `curl` and direct visits to protected routes, so test with a `fetch` call from a page in your storefront. The [BotID getting started guide](https://vercel.com/docs/botid/get-started) covers the remaining options.

## Reduce load on BigCommerce

Every request you can answer without calling BigCommerce helps, so a few changes are worth making:

* **Turn on reCAPTCHA** in the BigCommerce control panel. Catalyst supports it on registration, product reviews, and the contact form, and it picks up the setting from your store without code changes.
* **Leave `DEFAULT_REVALIDATE_TARGET` alone before a launch.** Lower values send more requests to BigCommerce. A value of 1 to 24 hours works for high-traffic stores, depending on how often your catalog changes. See [Set the cache duration](/developer/docs/storefront/catalyst/development/caching#set-the-cache-duration).
* **Cache your own queries for guests.** Skip the cache only for signed-in customers, as shown in [Cache your own requests](/developer/docs/storefront/catalyst/development/caching#cache-your-own-requests).
* **Don't poll from the browser.** Refreshing inventory or price from client code adds traffic for every open tab.

## Serve the storefront directly from Vercel

If you have a proxy or CDN in front of Vercel, such as Cloudflare, bot protection loses the signals it depends on. Real shoppers get challenged repeatedly, detection becomes less accurate, and IP-based rate limits can't see the real client IP. A **Limited** status in **Firewall** usually means a proxy is hiding request data.

Vercel recommends against using a reverse proxy. If your organization requires one, Verified Proxy restores the client IP for supported providers, including Cloudflare, Fastly, and AWS CloudFront. Self-hosted proxies need an Enterprise plan. See [Reverse Proxy Servers and Vercel](https://vercel.com/docs/security/reverse-proxy).

## Test and monitor

Coordinate load tests with Vercel before you generate significant load. Add bypass rules scoped to your test source IPs, because unannounced tests can be treated as an attack and blocked. Tests that need 50,000 or more requests per second require a ticket with Vercel's engineering team. See Vercel's [load testing guide](https://vercel.com/kb/guide/how-to-effectively-load-test-your-vercel-application). Run the test against a preview deployment and ramp up gradually. Function concurrency grows in steps per region, so a surge that jumps straight to peak can return `503 FUNCTION_THROTTLED`.

If you expect traffic well above your normal peak, let BigCommerce know ahead of time through your account team or [BigCommerce Support](https://support.bigcommerce.com). Don't load test your production store's APIs without talking to them first.

During the launch, here's where to look:

* **Firewall > Traffic** shows what's being allowed, challenged, denied, and rate limited.
* **Observability** shows function concurrency, duration, errors, and requests by hostname. If requests to your BigCommerce GraphQL hostname climb faster than page views, uncached traffic is getting through.
* [Drains](https://vercel.com/docs/drains), on Pro and Enterprise plans, send logs to your alerting tools.

[Spend Management](https://vercel.com/docs/spend-management), on Pro and Enterprise plans, can notify you or call a webhook when spend reaches a budget. It can also pause production deployments. That takes the whole storefront offline with a `503 DEPLOYMENT_PAUSED` until you resume each project by hand, and because spend is only checked every few minutes, usage can keep running briefly past the budget. Decide before the launch which behavior you want.

## If traffic overwhelms the storefront

If it happens anyway, work through these steps in order:

1. Move **Bot Protection** to **Challenge**.
2. In **Firewall > Traffic**, look for the IP addresses, regions, and user agents that dominate, and deny or rate limit them with new rules.
3. Turn on [Attack Mode](https://vercel.com/docs/vercel-firewall/attack-mode) under **Firewall > Bot Management**. It's free on every plan and lets verified bots through, but real shoppers get the challenge too, so turn it off once things calm down.
4. If BigCommerce API requests start failing with rate limit errors, cut uncached traffic first, then contact BigCommerce Support.

## Summary

To get ready for a launch, turn on bot protection in log mode and move it to challenge, rate limit the routes that reach BigCommerce uncached, add BotID to your add-to-cart action, and leave your caching alone. Then coordinate any load testing with Vercel, and tell BigCommerce what's coming. For more on the Firewall features, see Vercel's [bot management documentation](https://vercel.com/docs/bot-management) and [bot management guide](https://vercel.com/kb/guide/how-to-utilize-vercels-bot-management-features). To learn how Catalyst caches data, see [Caching](/developer/docs/storefront/catalyst/development/caching).