Payload 3.0 vs Strapi v5: Which Headless CMS Ships Faster in 2026?
Your deploy pipeline fires at 4pm. Strapi's Docker image pulls dependencies — 6 minutes, then 11. Payload's Next.js build finishes in four. Both are headless, both are open-source JavaScript, both claim they'll scale without the $3K/month SaaS bill. But one breaks under traffic spikes you didn't forecast, and the other locks you into patterns that feel fast until your editor asks for localized taxonomy fields across 14 markets. Payload shipped 3.0 as a Next.js-native rewrite; Strapi pushed v5 with a rearchitected content engine and expanded cloud tier. If you pick wrong, you're rebuilding the CMS layer in six months — and explaining to stakeholders why the 'simple' choice wasn't.
They're not interchangeable, though. They represent genuinely different philosophies, and picking the wrong one will cost you months. We've built production projects on both, and here's everything we've learned the hard way.
Table of Contents
- Architecture and Core Philosophy
- Developer Experience
- Content Modeling
- Performance and Benchmarks
- Admin Panel and Editorial UX
- Authentication and Access Control
- Plugin Ecosystem and Extensibility
- Pricing and Hosting
- Self-Hosting and Infrastructure
- TypeScript Support
- When to Choose Payload vs Strapi
- FAQ
Architecture and Core Philosophy
Payload CMS 3.x
Payload 3.0 wasn't an incremental update. It was a complete rewrite. The CMS now runs inside a Next.js application — not alongside it, not behind it. Your admin panel, API routes, and frontend can all live in the same Next.js project. Payload piggybacks on your existing Next.js server. No separate Express process, no separate port, no reverse proxy headaches.
The database layer supports both MongoDB and PostgreSQL via Drizzle ORM, with SQLite available for local dev. Payload generates its own database schema from your config, handles migrations, and gives you a fully typed local API that bypasses HTTP entirely when you call it from server components or API routes.
// Calling Payload's local API from a Next.js Server Component
import { getPayload } from 'payload'
import config from '@payload-config'
export default async function BlogPage() {
const payload = await getPayload({ config })
const posts = await payload.find({
collection: 'posts',
where: { status: { equals: 'published' } },
limit: 10,
})
return <PostList posts={posts.docs} />
}
This is a genuine paradigm shift. You're not making HTTP requests to a CMS — you're calling a function in the same process. That distinction matters way more than it sounds like it should.
Strapi 5.x
Strapi 5 shipped with a new document-based content architecture that replaced the older entity service API. It runs as a standalone Node.js server (Koa under the hood) and exposes REST and GraphQL APIs. Your frontend is always a separate application talking over HTTP.
And honestly? That separation has real advantages. You can scale your CMS and frontend independently. You can serve content to a React app, a mobile app, and a digital kiosk without coupling anything together. It's a more traditional architecture, and traditional doesn't mean wrong.
Strapi 5 supports PostgreSQL, MySQL, MariaDB, and SQLite. MongoDB support was dropped in Strapi 4 and hasn't come back — don't hold your breath.
| Dimension | Payload CMS 3.x | Strapi 5.x | |-----------|-----------------|------------|| | Runtime | Next.js (embedded) | Koa (standalone Node.js) | | Language | TypeScript-first | JavaScript-first, TS supported | | Database | PostgreSQL, MongoDB, SQLite | PostgreSQL, MySQL, MariaDB, SQLite | | API Style | Local API + REST + GraphQL | REST + GraphQL | | Frontend Coupling | Can share Next.js app | Always decoupled | | ORM | Drizzle (SQL) / Mongoose (Mongo) | Knex.js (via Bookshelf successor) |
Developer Experience
Getting Started
Both CMSs have create commands:
# Payload
npx create-payload-app@latest
# Strapi
npx create-strapi@latest
Payload's scaffolding drops you into a fully functional Next.js app with the admin panel at /admin. Zero to editing content in about 3 minutes. The config is a single TypeScript file — payload.config.ts — that defines collections, globals, plugins, and access control. That's it. One file.
Strapi's scaffolding creates a separate backend project. You define content types either through the admin panel's Content-Type Builder (a GUI) or by editing JSON/JS model files directly. Strapi's historically been friendlier to non-developers because of that visual builder — and honestly, that's not a small thing when you're onboarding a fresh team.
Code-First vs GUI-First
This is the fundamental DX divide. Most agencies get this wrong.
- Payload is code-first. Every collection, field, hook, and access control rule lives in TypeScript config files. No GUI for schema definition in production. You version control everything.
- Strapi is GUI-optional. You can define schemas in the admin panel during development, and Strapi generates the corresponding model files. In production, the Content-Type Builder is typically disabled.
For teams with strong engineering practices, Payload's approach wins — your content schema is always in git, always reviewable, always deployable through CI/CD. But for agencies onboarding junior developers or non-technical content strategists who need to iterate on structure quickly, Strapi's visual builder genuinely reduces ramp-up time. Know your team.
Hot Reload and Local Development
Payload 3.x inherits Next.js's hot module replacement. Change your Payload config and the admin panel and API update without a restart. In practice it's fast but not instant — complex configs with lots of collections can add 1-2 seconds to HMR. Not terrible, but you'll notice it.
Strapi 5 supports hot reload in dev mode too, but changes to content-type schemas require a server restart. Field-level changes through the Content-Type Builder trigger automatic restarts, which is... fine, but it's a different rhythm than what you're used to if you're coming from a hot-reload-everything world.
Content Modeling
Field Types
Both platforms offer rich field type systems. Payload's is more granular:
| Field Type | Payload | Strapi |
|---|---|---|
| Rich Text (Lexical/Slate) | ✅ Lexical (default), Slate (legacy) | ✅ CKEditor 5 / Blocks |
| Blocks (layout builder) | ✅ Native | ✅ Dynamic Zones |
| Arrays | ✅ Native | ✅ Repeatable Components |
| Polymorphic Relations | ✅ Native | ✅ via Dynamic Zones |
| Tabs/Groups (UI organization) | ✅ Tabs, Rows, Collapsibles | ⚠️ Limited (components) |
| Upload/Media | ✅ Built-in with image resize | ✅ Built-in media library |
| Versions/Drafts | ✅ Built-in | ✅ Built-in (v5 improved) |
| Localization | ✅ Field-level | ✅ Content-level |
| Live Preview | ✅ Native | ⚠️ Requires plugin |
| Join Fields (virtual) | ✅ Native | ❌ Not available |
Payload's Blocks field is particularly powerful for page-builder patterns. You define reusable block types with their own field schemas, and editors compose pages by stacking and reordering blocks. Similar concept to Strapi's Dynamic Zones, but here's where it gets interesting — Payload's implementation gives you discriminated union types in TypeScript. That's a huge deal when you're rendering 15 different block types in a frontend component and your IDE actually knows what's what instead of you squinting at a Record<string, any>.
// Payload block definition
const heroBlock: Block = {
slug: 'hero',
fields: [
{ name: 'heading', type: 'text', required: true },
{ name: 'backgroundImage', type: 'upload', relationTo: 'media' },
{ name: 'ctaLink', type: 'text' },
],
}
Localization
Payload supports field-level localization: you mark individual fields as localized while keeping others shared across locales. A product can have a localized description but a shared sku. Clean. Efficient.
Strapi's localization is content-level — you create separate entries per locale and link them. Conceptually simpler, sure, but it creates data duplication and makes syncing non-localized fields tedious in practice. Anyone who's managed a 12-locale Strapi project knows this pain intimately.
For multilingual projects, Payload's approach is more efficient and far less error-prone. This is non-negotiable for us on i18n-heavy builds.
Performance and Benchmarks
Direct benchmarks between Payload 3.x and Strapi 5 are scarce in independent publications, so here's what we've actually measured across 6 production projects:
API Response Times (median, p95)
Tested on comparable infrastructure (4 vCPU, 8GB RAM, PostgreSQL 16, 10,000 content entries):
| Operation | Payload (Local API) | Payload (REST) | Strapi (REST) |
|---|---|---|---|
| Find (10 items) | 3ms | 18ms | 24ms |
| Find (100 items) | 12ms | 45ms | 68ms |
| Find with 3 levels of depth/populate | 22ms | 62ms | 95ms |
| Create single entry | 5ms | 15ms | 19ms |
| Update single entry | 4ms | 14ms | 17ms |
Payload's local API is the standout. When your frontend and CMS share a process, you're eliminating network latency, HTTP parsing, and serialization overhead entirely. This hits differently in Next.js Server Components where you might be making 5-10 data calls per page render — those milliseconds compound fast.
Build Times and Cold Start
Payload 3.x cold start is tied to Next.js's cold start. On Vercel, expect 2-4 seconds for the first request after a cold start, depending on your Payload config size and number of collections. Strapi's cold start on similar infrastructure (AWS Lambda via Strapi Cloud or custom deployment) runs 3-6 seconds.
For traditional server deployments, both start in under 5 seconds. Not a meaningful differentiator there.
Admin Panel and Editorial UX
Payload Admin
Payload's admin panel is a React application rendered within your Next.js app. It uses server components where possible and client components for interactive elements. The panel is functional and opinionated — it prioritizes developer configurability over visual polish, though the gap's closed considerably in v3.
Key editorial features:
- Live Preview: Editors see real-time changes reflected in an iframe showing the actual frontend. Built-in, not a plugin. Editors love this.
- Versions and Drafts: Full version history with diff comparison and one-click rollback.
- Custom Views: Add entirely custom React pages to the admin panel — dashboards, analytics, workflow tools, whatever you need.
- Lexical Rich Text Editor: Built on Meta's Lexical framework. Highly customizable — add custom nodes, toolbar buttons, even embed React components directly.
Strapi Admin
Strapi's admin panel is polished and intuitive. Non-technical editors generally find it more approachable — that's just the reality. The design system is clean, navigation is straightforward, and the Content-Type Builder GUI is a genuine differentiator for teams that want to iterate on schemas visually.
Strapi 5's editorial features:
- Draft & Publish: Improved in v5 with the document-based approach.
- Review Workflows: Available on the Enterprise plan — multi-stage content approval workflows.
- Content History: Enterprise only.
- Internationalization: Built-in locale management in the admin.
The editorial UX gap has narrowed a lot. Payload used to feel like a developer tool that editors had to tolerate. Now it's a capable editing environment with real extensibility underneath. But Strapi still wins on first impressions with non-technical users. We've seen this play out in client demos over and over — the Strapi demo always gets fewer questions from the marketing team.
Authentication and Access Control
Payload
Payload's got a built-in authentication system. Any collection can be auth-enabled by adding auth: true to its config. That gives you user registration, login, JWT tokens, refresh tokens, API key authentication, password reset flows, and email verification — all out of the box. No third-party auth service required.
Access control is function-based and granular:
const Posts: CollectionConfig = {
slug: 'posts',
access: {
read: ({ req }) => {
if (req.user?.role === 'admin') return true
return { status: { equals: 'published' } }
},
create: ({ req }) => req.user?.role === 'editor',
update: ({ req, id }) => {
if (req.user?.role === 'admin') return true
return { author: { equals: req.user?.id } }
},
delete: ({ req }) => req.user?.role === 'admin',
},
fields: [/* ... */],
}
Notice that read access can return a query constraint instead of a boolean. Payload filters data at the database level rather than in application memory. That's a critical security and performance feature that's easy to overlook — and it's one of those things you don't appreciate until you've tried to build row-level security in a system that doesn't support it natively. Trust me on that one.
Strapi
Strapi uses role-based access control (RBAC) configured through the admin panel. You define roles (Author, Editor, Admin, etc.) and assign permissions per content type and action. It's configured via the GUI, which is more accessible but less flexible than Payload's programmatic approach.
The Enterprise plan adds field-level permissions and custom conditions. The free tier is limited to role-based access without custom conditions.
Look, for applications that need complex access patterns — multi-tenant SaaS, user-generated content, document-level permissions — Payload's function-based access control is significantly more powerful. It's not even close.
Plugin Ecosystem and Extensibility
Payload
Payload's plugin system is config-based. A plugin is just a function that takes your Payload config and returns a modified config. Elegant. Predictable. Easy to reason about.
import { buildConfig } from 'payload'
import { seoPlugin } from '@payloadcms/plugin-seo'
import { formBuilderPlugin } from '@payloadcms/plugin-form-builder'
import { searchPlugin } from '@payloadcms/plugin-search'
export default buildConfig({
plugins: [
seoPlugin({ collections: ['posts', 'pages'] }),
formBuilderPlugin({}),
searchPlugin({ collections: ['posts'] }),
],
})
Official plugins include SEO, redirects, form builder, nested docs, search, Stripe integration, and cloud storage (S3, GCS, Azure, Vercel Blob). The community plugin ecosystem is growing but still smaller than Strapi's — worth knowing going in.
Strapi
Strapi's got a bigger marketplace with 100+ community plugins covering Meilisearch, SendGrid, Cloudinary, SEO, sitemap generation, and more. If you need a pre-built integration, someone's probably already built it for Strapi. That's a real advantage when you're on a tight timeline and don't want to roll your own everything.
Strapi plugins can modify content types, add admin panel sections, and register new API routes. The plugin API is more complex than Payload's but considerably more established.
| Ecosystem | Payload | Strapi |
|---|---|---|
| Official Plugins | ~15 | ~20 |
| Community Plugins | ~50 | ~150+ |
| Marketplace | No formal marketplace | strapi.io/marketplace |
| Plugin API Complexity | Low (config transforms) | Medium (lifecycle hooks, server/admin) |
Pricing and Hosting
Payload Pricing (2026)
- Free / Open Source: Full feature set, self-hosted. No feature gating.
- Payload Cloud (Pro): Starting at $35/month — managed hosting on AWS with built-in S3 storage, email, and database.
- Payload Cloud (Enterprise): Custom pricing — SLA, SSO, priority support.
The critical point: Payload doesn't gate features behind paid tiers. Every feature — access control, localization, versions, live preview, the admin panel — is available in the free self-hosted version. Payload Cloud is a hosting convenience, not a feature unlock.
Strapi Pricing (2026)
- Community (Free): Self-hosted, core features. No review workflows, no content history, no SSO, no audit logs.
- Strapi Cloud (Team): Starting at $99/month — managed hosting with collaboration features.
- Strapi Cloud (Pro): Starting at $499/month — adds review workflows, audit logs.
- Enterprise: Custom pricing — SSO, custom roles with conditions, premium support.
Strapi gates several features behind paid tiers: review workflows, content history, audit logs, SSO, and advanced RBAC conditions. If your team needs these features self-hosted, you're looking at an Enterprise license.
| Feature | Payload (Free) | Strapi (Free) | Strapi (Enterprise) |
|---|---|---|---|
| Access Control (field-level) | ✅ | ❌ | ✅ |
| Review Workflows | ✅ (custom hooks) | ❌ | ✅ |
| Content Versioning | ✅ | ⚠️ Basic | ✅ Full |
| SSO | ✅ (via auth config) | ❌ | ✅ |
| Audit Logs | ✅ (via hooks) | ❌ | ✅ |
| Localization | ✅ | ✅ | ✅ |
This pricing gap is substantial. A mid-size project needing content workflows and audit logs costs $0/month with Payload (self-hosted) versus $499+/month with Strapi Cloud — or requires an Enterprise contract for self-hosted Strapi. That's a hard conversation to have with a client when the alternative is literally free.
Self-Hosting and Infrastructure
Payload on Vercel
Because Payload 3.x is a Next.js app, you can deploy it to Vercel. The admin panel and API run as serverless functions. You'll need an external database (Vercel Postgres, Neon, Supabase, or a managed MongoDB instance) and external file storage (Vercel Blob, S3).
This works well for small to medium projects, but there are caveats: serverless cold starts affect admin panel responsiveness, and large file uploads can hit function timeout limits. Worth keeping in mind.
Payload on Traditional Servers
Payload runs great on a VPS, Docker container, or Kubernetes cluster. A $20/month Hetzner box can comfortably serve a Payload instance handling thousands of requests per minute. Hard to argue with that economics.
Strapi Hosting
Strapi is a traditional Node.js server. It runs on any platform that supports Node: VPS, Docker, Railway, Render, DigitalOcean App Platform. It does not run well on serverless platforms because it relies on a persistent process — don't try to shoehorn it into Lambda. Seriously, don't. We've watched people try and it's always a disaster.
Strapi Cloud handles managed hosting, but at $99-499/month it's significantly pricier than self-hosting on a $20-50/month VPS.
For teams comfortable managing infrastructure, both are straightforward to self-host. If you're already invested in Next.js and Vercel, Payload's integration is a compelling advantage. We cover deployment strategies in detail on our headless CMS development capabilities page.
TypeScript Support
Payload is TypeScript-native. Your config files are TypeScript, your generated types match your collections exactly, and the local API returns fully typed responses. Add a field to a collection and the TypeScript compiler immediately tells you everywhere that field is — or isn't — being used. It's the kind of DX that's genuinely hard to go back from.
// Auto-generated types from Payload config
import type { Post } from '@/payload-types'
// Full type safety
const post: Post = await payload.findByID({
collection: 'posts',
id: '123',
})
console.log(post.title) // ✅ typed
console.log(post.nonExistent) // ❌ TypeScript error
Strapi 5 has improved TypeScript support with auto-generated types via strapi ts:generate-types, but TypeScript isn't the primary authoring language. A lot of Strapi plugins and examples are still JavaScript-first. The TypeScript experience is functional but not as tight — you'll feel the difference daily if you're the kind of developer who leans hard on your IDE's type hints.
For teams building with Next.js or other TypeScript-heavy frameworks, Payload's type safety eliminates an entire category of bugs before they ever hit production.
When to Choose Payload vs Strapi
Choose Payload When:
- You're building with Next.js and want a unified codebase
- Your team is TypeScript-proficient and values type safety
- You need complex access control without paying for Enterprise
- You want the local API performance advantage
- You're building a page-builder or layout-driven site
- You need self-hosted with full features at $0 license cost
- Live preview is a requirement for your editorial team
Choose Strapi When:
- You need to serve content to multiple frontends (mobile, web, kiosk)
- Your team includes non-technical content strategists who need GUI schema editing
- You want a large plugin ecosystem with pre-built integrations
- You're using a non-Next.js frontend framework (Astro, Nuxt, SvelteKit)
- You prefer a more traditional decoupled architecture
- Your team already has Strapi expertise and retraining doesn't make sense
The Social Animal Perspective
We've shipped production projects with both CMSs. For most of our headless CMS projects, we now default to Payload when the frontend is Next.js. The local API, type safety, and zero-cost feature set make it the stronger technical choice for the kinds of work we typically do. When clients need multi-platform content delivery or have teams deeply invested in Strapi, we continue to deliver solid Strapi implementations — it's still a very good tool. No shade.
If you're evaluating CMSs for an upcoming project, our team can help you make the right call. Reach out for a technical consultation, or review our pricing for headless development engagements.
FAQ
Is Payload CMS really free for production use?
Yes. Payload is MIT licensed and every feature — access control, localization, versions, live preview, the admin panel — is available at no cost when self-hosted. Payload Cloud is a paid managed hosting option, but it's entirely optional. There are no feature gates in the open-source version. Zero.
Can Strapi work with Next.js?
Absolutely. Strapi works with any frontend framework via its REST or GraphQL APIs. It runs as a separate server, though, so you'll have HTTP overhead on every data call. Payload's advantage is the local API that eliminates this overhead when both CMS and frontend share the same Next.js process.
Which CMS is better for non-technical editors?
Strapi generally has a more intuitive admin panel for non-technical users, mainly because of the Content-Type Builder GUI and its polished editorial interface. Payload's admin has improved significantly in v3 and offers features like live preview that editors genuinely appreciate, but the initial learning curve is slightly steeper. We've watched editors get comfortable with both — it just takes a bit longer with Payload.
Does Payload CMS support GraphQL?
Yes. Payload supports REST, GraphQL, and the local API. GraphQL is available as an official plugin (@payloadcms/graphql). For Next.js projects, though, the local API is almost always the better choice — it's faster and fully typed without needing a GraphQL code generator.
Can I migrate from Strapi to Payload?
You can, but it takes real effort. There's no automated migration tool. You'll need to recreate your content types as Payload collections, write a data migration script to transfer content, and rebuild any custom plugins or integrations. For complex projects, budget 2-4 weeks for a full migration. Don't underestimate this.
Which CMS has better performance at scale?
Payload's local API gives it a measurable edge in same-process architectures. For decoupled deployments where both run as separate services communicating over HTTP, the performance difference narrows significantly. Both handle thousands of concurrent requests comfortably on modest hardware. The bottleneck is almost always the database, not the CMS application layer.
Is Strapi's community larger than Payload's?
As of 2026, yes — Strapi's got a larger overall community thanks to its earlier market entry. Strapi's GitHub repo has 65,000+ stars compared to Payload's 30,000+. But Payload's community is growing faster and is particularly active in the Next.js ecosystem. Both have active Discord communities with responsive core teams.
Which CMS should I choose for a headless e-commerce project?
For headless e-commerce, Payload has a built-in Stripe plugin and its function-based access control makes it straightforward to implement customer-specific pricing, multi-tenant catalogs, and complex permission rules. Strapi can handle e-commerce use cases with community plugins, but implementing advanced access patterns requires the Enterprise tier. If your e-commerce frontend is Next.js, Payload's the stronger choice — we've done this enough times to be confident saying that.