Vercel ISR Writes: How I Hit 200,000 and Fixed It
Tech
Vercel
Next.js
ISR
Cloud

Vercel ISR Writes: How I Hit 200,000 and Fixed It

AI made Vercel the easy default. A broad Next.js cache strategy exhausted my ISR quota. This is the audit and fix I wish I had first.

Uygar DuzgunUUygar Duzgun
Jul 14, 2026
8 min read

An AI coding assistant will often recommend Vercel the moment it sees a Next.js project. That recommendation makes sense. Vercel removes most deployment work, gives every branch a preview URL, and handles the Next.js runtime without a custom server setup.

I followed that path and liked it. Then Vercel emailed me to say that my Hobby team had used 100% of its included 200,000 ISR Writes. Exceeding the allowance could pause the projects.

My blog contained 291 migrated posts, localized routes, category archives, search pages, and automated publishing tools. I first suspected traffic. The audit pointed somewhere else: the site had a cache lifecycle that allowed one content change to affect far more cached output than necessary.

Vercel was still a reasonable hosting choice. My implementation had never answered three operational questions: which content changed, which exact cache entries depend on it, and whether an unpublished draft should touch the public cache at all.

What Vercel ISR Writes measure

Incremental Static Regeneration lets Next.js serve cached pages while updating them after an interval or an explicit event.

Vercel stores ISR output in a durable cache. It measures reads and writes in 8 KB units. A stored response larger than 8 KB can therefore consume several units during one regeneration. A hypothetical 64 KB payload represents roughly eight units before compression and accounting effects.

Page count alone does not determine usage. Payload size, route count, cached representations, content changes, and invalidation scope all contribute.

Vercel also documents an important detail: a revalidation that produces the same content does not incur new ISR write units. Short revalidation intervals are therefore an incomplete explanation for high write usage.

The dangerous combination looks like this:

Many prerendered articles and archive pages
Broad cache invalidation after a small content change
Output containing timestamps, random values, or other changing data
Large responses that consume multiple 8 KB units
Content workflows that trigger unnecessary public regeneration

Time-based revalidation can still invoke background work. If the generated output changes, Vercel stores the new version. Vercel specifically recommends checking for values such as new Date or Math.random when unexpected ISR writes appear.

The cache pattern that put my project at risk

My audit found recurring ISR intervals across CMS-backed article, category, and marketing routes. The publishing layer could invalidate broad blog surfaces, while category pages handled more content than each response needed.

Draft operations also needed a clearer boundary. Saving an unpublished draft should not invalidate a public article, listing, category, or sitemap. Nothing visible changed.

The blog’s size made broad invalidation expensive by design. One article could affect:

Its canonical article route
The main blog listing
One or more category listings
Recent-article sections
Localized versions
The sitemap

Invalidating every blog surface after every mutation gave the system a poor upper bound. The problem grew with each imported article and locale.

Frequent production deployments created a second operational problem. Vercel can preserve ISR cache data between deployments, but a content workflow should not require a code deployment. Mixing editorial updates with releases made usage harder to diagnose and produced builds the site did not need.

I could not prove that one specific route created all 200,000 units from the available dashboard evidence. I could prove that the existing architecture allowed excessive regeneration, and I could remove that risk.

I replaced the clock with publication events

My new cache rule is direct: public caches change when public content changes.

I removed recurring ISR intervals from CMS-backed blog and static marketing routes. Cached data now stays valid until the write layer reports a relevant mutation.

Each cached query receives a narrow tag. The exact names vary by project, but the model includes separate tags for:

One article
The main article listing
Recent articles
One category and language
Sitemap content

Publishing an article creates a cache plan from both the previous and new versions. The plan invalidates the article, its affected listings, its categories, and the sitemap. A changed slug or category also invalidates the previous public location.

Next.js recommends revalidateTag with the max profile for this pattern. It marks matching data as stale. The next visitor receives the cached response while Next.js refreshes the data in the background. One publication does not immediately launch a regeneration storm across every tagged page.

I use revalidatePath for exact public routes and cache tags for shared data. The two APIs solve different parts of the same problem.

Draft-to-draft updates now produce an empty cache plan. Publishing, unpublishing, changing a slug, or changing a category produces a scoped plan.

Server pagination reduced the cache surface

The original blog structure made large collections too easy to move through one response. I added server-side pagination and limited normal category pages to 12 article links.

After the change, production-style smoke tests returned:

12 article links on the first Tech page
12 article links on page two
Six filtered results for a tested search
12 article links on the tested localized archive

The browser no longer needs hundreds of complete article records to render the first archive page. Smaller responses also mean fewer 8 KB write units when regeneration does happen.

At the configuration level, recurring CMS revalidation dropped to zero. The site can still create ISR writes after publication, which is intentional. One published article should refresh the small set of public surfaces that depend on it.

The Vercel checklist I now give AI agents

A successful deployment proves that the app builds. It does not prove that the cache strategy will remain within a free or paid usage budget.

I now ask an AI coding agent to complete this audit before shipping a content-heavy Next.js project:

Classify every route as static, dynamic, time-based ISR, or on-demand ISR.
Find every route export, fetch option, and cached function that sets a revalidation interval.
Map one article publication to the exact cache tags and paths it invalidates.
Confirm that unpublished draft edits produce no public invalidation.
Handle previous slugs, categories, and locales when content moves.
Paginate archives on the server and inspect the actual response size.
Search cached output for timestamps, random values, and request-specific data.
Keep CMS publication separate from production deployment.
Run next build and next start, then inspect cache hits, misses, and stale responses.
Group Vercel usage by project and region before changing architecture.

A broad revalidatePath call against the whole site should require a concrete reason. “Something changed in the CMS” is not enough.

Should you leave Vercel for DirectAdmin?

I considered moving the site because I already had Node.js hosting through DirectAdmin.

That fallback is technically valid. Next.js documents that a single next start process can support Server Components, ISR, Server Actions, Cache Components, and the rest of the Node.js runtime. DirectAdmin documents Node.js applications through Nginx Unit.

A single instance with persistent disk is the easiest self-hosted setup. Multiple instances require shared cache storage and tag coordination. The reverse proxy must also support streaming if the app depends on progressive Server Component or PPR responses.

Self-hosting transfers responsibility to the operator. You own process supervision, logs, updates, backups, proxy behavior, cache persistence, and incident recovery. Existing server capacity can make the cash cost attractive, but engineering time belongs in the calculation.

I kept the project on Vercel after fixing the cache architecture. Vercel still gives me managed CDN caching, request collapsing, fast previews, rollbacks, and global invalidation. I now treat DirectAdmin as a tested exit path instead of an emergency reaction.

Vercel’s Hobby plan also targets personal, non-commercial projects. A commercial application should choose an appropriate paid setup even when its cache usage fits within the technical limit.

My takeaway

The AI recommendation covered deployment and missed the cache contract.

Vercel remains one of the fastest ways to ship Next.js. That convenience can hide infrastructure decisions until a usage warning forces you to inspect them.

My mistake was allowing time and broad mutations to control a large public cache. The fix was smaller and more precise:

Revalidate after publication
Ignore unpublished drafts
Invalidate the affected article and listings
Paginate large archives
Deploy code changes instead of content changes
Keep a self-hosted Node.js fallback documented

Free hosting can work for a substantial content site when every public cache write has a reason. Design that lifecycle before importing hundreds of posts.

FAQ

Do all ISR revalidations create write units?+
No. Vercel says no write units are incurred when regenerated content is unchanged. Background function work may still occur.
Should I disable ISR to save money?+
Usually no. ISR is useful for content that benefits from cached responses. Use longer intervals or publish-triggered revalidation with narrow tags.
Should I use revalidatePath or revalidateTag?+
Use revalidatePath for exact routes and revalidateTag for shared cached data. Many publishing systems need both.
Can Next.js ISR run on DirectAdmin?+
Yes, when DirectAdmin provides a suitable Node.js runtime and reverse proxy. A single persistent instance is simpler than a multi-instance deployment.
Will Vercel pause a Hobby project after it exceeds free usage?+
Vercel’s plan documentation says Hobby projects can be paused after exceeding included free-tier usage.

Recommended for you

Vercel vs Stormkit: Proven Deployment Guide for Teams

Vercel vs Stormkit: Proven Deployment Guide for Teams

I break down vercel vs stormkit so you can choose the right deployment platform for pricing, previews, control, and portability.

15 min read
How I Built My MCP CMS With Agent Flows

How I Built My MCP CMS With Agent Flows

I built an MCP CMS inside Next.js to unify content, tools, and AI workflows into one fast, controlled publishing system.

11 min read
Headless WordPress Deployment: DNS, SSL, and AI

Headless WordPress Deployment: DNS, SSL, and AI

A real headless WordPress deployment can break DNS, SSL, images, and forms. Here’s how I fixed it in production.

8 min read