The trade-off across four dimensions
Deploy time: static export rebuilds every leaf on every deploy; ISR rebuilds nothing on deploy, leaves regenerate on first request. Under five hundred leaves, the static rebuild is fast enough to ignore; past five hundred, deploy time bites. First-request latency: static export serves from CDN cache, low double-digit milliseconds; ISR cold-leaf first request is eight hundred to one and a half seconds while the page renders. Cache invalidation: static needs no invalidation, just redeploy; ISR uses revalidatePath or revalidate-by-time, which adds operational surface.
The leaf-count threshold and the latency budget
Our threshold for cutover is five hundred leaves or a two-minute cold-build, whichever comes first. Below that, static export wins on operational simplicity. Above it, ISR wins on deploy economics. The first-request latency penalty on ISR is real but invisible to the long tail: a leaf with two impressions per month sees its first-request latency once and then serves from edge cache forever after. The penalty matters for trending leaves that get a burst of traffic on a cold cache; for those, manual pre-warming via revalidatePath on deploy is the fix.
Migration sketch in either direction
Static-to-ISR migration is straightforward: remove output: export from next.config.js, add revalidate: 86400 to the page export, deploy. The first deploy will still build all leaves statically; subsequent deploys will rely on ISR. ISR-to-static migration is also straightforward if your leaf count has shrunk: re-enable output: export, redeploy. The pitfall in either direction is the sitemap: static export emits the full URL list at build time; ISR emits whatever the slug manifest holds. Keep the sitemap source as the manifest, not the page set, to avoid drift.
