---
title: "CDN Requests"
description: "Disable prefetching on Saturday's product grid and drops rows so the browser only fetches route bundles for products visitors actually open."
canonical_url: "https://vercel.com/academy/optimize-your-vercel-account/edge-requests"
md_url: "https://vercel.com/academy/optimize-your-vercel-account/edge-requests.md"
docset_id: "vercel-academy"
doc_version: "1.0"
last_updated: "2026-07-22T03:03:48.585Z"
content_type: "lesson"
course: "optimize-your-vercel-account"
course_title: "Optimize Your Vercel Account"
prerequisites:  []
---

<agent-instructions>
Vercel Academy — structured learning, not reference docs.
Lessons are sequenced.
Adapt commands to the human's actual environment (OS, package manager, shell, editor) — detect from project context or ask, don't assume.
The lesson shows one path; if the human's project diverges, adapt concepts to their setup.
Preserve the learning goal over literal steps.
Quizzes are pedagogical — engage, don't spoil.
Quiz answers are included for your reference.
</agent-instructions>

# CDN Requests

# CDN Requests

A visitor lands on Saturday's homepage. They look at the hero, scroll through the grid, click "Drops," and leave. They were on the site for fourteen seconds. In those fourteen seconds, their browser made requests for:

- The homepage HTML
- Five product page bundles, one for each card in the grid
- The drops page bundle, the only one they actually clicked

Three of those product prefetches were pure speculation. They went to product pages the visitor never looked at. Multiply that by a hundred thousand visitors on drop day and you've burned a meaningful chunk of your CDN request budget fetching route bundles for pages nobody opens.

Next.js prefetches aggressively by default because it makes the next click feel instant. For high-engagement apps that's the right call. For an e-commerce browse where most visitors look at one or two things and bounce, it's worth tuning.

\*\*Note: One metric, two names\*\*

Vercel's docs now call this metric **CDN Requests**. The dashboard and Usage charts still label it **Edge Requests**. Same number, two names. We use "CDN requests" for the concept and "Edge Requests" when we point you at the actual chart.

\*\*Note: What are CDN requests?\*\*

Every request Vercel's CDN processes for your project: pages, RSC payloads,
static assets, API calls, and the speculative prefetches this lesson is
about. Each one counts against the metric, whether or not a human ever saw
the result.

## Outcome

Product card links and drop schedule rows fetch their route bundles only when the visitor clicks, not when the cards scroll into the viewport. Saturday's CDN request count for repeat browsing drops noticeably.

## Hands-on exercise 4.2

Two files. One prop on each high-volume link.

**Requirements:**

1. Open `app/page.tsx`
2. Find the product grid (`liveProducts.map(...)`). Each item renders a `<Link>` wrapping the product card.
3. Add `prefetch={false}` to that `<Link>`
4. Open `app/drops/page.tsx`
5. Find the schedule rows (`sortedDrops.map(...)`). Same pattern.
6. Add `prefetch={false}` to that `<Link>`
7. Leave `app/layout.tsx` untouched. The nav has two links: Shop and Drops. Prefetching those is cheap and the UX win is real.
8. Commit, push, redeploy

**Implementation hints:**

- `prefetch={false}` doesn't disable navigation. The link still works on click. It removes the speculative background fetch entirely, on viewport entry and on hover both.
- That means the route bundle downloads at click time. For pages the size of Saturday's product pages, that's tens of milliseconds on a decent connection, a fair price for skipping the four fetches the visitor never asked for.
- For the nav (`<Link href="/" />`, `<Link href="/drops" />`), keep prefetching on. Those bundles are loaded by almost every user and the prefetch behavior is a clear UX win.
- If you want to be more aggressive, set `prefetch={false}` on the "View Details" button under the hero teaser as well. That's a single high-value link, so prefetching is defensible there. Pick your battles.

## Try It

After the redeploy, open Saturday's homepage in DevTools. Filter the Network panel to "Doc" or "Fetch."

Before the change, scrolling the homepage would trigger a flurry of fetches as the product grid entered view. You'd see five additional `RSC` (React Server Component) requests appear in the panel.

After the change, the same scroll should be quiet. The Network panel stays at whatever it was after the initial load. Hovering doesn't trigger anything either; with `prefetch={false}`, Next.js skips speculation entirely. Click a product card and you'll see one RSC request appear at navigation time, for the one page the visitor actually opened.

In the Vercel dashboard, open Saturday > Observability > Edge Requests. The shape you're looking for is the ratio of requests-per-page-view. Before the change, a single homepage view triggers 1 (the page) + 5 (the grid prefetches) + however many static asset fetches. After, it's 1 + 0 + the assets. On a busy day this difference is the difference between staying within your tier and exceeding it.

## Done-When

- [ ] Product grid `<Link>` in `app/page.tsx` has `prefetch={false}`
- [ ] Drop schedule `<Link>` in `app/drops/page.tsx` has `prefetch={false}`
- [ ] Nav `<Link>` elements in `app/layout.tsx` are unchanged
- [ ] DevTools shows no RSC fetches when scrolling the homepage
- [ ] Clicking a product card triggers exactly one RSC fetch, at navigation time

## Troubleshooting

**Navigation feels slower now.**

That's the honest tradeoff: without prefetching, the route bundle downloads when the visitor clicks. On Saturday's small pages the delay should be barely perceptible. If it's genuinely laggy, the bundle is big enough that click-time fetching hurts, and that's a route bundle size problem worth investigating with `next build --analyze` before you reach for prefetching to paper over it.

**Edge Requests didn't drop in the dashboard.**

Give it 24 hours. The change only shows up in aggregate traffic, and you need a meaningful sample before the trend is visible. Also check that the homepage and drops page got new deployments after your push, the old behavior persists for any pre-existing client-rendered page.

**I'm seeing RSC fetches I don't expect.**

Some are from Next.js's own internal navigation. The dev tools panel can be noisy. Filter by your domain to remove third-party requests, and look at the path of each RSC request to confirm it's actually a product page rather than something internal.

## Solution

The product grid change:

```tsx title="app/page.tsx"
{liveProducts.map((product) => (
  <Link
    key={product.id}
    href={`/products/${product.slug}`}
    prefetch={false}
    className="group"
  >
    {/* ...card contents */}
  </Link>
))}
```

The drops row change:

```tsx title="app/drops/page.tsx"
<Link
  key={drop.id}
  href={`/products/${product.slug}`}
  prefetch={false}
  className="grid grid-cols-[120px_1fr_120px_100px] gap-6 py-6 border-b border-line items-center hover:bg-white transition-colors"
>
  {/* ...row contents */}
</Link>
```

Prefetching is a UX win when it matches user behavior. On a marketing site where people browse five things and click one, viewport prefetching loses the bet on the four they didn't click. Turning it off means the one click pays for one fetch, and the four misses cost nothing.

Up next: builds. Specifically, the builds you didn't need to run.


---

[Full course index](/academy/llms.txt) · [Sitemap](/academy/sitemap.md)
