Dynamic vs Static Sitemaps: Which One Does Your SaaS Need?
When dynamic sitemaps work, when static or build-time ones break, and the hybrid most growing SaaS products actually need.
Dynamic vs Static Sitemaps: Which One Does Your SaaS Need?
A dynamic sitemap is generated on demand (or on a schedule) from your live data. A static sitemap is a file that was written once and sits on disk until someone changes it. For most SaaS products, neither pure option is right — you need something that behaves like a dynamic sitemap but doesn't live inside your application.
This guide breaks down the four real implementation patterns, the specific ways SaaS sitemaps break that blog sitemaps don't, and how to pick the approach that still works when you 10x your page count.
Table of contents
- The four kinds of sitemap
- Why SaaS sitemaps are harder than blog sitemaps
- Static sitemaps: when they work, when they don't
- Dynamic sitemaps: the real gotchas
- Build-time sitemaps (the JAMstack special case)
- External / hosted sitemaps
- Decision framework
- FAQ
The four kinds of sitemap
"Dynamic vs static" is the common framing, but there are actually four patterns. Being precise about which one you have (or want) saves a lot of confusion:
| Pattern | How it's generated | How it's served | Typical home |
|---|---|---|---|
| Static | Written once, manually or by a script | File on disk | Brochure sites, very small catalogs |
| Build-time | Auto-generated at deploy time | File on disk | JAMstack (Next.js, Nuxt, Astro, Hugo) |
| Dynamic (on-demand) | Generated at request time from the DB | Your app responds to /sitemap.xml |
CMS plugins, custom Rails/Laravel apps |
| External / hosted | Generated by a service that crawls your site | CDN-hosted URL you point Google at | SaaS products, multi-stack environments |
Each has a genuine use case. The mistake isn't picking the "wrong" one in the abstract — it's picking the pattern that doesn't match your content velocity or your team's ops budget.
Why SaaS sitemaps are harder than blog sitemaps
A WordPress blog with Yoast installed has a solved sitemap problem. A typical SaaS product, even a small one, doesn't — and the reasons are structural, not tooling.
1. SaaS sites have at least four different URL types
The typical SaaS marketing surface includes:
- Marketing pages — homepage, pricing, features, about. Stable, rarely change.
- Blog / content — changes weekly or daily.
- Docs — updated with every product release, sometimes per-branch.
- Programmatic pages —
/{keyword}-vs-{competitor},/templates/{slug},/integrations/{slug}. Can be thousands of URLs generated from a database. - Changelog / release notes — updated on every deploy.
Each URL type has its own update rhythm. A single sitemap built by one mechanism rarely fits all four well.
2. Programmatic pages appear and disappear unpredictably
You launch 2,000 /integrations/{slug} pages. Three months later, you deprecate 200. A static sitemap snapshot of "the product on launch day" is wrong within a quarter. A dynamic sitemap that queries the live database catches this — but only if the database cleanly knows which pages are currently live.
3. Multi-tenant products have public subdomains or paths that matter for SEO
If your product is yoursaas.com but customers publish to {customer}.yoursaas.com or yoursaas.com/{customer} and those pages are indexable, you now have a sitemap per tenant problem. Most blog-era sitemap tools don't handle this at all.
4. Content velocity decouples from deploy velocity
Early-stage SaaS typically ships code weekly but publishes blog content and marketing pages much more often — through a CMS, a changelog tool, a hosted docs platform. If your sitemap is built at deploy time, it's stale between releases. If it's built on request from the DB, you're back to the dynamic-sitemap problem.
5. JavaScript-heavy product surfaces
Many SaaS marketing sites run on Next.js, Nuxt, or a SPA framework. If pages render only after JavaScript executes, any sitemap tool that fetches raw HTML — including Googlebot's first pass — sees an empty shell. The fix is SSR or pre-rendering, which is a real decision you have to make before sitemap tooling matters. More on this in why Google isn't indexing your pages.
Static sitemaps: when they work, when they don't
A static sitemap is exactly what it sounds like: an XML file written once, committed to the repo or uploaded to the server, and updated only when someone remembers to.
When static works
- Brochure sites under 50 pages that change once or twice a year
- Conference/event sites with a fixed agenda
- Portfolio sites where you manually add entries
- Fully-static documentation where every change is a conscious git commit
When static breaks
The instant you start publishing content more than once a month, the sitemap drifts. Two weeks into running a blog, you've forgotten to regenerate it. Six months in, it's missing 40% of your posts. New URLs get indexed eventually through internal linking, but much slower than they would with a current sitemap.
For SaaS specifically, static sitemaps are almost never right. SaaS sites have too many URL types with too many different update rhythms for "I'll regenerate it manually" to survive the first quarter.
Dynamic sitemaps: the real gotchas
A dynamic sitemap is generated at request time. When Google hits /sitemap.xml, your app runs a database query, formats the response as XML, and sends it back.
This is the pattern you get from:
- WordPress with Yoast/RankMath
- Shopify (built-in)
- Webflow (built-in)
- Ghost (built-in)
- Custom Laravel apps using
spatie/laravel-sitemap - Custom Rails apps using similar gems
Why dynamic sitemaps are tempting
Always up to date by definition. Every new blog post, product, or page is in the sitemap the moment it's published. No cron job, no manual regeneration. For a SaaS with a cleanly-modeled CMS, this is the obvious choice.
The four dynamic-sitemap gotchas nobody warns you about
1. Performance degrades with catalog size. A sitemap controller that was fine at 500 URLs stops being fine at 50,000. Query plans change, memory usage spikes, and the first request after a cache miss can take 30+ seconds. Googlebot times out. You see "Couldn't fetch" in Search Console and have no idea why.
2. Cache layers break sitemaps silently. A CDN caches /sitemap.xml for 24 hours. You publish a new post. Googlebot fetches the cached sitemap and sees nothing new. You don't notice until you check Search Console a week later.
3. <lastmod> is usually wrong. Most dynamic sitemap generators use updated_at from the database — which often reflects when the record was last saved, not when the content meaningfully changed. Save a blog post with one typo fix, and every CMS that treats updated_at = NOW() tells Google the post is fresh. Over time, Google stops trusting your <lastmod> dates.
4. Sitemap generation competes with production traffic. The same database your sitemap scans is the one serving your checkout flow. A crawl during peak hours can cause measurable latency on real user requests. On very large catalogs, this is the reason to offload sitemap generation entirely.
When dynamic still wins
Dynamic sitemaps are great for SaaS up to the point where any of the four gotchas above starts biting. That threshold is different for everyone — often somewhere around 10,000–50,000 URLs, or earlier if your app is on limited infrastructure. Below that, a well-written dynamic sitemap controller is the simplest and fastest option.
Build-time sitemaps (the JAMstack special case)
A build-time sitemap is generated during deployment by a library like next-sitemap, @nuxtjs/sitemap, or Astro's sitemap integration. The file is written to the deployed build output and served as a static asset.
The pattern
- CI builds the site.
- Build plugin walks your routes and content sources.
- Plugin writes
/sitemap.xmlinto the output directory. - Static hosting serves the file.
Fast at serve time (it's just a static file), always consistent with the deployed code, no database load.
Where it breaks for SaaS
Content changes between deploys. If your blog is in Sanity/Contentful/Notion and you publish without triggering a rebuild, the sitemap doesn't know. You fix this with build hooks, but now every content save waits for a build to complete.
Programmatic pages source from external data. If /integrations/{slug} pulls from your main app's API, your build pipeline needs access to that API — which means staging URLs, auth, rate limits. Buildable, but fragile.
Tenant/user pages multiply unpredictably. A build-time sitemap can't know about tenants that signed up after the last deploy.
The JAMstack stack is beautifully fast and legitimately right for a lot of SaaS marketing sites. The sitemap is the one place where build-time generation starts to feel like a mismatch — because content velocity usually outpaces deploy velocity.
External / hosted sitemaps
This is the pattern that most commonly fits SaaS: a service that crawls your live site on a schedule, generates the sitemap from what it actually finds in your HTML, and hosts it on its own CDN.
How it works
- You give the service your domain (e.g.
yoursaas.com). - The service crawls the site on a schedule — daily for most SaaS.
- It generates a sitemap from the discovered URLs and hosts it at a stable URL.
- You submit that URL to Google Search Console.
No plugin, no code change, no database query against your production DB. The sitemap lives entirely outside your app.
Why this pattern fits SaaS specifically
- Stack-agnostic. Whether your marketing site is Next.js SSR, your docs are Mintlify, your blog is Ghost, and your pricing page is hand-written HTML, the crawler sees one site and sitemaps it as one.
- Deploys and content changes both get picked up. The crawler doesn't care whether a page appeared because of a deploy or because someone saved a blog post — it sees the URL on the next run.
- No load on your production app. The crawler runs on external infrastructure at polite crawl rates. Your database doesn't know it's happening.
- Sitemap URL is stable. Paid plans on Indexly give a permanent sitemap URL you can submit to Google once and never touch again.
- Diff-aware. A good hosted tool compares each crawl to the previous one and surfaces what changed. This doubles as an early-warning system for deploys that accidentally drop pages — one of the most common sources of organic traffic drops at growing SaaS companies.
The caveat
External crawlers see what a typical user-agent sees. If your pages require JavaScript execution to render, an HTML-only crawler (including Indexly's, and including Googlebot's first pass) only sees the empty shell. The fix isn't a different sitemap tool — it's server-side rendering or pre-rendering your pages. Next.js SSR, Nuxt ssr: true, or a pre-render service in front of a pure SPA. Once the HTML contains your content, any crawler can build a correct sitemap from it.
For stack-specific guidance on this, see automating sitemaps across Laravel, WordPress and Webflow.
Decision framework
Run through this in order. First "yes" is your answer:
1. Is your site under 100 pages and changes less than monthly? → Static sitemap. Regenerate manually when you publish.
2. Are you on a CMS with a built-in sitemap (WordPress + Yoast, Shopify, Webflow, Ghost), under ~10,000 URLs, and on a single platform? → The built-in dynamic sitemap. Don't overthink it until it breaks.
3. Are you fully JAMstack (Next.js, Nuxt, Astro) with deploys on every content change?
→ Build-time sitemap. next-sitemap or equivalent.
4. Are you a SaaS with content spread across multiple tools (marketing site + blog + docs + programmatic pages), or over ~10,000 URLs, or hitting any of the dynamic-sitemap gotchas? → External / hosted sitemap. Indexly is designed for this specific shape of problem.
5. Are you a pure client-rendered SPA with no SSR?
→ Stop. Fix rendering first. No sitemap tool can fix "Googlebot sees an empty <div id=\"root\">."
The framework isn't about picking the "best" category — it's about picking the one that matches your actual architecture and content rhythm. Most growing SaaS products end up at option 4 within 12–18 months, even if they started at 2 or 3.
FAQ
What's the difference between a dynamic and static sitemap?
A static sitemap is a fixed XML file that only changes when someone manually regenerates it. A dynamic sitemap is generated on the fly from live data, so it always reflects the current state of your site. Static is simpler; dynamic stays accurate as content changes. Most sites outgrow static within a few months of regular publishing.
Does Google prefer dynamic or static sitemaps?
Google doesn't care how the sitemap is generated — only that it's accurate, reachable, and updates when your content does. A fresh static sitemap and a correctly-built dynamic one are equivalent to Googlebot. What Google does penalize (by trusting the sitemap less over time) is inaccurate <lastmod> dates, stale URLs, and sitemaps that return errors intermittently.
Can I have both a dynamic sitemap and an external hosted one?
Yes, but only submit one to Google Search Console. Running both creates the risk that they disagree on URLs or <lastmod> values, which confuses Search Console's reporting. Most teams that move to a hosted sitemap simply stop generating the dynamic one, or keep it around for internal use without submitting it.
What's the best sitemap approach for a SaaS with programmatic SEO pages?
Usually an external hosted sitemap, because programmatic pages often span multiple data sources (CMS, app DB, external APIs) that no single plugin sees. A crawler that reads the rendered HTML sees the same pages a user sees — which is the only way to reliably catch programmatic URLs that span systems. This assumes those pages render to HTML server-side.
Are build-time sitemaps good for SaaS?
They work well for fully-static SaaS marketing sites where every content change triggers a rebuild. They start to creak when content lives in external tools that publish without triggering deploys, when programmatic pages source from your main app's API, or when tenant pages multiply between builds. Past that, external sitemaps fit better.
Does a dynamic sitemap slow down my site?
It can. Every request to /sitemap.xml runs a database query; at scale, those queries can take seconds and compete with real user traffic. Good implementations cache the generated sitemap (not the query) for an hour at a time. Past ~50,000 URLs, most teams offload sitemap generation entirely to external tooling to stop it impacting production.
The bottom line
"Dynamic vs static" is the wrong binary for SaaS. The real question is whether your sitemap lives inside your application (dynamic, build-time) or outside it (external, hosted), and for most growing SaaS products the answer shifts from "inside" to "outside" somewhere around the point where the sitemap starts feeling like infrastructure you have to babysit.
If your team has better things to do than maintain a sitemap pipeline, try Indexly free. Point it at your site, pick a cadence, get a hosted sitemap URL that stays current automatically — no plugin, no package, no deploy required. Works with Next.js, Nuxt, Laravel, Rails, Ghost, Webflow, Shopify, and anything else that serves HTML. Every page found. Every page indexed.
Indexly Team
Writing about SEO, sitemaps, and how to get every page indexed by Google.
Enjoyed this post?
Get our next one delivered to your inbox — no spam, ever.
Ready to get your site fully indexed?
Get started free