In late 2022 a SaaS marketing team I was advising decided their WordPress site felt “dated.” Their PageSpeed score was 78. Their LCP was 2.4 seconds. Their conversion rate was healthy. Nothing was actually wrong. But Vercel had just launched another round of beautiful conference talks, the engineering team had two bored React developers, and the CMO had read three Medium posts that weekend about JAMstack. So they migrated to headless: Next.js on Vercel, WordPress as a content backend, WPGraphQL, ISR for revalidation, the full stack.

Eight months later I got the call. Editors hated previews. The build pipeline broke whenever someone changed a hero image. Their hosting bill had gone from $40 to $420 a month. Two engineers were spending six hours a week each keeping the integration glued together. Their LCP was 1.6 seconds — an improvement, but nowhere near worth the operational cost. By March 2024 they had migrated back to traditional WordPress with WP Rocket and Cloudflare APO. Today: LCP 1.7 seconds. Hosting $55/month. Engineers doing actual product work.

Headless WordPress hype peaked around 2021–2023. By 2026 we have enough longitudinal data to say it cleanly: headless is the right architecture for roughly 5% of WordPress sites and the wrong one for the other 95%. Most teams who went headless came back. This piece is the decision framework I wish someone had handed them.

What “headless WordPress” actually is

In a headless setup, the WordPress install keeps doing what it does well: storing content, providing the admin UI, managing users, handling media. What it stops doing is rendering the public site. That job moves to a separate frontend application, usually JavaScript or TypeScript, deployed on a different host.

Communication happens over HTTP. WordPress exposes content through one of two APIs:

  • The REST API — built into core since 4.7. Endpoints like /wp-json/wp/v2/posts return JSON. No plugin required.
  • WPGraphQL — a plugin that adds a GraphQL endpoint. Lets you query nested fields and avoid over-fetching. More flexible, but it’s a third-party plugin to maintain.

On the frontend the popular choices in 2026 are Next.js, Astro, Nuxt, and SvelteKit. Gatsby technically still exists but Netlify quietly stopped active maintenance in 2024 — do not start a new project on it.

Shorthand: in traditional WordPress you have one stack to deploy, monitor, secure, and back up. In headless you have two. That is the entire architectural tradeoff in one sentence.

When headless is and isn’t the right call

When it actually makes sense

I’m not anti-headless. I’ve built and operated both. The second stack pays for itself when:

  • Performance is a measurable business metric. Not “we want better scores.” I mean every 100ms of LCP correlates to a percentage point of conversion you can graph. Mostly large publishers and ecommerce, where 1.2s vs 2.0s is worth real money.
  • You ship the same content to multiple channels. The website is one consumer of your API. Mobile apps, partner feeds, email systems, digital signage all consume it too. WordPress feeding three or more channels is what headless was designed for.
  • Your frontend has heavy interactive components. A learning platform with progress tracking, a configurator with live pricing, deep data visualizations layered over editorial content. WordPress themes aren’t built for this; React, Vue, or Svelte are.
  • You already have a frontend engineering team. Plural. With CI/CD, monitoring, on-call, and the ability to debug a Next.js memory leak in production. Headless is a tax on engineering capacity. No capacity, no tax.
  • Core Web Vitals are blocking deals. If a Fortune 500 vendor review literally checks your Lighthouse scores, hitting 95+ on every metric is a measurable reason. Most teams don’t have that constraint.

Notice what’s missing: “modern,” “developer experience,” “future-proofing,” “Vercel is fast.” Those are sentiments. Sentiments don’t pay your hosting bill.

When it does not make sense

This list covers most sites I look at:

  • Most marketing sites. A well-tuned WordPress with WP Rocket, Cloudflare, and a lightweight theme like Kadence sits under 2.0s LCP and 100ms INP. Fast enough.
  • Teams without dedicated frontend engineers. If “the developer” is your agency’s WordPress freelancer, going headless triples the surface area they maintain.
  • Sites where editor experience matters more than Lighthouse scores. Editors need to publish, preview, fix typos, and drop in an image without filing a Jira ticket. Headless makes all four harder.
  • Sites that rely on plugins with frontend rendering. Gravity Forms, MemberPress, LearnDash, BuddyBoss, WooCommerce checkout, Beaver Builder, Elementor — all render in PHP. They break or require custom adapters in headless.
  • Anything WooCommerce. Headless WooCommerce exists. It is a special level of pain. Keep WooCommerce on traditional WordPress unless you have a strong reason.
  • Small teams without DevOps capacity. Two stacks means two CI pipelines, two CDNs to invalidate, two error tracking systems, two domains to renew, multiplied by every dependency upgrade.

The operational tradeoffs nobody puts in the marketing copy

Case studies on Vercel and Netlify show the happy path: green Lighthouse scores, a quote from a CTO. They don’t show what daily operations actually look like.

Previews are much harder

Traditional WordPress: editor clicks “Preview,” sees their draft. It just works. Headless: “Preview” means hitting a custom preview route that fetches draft content via an authenticated API call, with a separate token, caching disabled, often a different URL the editor has to bookmark. A working preview pipeline is two to five days of engineering plus ongoing maintenance every time frameworks or hosting change.

Many WordPress plugins partially or fully break

Yoast SEO outputs meta tags via PHP filters on the WordPress frontend. In headless those tags need to be re-emitted in your <head>. Yoast exposes the data via REST and WPGraphQL, but you read and render it yourself. Same for Rank Math.

Gravity Forms shortcodes don’t exist on a static frontend. You either iframe them (ugly, accessibility issues) or rebuild each form in React using their REST API. MemberPress and Restrict Content Pro assume PHP runs on every request — you have to recreate the access logic in your frontend with a custom auth flow.

Visual page builders — Elementor, Beaver Builder, Divi, Bricks — are essentially incompatible. They store layout markup in a way that’s opaque to the REST API. Give them up or don’t go headless.

Build and deploy pipelines become first-class infrastructure

Every content change can trigger a frontend rebuild. Pure SSG: a 2,000-page site takes 4–15 minutes to rebuild on Vercel. With ISR or on-demand revalidation you avoid full rebuilds, but the webhooks, secret tokens, and retry logic are real engineering work. I’ve seen builds queue up for an hour on heavy editorial days.

Caching gets multi-layered and confusing

You now have WordPress object cache, an API response cache, the CDN edge cache for the frontend, the frontend framework’s data cache, and the browser cache. Invalidation bugs cost a Friday afternoon every couple of months.

You pay for two hosts now

Straightforward but people forget it. WordPress still lives somewhere. The frontend lives somewhere. Both bills are real.

The data: cost and performance

Cost comparison, with real numbers

This is for a content site doing roughly 50,000 monthly active users, mostly editorial pages, modest API traffic. Numbers based on production deployments I’ve seen or run myself in the last 18 months.

Setup Hosting (mo) Annual Engineer ops/week Realistic LCP
Traditional WP, shared host, no caching $10–15 $120–180 0–1 hr 4–8s
Traditional WP + WP Rocket + Cloudflare APO $30–50 $360–600 1–2 hr 1.5–2.5s
Cloudways WP backend + Astro on Cloudflare Pages ~$80 ~$1,000 3–5 hr 0.9–1.5s
Headless: WP + Next.js on Vercel Pro $200–500 $2,400–6,000 5–10 hr 0.8–1.4s
Headless at 1M MAU on Vercel $800–1,500 $9,600–18,000 8–15 hr 0.8–1.4s

The dollars aren’t the whole story. The engineer-ops column is what quietly destroys budgets. At $120k loaded, ten hours a week of headless maintenance is roughly $30,000/year of capacity you no longer have for product work. That’s the line item nobody includes in the migration pitch.

What the performance numbers actually look like

The marketing claim is that headless is dramatically faster. The reality is more nuanced. From dozens of sites I’ve measured:

  • Headless, Astro or Next.js, well-optimized: LCP 0.8–1.5s, INP under 100ms, FCP under 1.0s. Genuinely excellent.
  • Traditional WP + WP Rocket + Cloudflare APO: LCP 1.5–2.5s, INP 100–200ms, FCP 1.0–1.6s. Solidly “Good” in Core Web Vitals terms.
  • Traditional WP, no optimization: LCP 4–8s, INP 400ms+, FCP 3s+. Legitimately bad.

The gap between headless and traditional-with-caching is usually under a second on LCP. The gap between headless and default-WordPress-with-no-caching is huge, but that’s a caching problem, not an architecture problem. You don’t need a new architecture; you need WP Rocket and a CDN.

Headless isn’t a performance solution; it’s an architecture choice for teams that already have engineering capacity to spare.

The stack picks that are actually current in 2026

Next.js + WordPress

The most popular pairing, biggest ecosystem, most tutorials. Best for sites that need SSR, ISR, and complex routing. Tradeoff: Next.js is opinionated and the App Router has a meaningful learning curve. Engineers who don’t already know React will be slow for the first month. Vercel hosting is excellent but expensive at scale.

Astro + WordPress

My default recommendation for content-heavy headless sites. Astro mixes static generation, on-demand SSR, and selectively-hydrated “islands” in one project. Output is mostly static HTML, which makes hosting cheap and fast. Smaller community than Next.js, but DX is excellent and build times are 3–5x faster on similar-sized sites. Cloudflare Pages or Netlify are natural targets.

Faust.js

Maintained by WP Engine, a thin opinionated layer over Next.js + WPGraphQL. Less boilerplate, decent preview pipeline out of the box. Tradeoff: tied to WP Engine’s pace, small community. Reasonable choice if you’re already on WP Engine.

Frontity

Dead. Maintenance ended in 2022. Ignore tutorials recommending it.

The decision framework

Run your situation through this matrix. If the recommendation says “Traditional,” stop reading the headless docs and go install WP Rocket.

Site type Traffic Team Recommendation
SaaS marketing site <100k MAU 1 dev, 1 marketer Traditional WP + caching
Content publisher 500k+ MAU 2+ frontend engineers Headless, lean Astro
Agency portfolio any Designer-led, no engineers Traditional WP, full stop
Ecommerce / WooCommerce any any Traditional WP
Membership / LMS site any any Traditional WP
Multi-channel publisher (web + mobile + email + partner feeds) any 2+ engineers, dedicated DevOps Headless, Next.js or Astro
Dev tools / API company blog 50k–500k MAU Engineering-led Reasonable case for headless Astro
Local business site <10k MAU Owner-operated Traditional WP, cheapest managed plan
News site, real-time editorial 1M+ MAU Full eng team + ops Headless if Core Web Vitals are tracked KPIs
Personal blog any Solo Traditional WP, please
Going headless to fix a slow site is like buying a Tesla to fix your commute when you haven’t tried leaving 10 minutes earlier. Try caching first. If your default WordPress install is slow, the answer is almost never a new architecture — it’s WP Rocket, an image CDN, and Cloudflare. You can install all three in an afternoon for under $80/year. The headless migration will take three months and cost ten times that. Solve the cheap problem first.

Alternatives and a look at the code

What to try before you go headless

Most “we need headless for performance” conversations should start here. These get you 70–80% of the speed benefit at maybe 5% of the operational cost.

  • Server-level full-page caching. WP Rocket + Cloudflare APO, or LiteSpeed Cache if your host supports it. Usually cuts LCP in half.
  • An image CDN with format conversion. Bunny.net, Cloudflare Images, ImageKit. Serves WebP/AVIF, resizes on the fly, offloads bandwidth.
  • A lighter theme. Replace Elementor or Divi with Kadence, GeneratePress, or Blocksy. Theme weight is a top cause of slow sites and nobody measures it.
  • Better hosting. Move from $4 shared to a $30–50/mo managed plan or Cloudways. TTFB difference alone is often 600ms.
  • A real database audit. Query Monitor, Object Cache Pro or Redis, and pruning autoloaded options. WordPress sites often have multi-megabyte autoloads bloating every request.

I’ve taken sites from 6.5s LCP to 1.6s using only this list. Zero architecture changes. Two weeks of work.

A small look at the actual code

For teams that have run the framework above and genuinely want to go headless, here’s the basic shape of fetching content from WordPress in a frontend app. This is the REST API version — no plugins required.

// app/lib/wp.ts
const WP_API = process.env.WP_API_URL; // e.g. https://cms.example.com/wp-json/wp/v2

export async function getPosts({ page = 1, perPage = 10 } = {}) {
  const url = new URL(`${WP_API}/posts`);
  url.searchParams.set('per_page', String(perPage));
  url.searchParams.set('page', String(page));
  url.searchParams.set('_embed', 'wp:featuredmedia,author');

  const res = await fetch(url, {
    next: { revalidate: 300 }, // ISR: refresh every 5 minutes
  });

  if (!res.ok) {
    throw new Error(`WP fetch failed: ${res.status}`);
  }

  const total = Number(res.headers.get('X-WP-Total') ?? 0);
  const posts = await res.json();
  return { posts, total };
}

export async function getPostBySlug(slug: string) {
  const url = new URL(`${WP_API}/posts`);
  url.searchParams.set('slug', slug);
  url.searchParams.set('_embed', 'wp:featuredmedia,author');

  const res = await fetch(url, { next: { revalidate: 60 } });
  if (!res.ok) throw new Error(`WP fetch failed: ${res.status}`);

  const [post] = await res.json();
  return post ?? null;
}

Looks clean. What this code doesn’t show: the webhook from WordPress that triggers res.revalidate on publish; the preview route that uses an authenticated nonce; the Yoast meta-tag re-emission; the error handling for when the WordPress origin is down; the cache-poisoning protection on your CDN. All of those are real production work. Plan for two engineers over six to eight weeks, minimum, to ship a headless WordPress site you actually trust in production.

The team that came back: a composite story

I’ve worked with or talked to enough teams in this situation that I can write the composite arc with confidence. None of these are real company names; the pattern is real.

A B2B SaaS company with ~60,000 monthly visitors migrated to Next.js + WordPress + WPGraphQL in mid-2022. Pre-migration: managed WordPress on Kinsta, $40/month, LCP 2.4s. The migration took four months of part-time work for two engineers. Post-launch: LCP dropped to 1.3s, Lighthouse hit 96. They celebrated.

Then the bills arrived:

  • Vercel Pro plus traffic overages: $280–420/month, climbing with traffic.
  • WPGraphQL maintenance: a major version every quarter, each requiring a frontend code update.
  • Editor preview pipeline broke after a Next.js version bump. Fix took three days. Editors used staging meanwhile, which they hated.
  • Build times grew from 90 seconds to 12 minutes as the site grew.
  • A Yoast update changed how a meta field was returned via REST. Title tags broke for a day before anyone noticed.
  • Combined engineering ops settled at ~6 hours a week between two engineers, sustained.

By Q3 2023 the CMO and CTO looked at the data. Six engineering hours/week is ~$30k/year of opportunity cost. Hosting had gone from $40 to over $400. The actual user-facing improvement was 1.1 seconds of LCP — meaningful but not transformational, especially with no evidence it was moving conversion.

They migrated back. Cloudways, WP Rocket, Cloudflare APO, pruned three heavy plugins. Two weeks of work, mostly content sync. New LCP: 1.7s. Hosting: $55/month. Engineer time: under an hour a week. The frontend repo got archived; those two engineers shipped a real product feature the next quarter.

This story is more common than the success stories. The case studies don’t come back and post a follow-up.

Common mistakes when teams go headless anyway

  • Going headless because “Vercel is cool.” A vibe is not a business case. The Vercel post that excited you ran on someone else’s budget.
  • Underestimating ongoing maintenance. Launch is easy. The hard part is keeping the integration working through 18 months of WordPress updates, framework upgrades, plugin changes, and Node version bumps.
  • Forgetting WordPress plugins won’t work the same way. Yoast meta, Gravity Forms, MemberPress, page builders, schema plugins, related-posts widgets, breadcrumbs — all need adapters or replacements. Audit before you commit.
  • Not budgeting for the second hosting bill. You still pay for WordPress; you also pay for the frontend. Vercel feels free at low traffic, then a viral post pushes the monthly bill from $20 to $700.
  • Not planning for the editor preview workflow. If editors can’t preview in 30 seconds, they route around the system — Google Docs, manual deploys, or bypassing the CMS entirely.
  • Skipping the “try caching first” step. Without testing WP Rocket + Cloudflare APO on the existing site, you don’t know whether headless is solving a real problem or an imagined one.

My opinion, said plainly

For 95% of WordPress sites, the right answer in 2026 is boring. Stay on traditional WordPress. Get good managed hosting (Kinsta, WP Engine, or Cloudways). Install WP Rocket and put Cloudflare APO in front of it. Use a lightweight theme. Audit your plugins and remove what you don’t use. Move images to a real CDN. Spend the time you would have spent on a headless migration writing better content. You’ll be fast enough, simple enough, cheap enough.

For the 5% that genuinely need headless — large publishers, multi-channel shops, sites where Core Web Vitals are tracked business KPIs, teams with full frontend capacity — pick carefully. Astro for content sites. Next.js for app-like experiences. Vercel if budget isn’t tight, Cloudflare Pages or Netlify if it is. Build a real preview pipeline before launch, not after. Document the integration so the next engineer can debug it at 2am.

Wrong reasons to go headless: “modern,” “developer experience,” “Lighthouse scores,” “future-proofing,” “the marketing team is bored.” Right reasons: “we have a frontend team,” “Core Web Vitals are blocking enterprise deals,” “we ship the same content to three or more channels.”

If you can’t name one of those right reasons clearly when asked, you’re not in the 5%. Stay with WordPress. It’s allowed to be enough.