What is Deferred Static Generation (DSG) in Gatsby and When Should You Use It?
Deferred Static Generation (DSG) is a Gatsby rendering mode that delays HTML/JSON generation until the first user request, reducing build times for large sites while serving cached static assets for subsequent visits.
Gatsby supports three distinct rendering strategies: Static Site Generation (SSG), Server-Side Rendering (SSR), and Deferred Static Generation (DSG). While SSG generates all pages at build time and SSR renders pages on every request, DSG offers a hybrid approach specifically designed to solve build-time scalability issues in the gatsbyjs/gatsby repository. This mode allows developers to ship sites with thousands of pages without waiting for every single page to build during continuous integration.
How Deferred Static Generation Works Under the Hood
The defer Flag in createPage
DSG is triggered by setting defer: true when creating pages programmatically. In packages/gatsby/src/redux/actions/public.js, the createPage action accepts this flag and attaches it to the page object:
// From public.js lines 172-174
{
path: `/blog/${node.slug}/`,
component: require.resolve(`./src/templates/blog-post.js`),
context: { slug: node.slug },
defer: true, // Enables DSG for this page
}
Mode Resolution Logic
During the build process, Gatsby determines each page's rendering mode through the resolver in packages/gatsby/src/utils/page-mode.ts (lines 66-68). The system checks the explicit defer flag and, for File-System Route API pages, evaluates the exported config function to decide whether to treat the page as SSG, SSR, or DSG.
Pages that are forced to SSG include 404/500 error pages, as explicitly coded in page-mode.ts lines 70-77, ensuring critical error pages are always available immediately.
First Request Materialization
Only pages whose mode is not SSG are written into the materialized page-mode store (page-mode.ts lines 99-107), allowing gatsby serve to identify which pages require lazy rendering.
When a request hits a DSG page:
- The server executes the page's GraphQL queries
- Renders the React component to HTML
- Writes the resulting HTML/JSON to the build output
- Returns the response immediately while caching the assets
Subsequent requests receive the cached static files directly, delivering identical performance to fully pre-generated pages.
When to Use DSG for Large Gatsby Sites
DSG solves specific scalability challenges in large-scale Gatsby deployments. Consider implementing deferred generation in these scenarios:
| Situation | Why DSG Helps | Implementation |
|---|---|---|
| Thousands of low-traffic pages (old blog posts, archives, user-generated content) | Build time scales with page count. Deferring rarely visited pages can reduce build times by 30-70% according to v4.0 release notes. | Mark pages with defer: true via createPage or config export. |
| Content changing infrequently but not needed at launch | Ship quickly while supporting on-demand generation for omitted pages later. | Apply DSG to "future" content added after initial release. |
| Sites with many locale-specific pages (i18n with multiple language variants) | Generating every locale upfront multiplies build work. Deferring secondary locales reduces the build graph. | Use defer: true for non-primary locale pages. |
| Pages with heavy GraphQL queries | Query costs occur only on first request, not during every CI build. | Combine DSG with query caching on Gatsby Cloud for optimal performance. |
Avoid DSG for critical paths (homepage, checkout flows), 404/500 error pages (Gatsby forces SSG for these), or sites deployed to static-only hosts without Node.js server capabilities.
Implementation Examples
Using createPage with defer
Programmatically create deferred pages in gatsby-node.js:
// gatsby-node.js
exports.createPages = async ({ actions, graphql }) => {
const result = await graphql(`
{
allMdx(filter: { frontmatter: { draft: { ne: true } } }) {
nodes {
slug
}
}
}
`)
result.data.allMdx.nodes.forEach(node => {
actions.createPage({
path: `/blog/${node.slug}/`,
component: require.resolve(`./src/templates/blog-post.js`),
context: { slug: node.slug },
defer: true, // ← DSG flag
})
})
}
The defer flag is defined in packages/gatsby/src/redux/actions/public.js lines 172-174.
File System Route API Config Export
For pages created via the File System Route API, export a config function:
// src/pages/blog/{Mdx.slug}.js
export async function config() {
// Optional: Run GraphQL here to determine deferral logic
return ({ params }) => ({
defer: true, // ← DSG enabled for this route
})
}
This API is documented in docs/docs/reference/rendering-options/deferred-static-generation.md lines 14-27.
DSG Page Component Structure
A minimal DSG page template looks identical to standard Gatsby pages:
// src/templates/using-dsg.js
import * as React from "react"
import { Link } from "gatsby"
import Layout from "../components/layout"
import Seo from "../components/seo"
const UsingDSG = () => (
<Layout>
<h1>Hello from a <b>DSG Page</b></h1>
<p>This page is not created until requested by a user.</p>
<Link to="/">Go back to the homepage</Link>
</Layout>
)
export const Head = () => <Seo title="Using DSG" />
export default UsingDSG
This example is available in the default starter at starters/default/src/templates/using-dsg.js.
Key Source Files and Architecture
Understanding the internal implementation helps debug DSG behavior in production:
| File | Purpose |
|---|---|
packages/gatsby/src/redux/actions/public.js |
Defines the createPage action including the defer parameter (lines 172-174). |
packages/gatsby/src/utils/page-mode.ts |
Resolves page modes (SSG, SSR, DSG) and forces SSG for error pages (lines 66-68, 70-77, 99-107). |
docs/docs/reference/rendering-options/deferred-static-generation.md |
Official DSG documentation covering API usage and limitations (lines 14-27, 66-73). |
starters/default/src/templates/using-dsg.js |
Minimal runnable DSG page example in the default starter template. |
docs/docs/how-to/rendering-options/using-deferred-static-generation.md |
Step-by-step implementation guide for real-world DSG scenarios. |
These files illustrate how DSG is expressed in the API, how Gatsby decides to treat a page as deferred, and how developers can enable it in their projects.
Summary
- Deferred Static Generation (DSG) delays HTML/JSON creation until the first user request, caching results for subsequent static serving.
- Enable DSG by setting
defer: trueincreatePage(defined inpackages/gatsby/src/redux/actions/public.js) or returningdefer: truefrom a File System Routeconfigexport. - Gatsby determines page modes in
packages/gatsby/src/utils/page-mode.ts, forcing SSG for error pages regardless of defer settings. - DSG requires a running Node.js server (
gatsby serveor Gatsby Cloud) and cannot deploy to pure static hosts. - Ideal for large sites with thousands of low-traffic pages, heavy GraphQL queries, or multi-locale content that would otherwise inflate build times.
Frequently Asked Questions
What is the difference between DSG and SSR in Gatsby?
Server-Side Rendering (SSR) generates HTML on every single request, making it suitable for personalized or highly dynamic content. Deferred Static Generation (DSG) generates HTML only on the first request, then caches and serves the result statically for all subsequent visitors. According to the Gatsby source code in packages/gatsby/src/utils/page-mode.ts, both modes bypass the build-time SSG pipeline, but DSG persists the output to disk while SSR does not.
Can I use DSG with static hosting platforms like Netlify or Vercel?
No. DSG requires a running Node.js server to handle the initial request generation and subsequent caching. Static hosting platforms that only serve pre-built files from a CDN cannot execute the on-the-fly rendering logic implemented in gatsby serve. To use DSG, you must deploy to Gatsby Cloud, a Node.js server environment, or any hosting solution that supports server-side execution.
How does DSG affect SEO and page performance?
SEO impact is minimal if you configure your hosting correctly. While the first request incurs a slight delay (cold start) as Gatsby generates the HTML, subsequent requests receive cached static files with identical performance characteristics to SSG pages. Search engine crawlers typically receive the cached version after the first visit. However, critical landing pages should remain SSG to guarantee instant availability for all visitors, as recommended in the DSG documentation.
Which pages should not use Deferred Static Generation?
Avoid DSG for high-traffic entry points (homepage, product pages, checkout flows), 404/500 error pages, and any content required for immediate site functionality. The Gatsby source code in packages/gatsby/src/utils/page-mode.ts (lines 70-77) explicitly forces SSG mode for error pages regardless of developer configuration. Additionally, pages that must be available offline or served from pure static CDNs cannot use DSG due to its server-side rendering requirement.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →