Every WordPress performance project eventually hits the same wall. You can cache pages, lazy-load images, and buy better hosting, but the architecture itself — PHP executing against MySQL on every uncached request, twenty plugins each injecting their own scripts — sets a floor under your latency that no optimization plugin can break through.
Migrating to Hugo removes the floor. Pages become pre-rendered files served from a CDN edge, time to first byte drops by an order of magnitude, and the attack surface that keeps WordPress on a weekly patch cycle simply ceases to exist. The catch: a migration done carelessly can vaporize a decade of accumulated search equity in one DNS change.
This is the migration plan we use on client projects — export, front matter, permalinks, plugin replacement, and the SEO safety rails, in the order that prevents expensive surprises.
What You Actually Gain (and What You Give Up)
| Dimension | WordPress (typical shared/managed) | Hugo + CDN edge |
|---|---|---|
| Time to first byte | PHP + database on every uncached hit | A cached file from the nearest edge |
| Requests hitting origin code | Every uncached page view | Zero (files only) |
| Security patching | Core + theme + plugins, weekly | None at runtime |
| Hosting cost (small site) | A recurring monthly bill | $0 on free static tiers |
| Editing UX for non-devs | Excellent, built-in | Requires a CMS layer (Decap, Tina) |
| Dynamic features (search, forms, comments) | Plugins, instant | Must be re-architected |
Be honest with stakeholders about the right-hand column’s last two rows. The speed and security wins are structural and permanent, but dynamic features do not come along for free — each one needs a deliberate static-era replacement, covered below.
Step 1: Export WordPress Content to Markdown
The most reliable exporter is the wordpress-export-to-markdown CLI, run against the XML file WordPress produces under Tools → Export:
npx wordpress-export-to-markdown \
--input export.xml \
--output content/blog \
--post-folders true \
--year-folders false \
--save-images attached \
--frontmatter-fields title,date,slug,categories,tags,excerptKey flags: --post-folders true gives you Hugo-style page bundles (content/blog/my-post/index.md) with images co-located, and --save-images attached downloads every media-library asset referenced by a post so nothing keeps hotlinking the old /wp-content/uploads/ path.
Expect cleanup. Posts written in the block editor export as tidy Markdown; posts built in Elementor or Divi export as div soup that you will convert by hand or with Pandoc. Budget this honestly — on heavy page-builder sites, cleanup is the single largest line item in the migration.
Step 2: Reproduce Your Permalinks Exactly
The golden rule of migration SEO: the URL that ranks today should still be the URL after cutover. Hugo’s permalink configuration can imitate any WordPress structure:
# hugo.toml — matching WordPress /%postname%/
[permalinks]
blog = "/:slug/"
# or matching /%year%/%month%/%postname%/
# blog = "/:year/:month/:slug/"If you take the opportunity to flatten date-based URLs into clean slugs (usually worth it), every old URL needs a one-hop 301 before launch. Build the redirect map from the old sitemap, not from memory — and wire it at the edge, following the patterns in our guide to canonical URLs and 301 redirect architecture for static sites. Do this before DNS cutover; retrofitting redirects after Google has already crawled a wall of 404s costs you weeks of recovery.
Step 3: Replace the Plugins That Mattered
Roughly five plugin categories carry real user-facing function. Each has a mature static-era answer:
- Forms → an endpoint service (Formspree, Basin) or a Cloudflare Pages Function that relays to email. No PHP mail handler to exploit.
- Search → Pagefind, which indexes your rendered HTML at build time and ships a tiny WASM search UI; no server, no query API.
- Comments → giscus, backed by GitHub Discussions, or drop comments entirely (most business blogs should).
- SEO meta (Yoast/RankMath) → template partials. Titles, meta descriptions, Open Graph, and JSON-LD become explicit code you control, rather than plugin magic.
- Caching/optimization (WP Rocket, Autoptimize) → deleted with no replacement. The entire category exists to mitigate the architecture you just left.
Step 4: Ship, Then Verify the Vitals
Deploy the build output to a static edge host — our breakdown of hosting static sites free on Cloudflare Pages covers the exact build settings for Hugo — and then measure, because the migration’s business case lives in the field data.
What typically moves, and why:
- TTFB collapses because requests never execute code. This is the input to everything downstream.
- LCP improves as render-blocking plugin CSS/JS disappears; a stock Hugo template ships kilobytes where a themed WordPress page ships megabytes.
- CLS approaches zero once ad-injected and plugin-injected late DOM mutations are gone.
- INP improves because the JavaScript main-thread work simply is not there anymore.
Remember that Core Web Vitals field data (CrUX) is a 28-day rolling window measured at the 75th percentile — the Search Console improvement lags the deploy by about a month. Use lab tools for immediate confirmation and the field report for the trend line; our deep-dive on mobile Core Web Vitals optimization covers the target thresholds metric by metric.
The compounding effect is real, though the honest version of it is messier than a straight growth curve. The MarketLens dental-clinic engagement — a Hugo site plus systematic content optimization — began as a recovery, not a launch: organic traffic to that domain had been falling for two years and bottomed out at 725 organic sessions in December 2025. The reversal starts in January 2026. Comparing May–August year over year in Search Console, clicks went from 8,122 to 18,747 (+130.8%) and impressions from 483,969 to 1,047,189 (+116.4%), while mobile average position improved from 23.8 to 8.6. Direct contact actions over January–August rose from 503 to 1,135 (+125.6%), with no paid search spend on the domain. Architecture alone did not do that, and the site had to climb out of a hole first — but architecture is what made every subsequent content improvement land on a site fast enough to convert. The full figures, and the exact queries behind them, are in the dental clinic case study.
The Failure Modes to Design Against
- Orphaned media URLs. Anything still referencing
/wp-content/uploads/breaks the day you decommission the server. Grep the exported Markdown for the string before launch. - Forgotten non-post URLs. Category archives, tag pages, paginated archives, and
/feed/all had inbound links. Map or deliberately 410 them. - Keeping WordPress alive “just in case” at a subdomain. It will get indexed, duplicate every article, and get hacked — the worst of both worlds. Export, archive the database offline, decommission.
- Migrating markup instead of content. Exported page-builder HTML pasted into Markdown files carries the old site’s bloat into the new one. Convert to real Markdown even when it hurts.
Where to Start This Week
Run the export command against a copy of your XML file today — it is read-only and risk-free — and inspect the Markdown quality. That single artifact tells you whether you are facing a two-day cleanup or a two-week one, which is the number every other planning decision hangs on. If you want the full gap analysis first, a MarketLens Standard Audit inventories your current stack’s latency, plugin surface, and URL structure into a migration-ready punch list.
MarketLens