Directus: A Database-First CMS Guide
Understand Directus database-first CMS architecture, setup steps, and the true cost of self-hosting vs managed platforms. Own your data without vendor lock-in.
- Directus wraps any SQL database to auto-generate REST APIs, GraphQL, and an admin UI: database-first, not code-first like Strapi or Contentful.
- You keep data ownership and avoid vendor lock-in because the database is yours; switching platforms doesn't require expensive exports or migrations through a proprietary API.
- Self-hosting Directus costs $60-180/month in infrastructure plus $2,000-4,000/month in ops labor; managed hosting through providers like Opsily costs $150-400/month and eliminates the DevOps tax.
- Best for legacy system modernization, multi-database architectures, and teams that prioritize data control over ease-of-use; avoid database-first if your team needs simple workflows or non-technical content management.
Directus wraps any SQL database to automatically generate REST and GraphQL APIs alongside a visual admin interface: no code-first framework, no proprietary data store, just your database elevated to a CMS. If you manage data with relational databases, Directus is worth understanding because it shifts control back to you.
Most headless CMS platforms (Sanity, Contentful, Strapi) are code-first: you build a schema in code or their UI, and they manage the data store. Directus flips this: you point it at an existing PostgreSQL, MySQL, MariaDB, or SQLite database, Directus introspects the schema, and instantly exposes permissions-driven APIs. That distinction matters for business continuity, vendor independence, and cost.
What Does "Database-First" Actually Mean?
Database-first architecture means the database schema is your single source of truth, and the CMS adapts to it, not the other way around. Directus uses schema introspection: it reads your database structure and auto-generates REST endpoints, GraphQL types, and an admin UI to match. No intermediate schema definition layer, no duplication.
In a traditional code-first CMS like Strapi, you define content models in JavaScript or YAML, the framework generates a database, and you're locked into that vendor's data model and export formats. With Directus, you start with a database schema (your own schema, or a legacy one from an existing system), and Directus becomes the UI and API wrapper around it.
This distinction is architectural, not cosmetic. When you own the database, you own the data. You can query it directly with SQL if needed. You can export it, migrate it, or run it on your own servers. A code-first platform forces you through their export APIs and formats, usually at a cost, and data lives in their proprietary store unless you migrate out (which is expensive and risky).
How Directus's Database-First Architecture Works
The setup is straightforward: connect Directus to your database, and it reads the schema. Directus then generates REST endpoints and GraphQL queries for every table, with permissions enforced per user and role. The admin interface is built dynamically from the schema.
Let's say you have a PostgreSQL database with a posts table (id, title, content, created_at, author_id) and an authors table (id, name, email). Directus immediately exposes:
- GET /items/posts (list all posts with filtering, sorting, pagination)
- POST /items/posts (create a post, respecting role permissions)
- GET /items/posts/:id (fetch one post)
- PATCH /items/posts/:id (update)
- DELETE /items/posts/:id (delete)
The same endpoints exist in GraphQL. Every query respects field-level and row-level permissions you define in Directus's admin panel. Non-technical team members get a database UI that doesn't look like raw SQL.
For legacy systems, this is powerful: you have a 10-year-old customer database running on MySQL. Instead of rewriting it into a SaaS schema, you run Directus against it and instantly have an API and dashboard for internal teams or partners without touching the original code.
The architecture also handles relationships. If your schema has a foreign key (author_id in posts), Directus automatically traverses it in queries, so clients can fetch a post with its author details in a single request: GET /items/posts?fields=,author.
The Core Appeal: Data Ownership Without Vendor Lock-In
This is why database-first matters for business decision-makers. You own your data, your schema, and your infrastructure decisions. There's no proprietary export process or API blackmail to switch platforms.
Compare two scenarios:
Scenario 1: Contentful or Sanity (code-first, proprietary store). You build a content model in their CMS, publish 50,000 articles, and in three years decide you want to leave. You have to use their export API (which costs), write a migration script to map their schema to a new platform, and hope for no data loss. Switching platforms takes months and risk.
Scenario 2: Directus (database-first). Your data lives in PostgreSQL. You define permissions in Directus, but the data itself is standard SQL. If you decide to switch to another tool (or no CMS at all), you have the raw database. Export it, point a different API layer at it, or query it directly. No vendor lock-in.
This advantage compounds over time. As your company grows, data ownership becomes a competitive asset. You're not paying Contentful's price premium or Sanity's per-user fees; you're paying infrastructure and your own ops overhead.
For multi-database architectures, database-first is essential. If you manage a data warehouse, a customer database, and a content database across different vendors and geographies, Directus can wrap multiple databases with a unified permissions and API layer, letting you stay database-agnostic.
Setting Up Directus: What You Actually Need to Know
Directus runs on Node.js. Self-hosting requires Docker, a database, and a server (your own VM, a VPS, or a Kubernetes cluster). The official quickstart uses Docker Compose:
Version 3
Services:
postgres:
image: postgres:15
environment:
POSTGRES_DB: directus
POSTGRES_USER: postgres
POSTGRES_PASSWORD: mysecurepassword
volumes:
- postgres-data:/var/lib/postgresql/data
directus:
image: directus/directus:latest
ports:
- "8055:8055"
environment:
DB_CLIENT: postgres
DB_HOST: postgres
DB_PORT: 5432
DB_DATABASE: directus
DB_USER: postgres
DB_PASSWORD: mysecurepassword
ADMIN_EMAIL: admin@example.com
ADMIN_PASSWORD: adminpassword
SECRET: your-secret-key-here
depends_on:
- postgres
Volumes:
postgres-data:
Run docker-compose up, wait for services to start, and access the admin panel (default: localhost:8055). Log in, create collections (tables), set permissions, and start adding data through the UI or API.
Common gotchas:
Database setup: Directus prefers PostgreSQL for reliability at scale, but MySQL and MariaDB work. SQLite is useful for development but not production (no concurrent writes, limited scaling).
Permissions complexity: Directus has granular role-based access control (RBAC), but configuring it correctly takes time. If you have 10 content roles and custom workflows, plan a week to model permissions correctly.
Migrations and versioning: Schema changes in a live database are risky. Directus tracks migrations, but rolling back a bad change isn't one command; it requires database-level reversions or manual SQL fixes.
Time to production: For a small team (1-3 people), Docker Compose to working CMS is 2-4 hours. For a team integrating Directus into an existing multi-database architecture with strict RBAC, expect 2-4 weeks.
The Hidden Costs of Self-Hosting Directus
Directus software is free (BSL 1.1 license, free for use under $5M revenue). The cost of self-hosting is infrastructure, not software.
Breakdown of typical self-hosted costs:
Infrastructure: A managed PostgreSQL database (AWS RDS, DigitalOcean, Hetzner) is $30-100/month depending on size. A single VM for Directus (2 CPU, 4GB RAM) is $20-50/month. Storage, backups, and bandwidth add $10-30. Total: $60-180/month in cloud infrastructure.
Maintenance and operations: Database backups, monitoring, patching, and incident response are your responsibility. If Directus crashes or your database runs out of disk, it's your team's problem, not a vendor's SLA. A junior DevOps engineer costs $40-80k annually (or $2,000-4,000/month for fractional ops).
Labor for migrations and schema changes: If you need to restructure your content model or migrate data, you write SQL. If you're not comfortable with database migrations, you're outsourcing to a consultant ($150-300/hour, weeks of work for major migrations).
Monitoring and alerting: You need tools to watch database performance, API latency, and error rates. DataDog, New Relic, or Grafana add $100-500/month depending on scale.
Total annual cost of self-hosting: $1,000-2,500/month ($12k-30k/year) for a small-to-medium team running a moderately complex Directus instance. That's infrastructure ($700-2,000/month) plus fractional ops labor (either internal time or external consulting).
For comparison: Directus's Professional Cloud plan is $99/month (5 studio users, 75K entries, 250K API requests/month). Managed Directus hosting through providers like Opsily starts around $150-300/month depending on your database size and API volume.
When Database-First CMS Is the Right Choice
Database-first is not universally better. It's a different trade-off, right for specific scenarios:
Good fit for database-first CMS:
-
Legacy system modernization. You have a 15-year-old MySQL database running your business. Rewriting it into a SaaS CMS is impossible. Directus wraps it without migration.
-
Multi-database architectures. You manage customer data, transactional data, and content across different databases and vendors. A unified CMS wrapper (Directus) gives you a single permissions and API layer without forcing convergence.
-
High-volume data or strict data governance. You're moving 100M+ records or have GDPR/HIPAA requirements. You want your data in a database you control, auditable and portable.
-
Technical teams, not content teams. Your users are engineers or data analysts, not marketers. They're comfortable with schema concepts and prefer raw API access to UI wizardry.
-
Custom workflows or business logic. Your content has complex rules (conditional publishing, approval chains, multi-step versioning). Database-first lets you bake these into SQL constraints and triggers.
Poor fit for database-first CMS:
-
Non-technical content creators. Directus admin UI is good but assumes database literacy. If your team is comfortable with WordPress or Notion, Directus may feel foreign.
-
Simple publishing workflows. If you're just blogging, a traditional headless CMS (Contentful, Sanity, Payload) is simpler and faster to set up.
-
Heavy reliance on managed services. If you want to avoid DevOps entirely, don't self-host Directus. Use managed hosting or a SaaS CMS.
-
Rapid iteration on content model. If your schema changes monthly, database-first rigidity (migrations take time) might slow you down more than code-first flexibility.
Directus Cloud vs Self-Hosted vs Managed Hosting
You have three options:
Directus Cloud (Official SaaS): Starting at $99/month (Professional plan: 5 studio users, 75K entries, 250K API requests/month). Directus maintains infrastructure, backups, and uptime. No DevOps overhead. Downside: you're on their terms, price locks you into their service, data lives in their datacenters.
Self-Hosted (Your Infrastructure): Free software, but $1,000-2,500/month in infrastructure and ops labor. Full control, but you own all operational responsibility. Right for teams comfortable with DevOps and willing to spend time on infrastructure.
Managed Hosting (Third-Party Provider like Opsily): Typically $150-400/month depending on database size and API volume. Opsily (or similar providers) handles infrastructure, backups, scaling, and updates, while you keep data ownership. No vendor lock-in to Directus itself (you own the database), but locked into the hosting provider for ops.
Cost comparison table:
| Option | Monthly Cost | Infrastructure | Ops Overhead | Data Ownership | Switching Cost |
|---|---|---|---|---|---|
| Directus Cloud | $99-500+ | Directus-managed | Zero | Low (SaaS) | High (data export, API-dependent) |
| Self-Hosted | $60-180 infrastructure + $2k-4k ops labor | Your servers | High | High (your database) | Low (migrate database anywhere) |
| Managed Hosting | $150-400 | Provider-managed | Low | High (your database) | Low (migrate to another provider) |
For most growing teams, managed hosting (Opsily) hits the sweet spot: you keep data ownership and database portability, skip the DevOps tax, and pay a predictable monthly fee.
Frequently Asked Questions
What databases does Directus support?
PostgreSQL (recommended), MySQL 8.0+, MariaDB 10.2+, SQLite, and experimental support for Oracle and MS SQL Server. PostgreSQL is most mature and recommended for production.
Is Directus truly open-source?
Partially. Directus uses BSL 1.0 (Business Source License), which allows free use for entities under $5M revenue and less than 50 employees. It converts to GPLv2 after a deferral period. Not OSI-approved open source, but free for small teams and non-commercial use.
Can Directus work with my existing database?
Yes, that's its core strength. Directus introspects any SQL database and generates APIs and admin UI from the existing schema. You don't need to migrate data or rewrite your structure.
How is Directus different from Strapi?
Strapi is code-first (you define schema in code, Strapi creates the database). Directus is database-first (you have a database, Directus wraps it). Strapi locks you into their data model; Directus adapts to your existing schema. For legacy systems, Directus wins. For greenfield projects, Strapi might be simpler.
Does Directus include user authentication and roles?
Yes. Directus has built-in role-based access control (RBAC) with field-level and row-level permissions. You define roles, assign permissions, and non-technical users can log into the admin UI with limited access.
How do I migrate to Directus from another CMS?
You need to export data from your old CMS (usually as JSON or CSV), transform it to match your Directus schema, and load it into your database. For large migrations, script it with Python or Node.js. Directus itself doesn't include a built-in migration tool, so the effort depends on schema mismatch and data volume.
What's the learning curve for a non-technical team?
Directus admin UI is intuitive if you understand databases and tables. For teams used to WordPress or Notion, it may feel unfamiliar. Expect 1-2 weeks for non-technical users to be comfortable creating and editing content, especially if permissions are complex.
The Bottom Line
Directus is a smart choice if you own a database and want an API and admin interface without rewriting your data layer. It trades managed simplicity for control and portability: you're responsible for infrastructure and schema decisions, but you keep your data and avoid vendor lock-in.
For small teams or greenfield projects, a traditional headless CMS (Contentful, Sanity) might be faster. For teams with existing databases, legacy systems, or strict data governance requirements, database-first is the only sensible path.
If self-hosting feels like too much ops burden, managed Directus hosting eliminates the DevOps overhead while keeping you in control of your data.