Vercel ISR vs SSG for Content Sites: Which Wins

ISR sounds modern, SSG sounds old, but for a content site the choice is concrete. Here is the actual trade-off in build time, freshness, cost, and rollback.

SSG means every page is pre-rendered at build and served from CDN forever (until the next build). ISR means pages are pre-rendered too, but Vercel re-renders them in the background on a schedule or on demand. For a content site, the decision comes down to four numbers: build time, freshness needs, function cost, and rollback complexity.

Background

SSG (Static Site Generation) writes HTML during next build or astro build. Every URL becomes a file in out/ or dist/. ISR (Incremental Static Regeneration) is Next.js-specific: pages are still pre-rendered, but stale pages trigger a background regeneration on the next request after revalidate seconds. Vercel supports both, but ISR needs a Node serverless function as the renderer.

How to tell

  • Your build takes over 5 minutes and you have hundreds of articles — ISR can split the cost across requests instead of bunching it at build.
  • You publish 20+ updates a day across a small editorial team — ISR or on-demand revalidation avoids 20 redeploys.
  • Your content is fully static (legal pages, docs, archived posts) — SSG is simpler and cheaper.
  • You hit Vercel’s build time limits (45 minutes on Hobby, longer on Pro) — that is the loudest ISR signal.

Quick verdict

Under 500 articles, infrequent edits, fast build: SSG wins. Over 2,000 articles or daily updates: ISR with on-demand revalidation wins. In between, either works — pick by team workflow, not benchmarks.

When SSG is the right answer

Five real signals that SSG is enough:

  • Build takes under 3 minutes — no pain to redeploy for an edit.
  • Editors are comfortable with git, or a CMS already triggers a redeploy on save.
  • You want the most boring possible production: CDN serves files, no function invocations, no surprises.
  • Rollback is “promote the previous deployment” — instant, atomic, no cache eviction needed.
  • Your hosting bill should be roughly the cost of a CDN, period.

Astro defaults to SSG with output: 'static'. Next.js defaults to SSG for any route with generateStaticParams and no dynamic APIs.

When ISR pays for itself

Three concrete cases:

  1. Build time is the bottleneck. 5,000+ articles, build takes 20 minutes, every typo fix is a 20-minute wait. ISR builds only the most popular slugs and lazily regenerates the rest:
// app/articles/[slug]/page.tsx
export const revalidate = 3600;  // ISR: regenerate at most every hour

export async function generateStaticParams() {
  // Only pre-render the top 200; rest are lazy
  return (await getTopArticles(200)).map(a => ({ slug: a.slug }));
}
  1. On-demand revalidation from a CMS webhook. Editor hits Publish in Sanity / Contentful, the webhook calls /api/revalidate, the one affected URL regenerates in seconds. No full redeploy:
// app/api/revalidate/route.ts
import { revalidatePath } from 'next/cache';
import { NextRequest, NextResponse } from 'next/server';

export async function POST(req: NextRequest) {
  const secret = req.nextUrl.searchParams.get('secret');
  if (secret !== process.env.REVALIDATE_SECRET) {
    return NextResponse.json({ ok: false }, { status: 401 });
  }
  const { slug } = await req.json();
  revalidatePath(`/articles/${slug}/`);
  return NextResponse.json({ ok: true, revalidated: slug });
}
  1. Scheduled revalidation for changing fragments. Article body is fixed, but a “related articles” rail needs refreshing weekly. Set revalidate = 604800 and the page rebuilds itself.

Rollback differs

  • SSG rollback is one click — Vercel promotes the previous build, atomic across all pages.
  • ISR rollback is trickier — the previous deployment may still hold stale regenerated copies in the function cache. Use revalidatePath or revalidateTag after promoting, or wait out the TTL.

Common mistakes

  • Setting revalidate = 60 on every page “to be safe” — you have just turned every request after the first cold one into a function invocation. Bill goes up, CDN hit rate goes down.
  • Using ISR but no on-demand hook — editors still wait for the revalidate window to see their changes live.
  • Forgetting that ISR needs Node serverless functions deployed, not just static files — affects cost model and which Vercel plan you need.
  • Mixing SSG and ISR in the same app and being confused why a page shows old content — check export const revalidate in the segment.
  • Treating Astro’s output: 'hybrid' as “Astro ISR” — it is closer to SSR per route. Astro does not have true ISR in 2026; it has on-demand regeneration via the Vercel adapter.

FAQ

  • Is ISR worse for SEO than SSG?: No. Both serve pre-rendered HTML to crawlers. ISR’s first regenerate after a redeploy may be slightly slower; subsequent hits are CDN-fast.
  • Can I use ISR with Astro?: Sort of. Astro has on-demand rendering with the Vercel adapter, but not “stale-while-revalidate” timing semantics like Next.js. Astro content sites are usually fine on SSG.
  • What about Vercel’s “Data Cache”?: That is per-fetch caching, orthogonal to ISR. You can combine them: ISR caches the rendered page; Data Cache caches individual fetch() calls inside it.
  • What happens if a regenerate fails?: The stale page keeps serving. You will see the error in Vercel logs, but users see the last-known-good HTML — that is the whole point.
  • Is ISR the same as revalidateOnInterval?: Same idea, different framework. Astro and SvelteKit on Vercel use different terms, but the cache primitive is the same.

Tags: #Indie dev #Vercel #Hosting #isr #Performance