Payload vs Directus: Which Headless CMS to Self-Host?
Quick Verdict
Directus is the better choice for most self-hosters. It pulls as a single Docker image, connects to any existing SQL database, and provides an instant API and admin panel — no code required. Payload is better for TypeScript teams who want the CMS to be part of their codebase, but it requires building a custom Docker image and managing a Next.js build pipeline.
Overview
Both are modern headless CMSs, but they take fundamentally different approaches.
Directus is a database-first CMS. Point it at a PostgreSQL, MySQL, or SQLite database, and it generates a REST + GraphQL API plus a polished admin panel automatically. It wraps your existing database — you can use the same database with other tools, run raw SQL queries, and even use Directus alongside a hand-built backend.
Payload is a code-first CMS framework. You define content models in TypeScript inside a Next.js project. Payload generates the database schema, APIs, and admin panel from your code. It’s not a standalone application — it’s a library you install into your project.
| Aspect | Payload | Directus |
|---|---|---|
| Architecture | Code-first (TypeScript definitions) | Database-first (schema introspection) |
| Framework | Built on Next.js | Standalone Node.js application |
| Language | TypeScript (strict) | JavaScript/TypeScript |
| Docker image | None (custom build required) | Official (directus/directus:11.5) |
| Database support | PostgreSQL, MongoDB, SQLite | PostgreSQL, MySQL, SQLite, MS SQL, MariaDB, CockroachDB |
| API | REST + GraphQL | REST + GraphQL |
| License | MIT | BSL 1.1 (converts to GPLv3 after 3 years) |
| GitHub stars | 40,000+ | 29,000+ |
Feature Comparison
| Feature | Payload | Directus |
|---|---|---|
| Admin panel | React-based, customizable | Vue.js-based, highly customizable |
| Content modeling | TypeScript config file | Visual UI or raw SQL |
| Authentication | Built-in (JWT, HTTP-only cookies) | Built-in (JWT, session, SSO) |
| Access control | Document and field-level | Role-based with custom permissions |
| Versioning/drafts | Built-in | Built-in |
| Localization | Built-in (multi-language) | Built-in (content translations) |
| Rich text editor | Lexical (block-based) | WYSIWYG, Markdown, or custom |
| File storage | Local, S3, Azure, GCS | Local, S3, Azure, GCS, Cloudflare R2 |
| Webhooks | Built-in | Built-in |
| Flows/automation | Via hooks (code) | Visual flow builder (no-code) |
| Live preview | Built-in (Next.js integration) | Via extensions |
| Search | Built-in | Extension required |
| Import/export | Via API | Built-in UI for CSV/JSON |
| Marketplace | Plugin system | Extension marketplace |
Installation Complexity
Directus deploys in under 5 minutes:
services:
directus:
image: directus/directus:11.5.0
ports:
- "8055:8055"
environment:
SECRET: changeme-openssl-rand-hex-32
DB_CLIENT: pg
DB_HOST: db
DB_PORT: "5432"
DB_DATABASE: directus
DB_USER: directus
DB_PASSWORD: changeme
ADMIN_EMAIL: [email protected]
ADMIN_PASSWORD: changeme
depends_on:
- db
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: directus
POSTGRES_USER: directus
POSTGRES_PASSWORD: changeme
volumes:
- db-data:/var/lib/postgresql/data
Run docker compose up -d and it works. No build step. No configuration files. Schema changes happen through the admin UI or API.
Payload requires a project, a Dockerfile, and a build:
- Scaffold a Next.js project with
create-payload-app - Define collections in
payload.config.ts - Write a multi-stage Dockerfile
- Run
docker compose up -d --build(2–4 minute build) - Rebuild after every schema change
See our Payload CMS setup guide for the full configuration.
Performance and Resource Usage
| Metric | Payload | Directus |
|---|---|---|
| RAM (idle) | 300–500 MB | 200–400 MB |
| RAM (under load) | 500 MB – 1.5 GB | 300 MB – 1 GB |
| Cold start | 10–30 seconds (Next.js init) | 3–5 seconds |
| Build time | 2–4 minutes | None (pre-built image) |
| Disk (application) | ~500 MB (with node_modules) | ~300 MB |
Directus is lighter because it’s a standalone Node.js server without the Next.js compilation layer. Payload’s build-time requirement adds complexity and resource usage during deployments.
Community and Support
| Metric | Payload | Directus |
|---|---|---|
| GitHub stars | 40,000+ | 29,000+ |
| Community | Discord, GitHub (active) | Discord, GitHub (active) |
| Documentation | Good (official docs) | Excellent (comprehensive) |
| Commercial support | Payload Cloud (optional) | Directus Cloud (optional) |
| Update frequency | Weekly | Monthly |
| Contributors | 800+ | 500+ |
Both have active, helpful communities. Payload’s documentation assumes TypeScript knowledge. Directus’s documentation is more accessible to non-developers because the product itself is more accessible to non-developers.
Use Cases
Choose Payload If…
- Your team writes TypeScript and wants type-safe content models
- You’re building a Next.js application and want the CMS integrated into the same codebase
- You need live preview of content changes in your frontend
- You want document-level and field-level access control defined in code
- You prefer defining schemas in code over a GUI
Choose Directus If…
- You want a headless CMS running in minutes without writing code
- Non-developers need to manage content and define new collections
- You need to wrap an existing database with an API without rebuilding your backend
- You want a visual automation flow builder (no-code)
- You need broad database support (MySQL, MariaDB, MSSQL in addition to PostgreSQL)
- Docker simplicity matters — official image, no custom builds
Final Verdict
For self-hosting, Directus wins on operational simplicity. It pulls as a Docker image, starts instantly, and lets you model content through a web UI. Schema changes don’t require rebuilding anything. Non-technical team members can manage content independently.
Payload wins on developer experience. If your team already uses TypeScript and Next.js, having the CMS as part of the codebase means type-safe content access, co-located preview, and a single deployment pipeline. The trade-off is that every schema change requires a rebuild, and there’s no official Docker image.
Pick Directus if you want a CMS that works like a service. Pick Payload if you want a CMS that works like a framework.
Related
- How to Self-Host Payload CMS with Docker Compose
- How to Self-Host Directus with Docker Compose
- How to Self-Host Strapi with Docker Compose
- Directus vs Strapi: Best Headless CMS
- Strapi vs Directus vs Payload: Headless CMS Showdown
- Best Self-Hosted CMS Platforms
- Self-Hosted Alternatives to Squarespace
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments