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.

AspectPayloadDirectus
ArchitectureCode-first (TypeScript definitions)Database-first (schema introspection)
FrameworkBuilt on Next.jsStandalone Node.js application
LanguageTypeScript (strict)JavaScript/TypeScript
Docker imageNone (custom build required)Official (directus/directus:11.5)
Database supportPostgreSQL, MongoDB, SQLitePostgreSQL, MySQL, SQLite, MS SQL, MariaDB, CockroachDB
APIREST + GraphQLREST + GraphQL
LicenseMITBSL 1.1 (converts to GPLv3 after 3 years)
GitHub stars40,000+29,000+

Feature Comparison

FeaturePayloadDirectus
Admin panelReact-based, customizableVue.js-based, highly customizable
Content modelingTypeScript config fileVisual UI or raw SQL
AuthenticationBuilt-in (JWT, HTTP-only cookies)Built-in (JWT, session, SSO)
Access controlDocument and field-levelRole-based with custom permissions
Versioning/draftsBuilt-inBuilt-in
LocalizationBuilt-in (multi-language)Built-in (content translations)
Rich text editorLexical (block-based)WYSIWYG, Markdown, or custom
File storageLocal, S3, Azure, GCSLocal, S3, Azure, GCS, Cloudflare R2
WebhooksBuilt-inBuilt-in
Flows/automationVia hooks (code)Visual flow builder (no-code)
Live previewBuilt-in (Next.js integration)Via extensions
SearchBuilt-inExtension required
Import/exportVia APIBuilt-in UI for CSV/JSON
MarketplacePlugin systemExtension 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:

  1. Scaffold a Next.js project with create-payload-app
  2. Define collections in payload.config.ts
  3. Write a multi-stage Dockerfile
  4. Run docker compose up -d --build (2–4 minute build)
  5. Rebuild after every schema change

See our Payload CMS setup guide for the full configuration.

Performance and Resource Usage

MetricPayloadDirectus
RAM (idle)300–500 MB200–400 MB
RAM (under load)500 MB – 1.5 GB300 MB – 1 GB
Cold start10–30 seconds (Next.js init)3–5 seconds
Build time2–4 minutesNone (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

MetricPayloadDirectus
GitHub stars40,000+29,000+
CommunityDiscord, GitHub (active)Discord, GitHub (active)
DocumentationGood (official docs)Excellent (comprehensive)
Commercial supportPayload Cloud (optional)Directus Cloud (optional)
Update frequencyWeeklyMonthly
Contributors800+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.

Comments