Skip to content

Experimental incremental static builds

Type: boolean
Default: false

Added in: astro@7.2.0 New

This experimental feature reuses the output of a previous build so that unchanged pages are not rendered again.

When enabled, Astro can skip a static page generated by getStaticPaths() if both its data and the code it depends on are unchanged since the last build. You mark a page’s data by returning a cacheKey for it, and Astro tracks the code by hashing the page’s module dependency graph. When both match the previous build, Astro copies the earlier output instead of rendering the page again.

On large sites where most pages change infrequently, this can reduce build times significantly because rendering is skipped for pages that would produce identical output.

To enable incremental builds, add the flag to your Astro config:

astro.config.mjs
import { defineConfig } from "astro/config";
export default defineConfig({
experimental: {
incrementalBuild: true,
},
});

Only pages returned from getStaticPaths() that include a cacheKey can be skipped. Every other page, including static pages that do not use getStaticPaths(), is rendered on each build.

A cacheKey is a string that identifies the data used to render a page. Choose a value that changes whenever the page’s content changes, such as a content hash, a version number, or an updated timestamp from your data source. Astro re-renders the page when its cacheKey differs from the previous build, and reuses the previous output when it is the same.

src/pages/blog/[slug].astro
---
export async function getStaticPaths() {
const posts = await fetchPosts();
return posts.map((post) => ({
params: { slug: post.slug },
props: { post },
cacheKey: post.updatedAt,
}));
}
---

When you generate pages from a content collection, a loader can provide a digest for each entry. The loader is responsible for updating this value whenever the entry’s data changes. This makes it a convenient cacheKey:

src/pages/docs/[...slug].astro
---
import { getCollection, render } from "astro:content";
export async function getStaticPaths() {
const entries = await getCollection("docs");
return entries.map((entry) => ({
params: { slug: entry.id },
props: { entry },
cacheKey: String(entry.digest),
}));
}
const { entry } = Astro.props;
const { Content } = await render(entry);
---

A page with a matching cacheKey is still re-rendered when the code it relies on changes. Astro hashes the page’s module dependency graph, including the contents of its layouts, components, and imported files, so editing any of them invalidates the pages that use them. Changing your Astro configuration or your project’s dependencies invalidates the entire cache, since those can affect the output of every page.

Pages that are removed from getStaticPaths() between builds have their previous output cleaned up automatically.

Astro stores the incremental cache in your project’s cacheDir, which is node_modules/.astro/ by default. This holds both the build manifest and the reusable output of previously-rendered pages. The output directory is emptied at the start of every build, and skipped pages are restored from cacheDir.

For pages to be skipped in a continuous integration environment, cacheDir must be restored before running astro build. Cache and restore this single directory between builds; nothing else needs to persist. If it is missing, Astro re-renders every page.

To ignore the cache and re-render every page, run astro build --force. Astro still writes a fresh cache for the next build.

This experimental feature currently has the following limitations:

  • build.concurrency: The incremental cache is disabled when build.concurrency is greater than 1. Astro logs a warning and re-renders every page.

  • Server islands: Pages that renders server islands embed props with a key that is regenerated on each build by default. They are re-rendered every time. To cache these pages and reuse them between builds, set a stable ASTRO_KEY. Changing the key invalidates them, ensuring that their embedded content stays decryptable.

  • Middleware: Changes to your middleware do not invalidate cached pages. If your middleware changes the HTML of prerendered pages, run astro build --force after editing it.

Contribute Community Sponsor