Why HashiCorp moved past full-site rebuilds

Incremental Static Regeneration (ISR) has been part of Next.js since version 9.5, giving teams a rendering strategy that sits between full static generation and server-side rendering. Instead of forcing an entire site rebuild whenever any page changes, ISR lets developers re-run getStaticProps after the build has finished, generating static pages at runtime rather than only at build time. That distinction matters more as sites grow: build times scale with page count, so a site with thousands or millions of pages can easily take hours to rebuild for even a minor content edit.

Next.js 12.1 introduced on-demand ISR, which extends the model further by letting developers purge the cache for a specific page on demand via an API call. That addresses one of the most common requests from teams shipping large-scale projects: the ability to push content changes live immediately, without waiting for a revalidation window or triggering a full deploy for a handful of changed pages.

What ISR changes operationally

Traditional SSG treats a site as a single unit: any change means rebuilding everything. ISR makes static generation a per-page decision. Pages can be generated at runtime, which cuts build time significantly, but still serve as static HTML to visitors. Enterprises have used this approach to keep large content sites fresh without sacrificing performance.

The usefulness of ISR depends on how quickly stale content can be refreshed. A revalidate timer gives a baseline, but aggressive timers make caching less effective, and conservative ones leave content creators waiting. On-demand ISR eliminates that tradeoff by allowing an instant revalidation of any page using getStaticProps. A headless CMS webhook, for example, can call the revalidate endpoint when content changes, producing near-instant updates without rebuilding unchanged pages or forcing a deploy.

HashiCorp’s documentation architecture

HashiCorp’s documentation team runs sites for eight open-source products, each built from content in its own repository. Over the past year, the team added versioned documentation for every product, rendering many past versions of each doc set rather than just the latest. That multiplied the page count dramatically. The team responded by serving documentation content from an API instead of reading from the file system, and using ISR to generate only the most-visited pages at build time—identified from analytics data—and defer the rest until after the initial build.

The team currently sets its revalidate timeout to one hour. With ISR, content changes propagate to live sites without a full rebuild. But one hour is still a delay, and HashiCorp wanted shorter feedback cycles for content creators.

On-demand ISR closes that gap. Since the team’s content lives in GitHub, a GitHub application listens for push events containing documentation changes, and GitHub Actions uploads the content to the database. Because the workflow has access to the files that changed, it can trigger on-demand ISR for only the affected pages.

// Pre-render the top pages based on traffic data

// `fallback: blocking` will generate the page on-demand

// it if hasn't already been generated.

export async function getStaticPaths(ctx) {

return {

paths: await getTopPathsFromAnalytics(ctx),

fallback: 'blocking'

}

}

// Fetch the data for this specific page

export async function getStaticProps(ctx) {

return {

props: await getDocumentationContent(ctx),

revalidate: 360 // 1 hour

  }

}

Production patterns with on-demand ISR

HashiCorp’s integration point is a small API route, pages/api/revalidate.js, which invokes the revalidation for a given page path.

export default async function revalidate(request, response) {

const { secret, path } = request.query

// Check for secret to confirm this is a valid request

if (secret !== process.env.REVALIDATE_SECRET) {

return response.send(401)

  }

if (await isValidPage(path)) {

  await response.unstable_revalidate(path)

return response.status(200).json({ revalidated: true })

}

return response.send(400)

}

For large batches of updates—like a product release—the team still uses Vercel deploy hooks to trigger a full-site deploy. But they are evaluating whether targeted on-demand ISR calls can replace those unnecessary builds. The programmatic interface matters here: it lets the team adjust the revalidation logic to fit the architecture rather than adapting the architecture to a fixed webhook model.

“A lot of teams struggle with trying to implement their own version of ISR at scale. In an enterprise organization, entire teams can be dedicated to making it work. But with Vercel, ISR works out of the box.”

Next steps for HashiCorp

Having on-demand ISR in place gives HashiCorp room to make its revalidate timers more aggressive without worrying about serving stale content. The team plans to expand on-demand ISR usage across its suite of Next.js sites and speed up iteration across all of its documentation properties.

HashiCorp is also evaluating what it can shift to edge compute using Next.js Middleware. The team sees Middleware as a testbed for moving logic to the edge without hurting runtime performance or losing the benefits of static generation—the same tension that motivated the move to on-demand ISR in the first place.