Comparisons9 min read

Directus vs Payload vs SonicJS: Open Source CMS Battle

Compare Directus, Payload, and SonicJS open source headless CMS platforms. Performance benchmarks, database flexibility, and developer experience analysis.

SonicJS Team

Visual comparison of three open source headless CMS architectures

Directus vs Payload vs SonicJS: Open Source CMS Battle

TL;DR — Directus wraps existing databases but struggles with performance at scale (1.5s+ response times with relations). Payload offers excellent TypeScript DX but requires 13GB RAM for dev servers. SonicJS is edge-first with zero cold starts and sub-50ms global latency.

Key Stats:

  • Directus: 45,000ms+ load times with 400k files (GitHub Issue #7783)
  • Payload: 15x slower than Mongoose for populated queries
  • SonicJS: Under 50ms globally, zero cold starts
  • All three: MIT/GPL licensed, truly open source

Looking for an open source headless CMS? Directus, Payload, and SonicJS represent three different philosophies. This comparison covers the real-world trade-offs based on developer feedback and production experiences.

Quick Comparison

FeatureDirectusPayload CMSSonicJS
ArchitectureNode.js (Express)Next.js-nativeEdge-first (Cloudflare Workers)
DatabasePostgreSQL, MySQL, SQLite, MSSQL, OracleMongoDB, PostgreSQLD1 (SQLite at edge)
Existing DB SupportYes (wraps existing tables)NoNo
TypeScriptPartialNative, excellentNative, full type safety
Cold starts300-1000ms100-300ms0-5ms
Global latency200-500ms150-400msUnder 50ms
Admin UIVue.jsReactHTMX
LicenseGPL v3 / BSLMITMIT
GraphQLBuilt-inYesRoadmap

The Real Problems

Directus: Performance at Scale

Directus's strength—wrapping existing databases—becomes its weakness with complex queries.

Documented Performance Issues from GitHub:

IssueScenarioReported TimeNotes
#11766500 items with relations1,500msrunAST bottleneck
#7783400k files45,000ms+Heap out of memory
#1575Simple queries4,000msCold query performance
#20201,000 items5,500msCollection listing
#10034200 row insertsConnection crashesPool exhaustion

"With a lot of items linked to other items, Directus becomes slow. For only 500 items, Directus took 1.5 seconds to load all of them." — GitHub Issue #11766

The file system performance is particularly concerning:

"Loading with 400k files takes around 45 seconds. My latest test was now at 500 seconds." — GitHub Issue #7783

Common Directus pain points:

  • Connection pool crashes under load (Issue #10034)
  • Missing database indexes cause slowdowns
  • Memory consumption with large datasets
  • Complex relations degrade performance significantly

Payload: Resource Hunger

Payload's TypeScript-first approach is excellent, but the development experience has issues.

Documented Performance Issues from GitHub:

IssueScenarioReported TimeNotes
#113251,000 docs with populate4,000ms15x slower than Mongoose
#7505Query with joins5,734msvs 23ms raw Mongoose (249x slower)
Discussion #14230Dev server10-60s per call13GB RAM consumption
Discussion #2413Production page loads20,000msWith ~10 concurrent users

"Dev server needs 13GB of RAM just to start." — GitHub Discussion #14230

"find() returning populated documents is 15x slower than the same query in Mongoose." — GitHub Issue #11325

Common Payload pain points:

  • Heavy memory usage during development
  • Performance degrades with population/relations
  • S3 adapter memory leaks reported
  • Build times can be excessive

SonicJS: Honest Limitations

SonicJS is newer and building rapidly:

  • Smaller plugin ecosystem (growing with community)
  • D1 database only (edge-native by design)
  • Learning curve for edge concepts
  • GraphQL on roadmap, not shipped yet

The difference? Edge-first architecture means you're not fighting fundamental design decisions.

Architecture Deep Dive

Directus: Database-First

Directus can wrap any existing SQL database, making it unique for brownfield projects:

// Directus wraps your existing database
{
  "database": {
    "client": "pg",
    "connection": {
      "host": "localhost",
      "database": "existing_db"
    }
  }
}

When this works well:

  • Legacy database integration
  • Multiple applications sharing data
  • Gradual CMS adoption

When this fails:

  • Complex relations at scale
  • High-traffic applications
  • Global performance requirements

Payload: Next.js Native

Payload integrates directly into Next.js applications:

// payload.config.ts
import { buildConfig } from 'payload/config'

export default buildConfig({
  collections: [Posts, Users, Media],
  db: mongooseAdapter({ url: process.env.DATABASE_URI }),
})

Strengths:

  • Same deployment as your frontend
  • Excellent TypeScript integration
  • Code-first content modeling

Weaknesses:

  • Inherits Next.js cold start times
  • Memory-intensive development
  • Performance with populated queries

SonicJS: Edge-First

SonicJS runs on Cloudflare Workers globally:

// sonic.config.ts
import { createSonicJS } from '@sonicjs-cms/core'

const cms = createSonicJS({
  database: env.DB,     // D1 at the edge
  cache: env.CACHE,     // KV for instant reads
  storage: env.STORAGE, // R2 for files
})

export default cms.app

Implications:

  • Zero cold starts (V8 isolates)
  • Under 50ms response globally
  • Automatic scaling
  • Predictable Cloudflare pricing

Performance Comparison

ScenarioDirectusPayloadSonicJS
Simple GET (same region)50-200ms50-150ms15-30ms
Simple GET (cross-region)200-500ms150-400ms30-60ms
Complex query (relations)500-1500ms+200-500ms*40-80ms
Cold start300-1000ms100-300ms0-5ms
With 400k files45,000ms+UnknownUnder 100ms

*Payload populated queries can be 15x slower than raw queries

Why Edge Wins

When your CMS runs in 300+ locations worldwide:

User in Sydney → Sydney Edge (15ms)
User in Tokyo → Tokyo Edge (15ms)
User in London → London Edge (15ms)

vs Traditional (server in Virginia):
User in Sydney → Virginia Server (250ms+)

Database Flexibility

Directus: Maximum Flexibility

Supports PostgreSQL, MySQL, MariaDB, SQLite, MS SQL Server, Oracle, and CockroachDB. Can introspect existing schemas.

Payload: MongoDB or PostgreSQL

Excellent with MongoDB, PostgreSQL adapter available but newer. No existing database wrapping.

SonicJS: D1 Only (By Design)

D1 (SQLite at the edge) provides:

  • Global replication
  • Zero configuration
  • Edge-native performance
  • Standard SQL queries

Trade-off: No PostgreSQL/MongoDB. Benefit: Consistent global performance.

Developer Experience

TypeScript Support

Directus: SDK is TypeScript, but content types require generation:

// Types must be generated from schema
import type { Collections } from './directus-types'

Payload: Native TypeScript with excellent inference:

import { CollectionConfig } from 'payload/types'

const Posts: CollectionConfig = {
  slug: 'posts',
  fields: [
    { name: 'title', type: 'text', required: true },
  ],
}

SonicJS: Full type safety from schema to API:

const posts = defineCollection({
  name: 'posts',
  fields: {
    title: { type: 'string', required: true },
    content: { type: 'richtext' },
  },
})
// Types automatically inferred

Content Modeling

All three support code-first content modeling. Key differences:

  • Directus: Can also use visual schema builder
  • Payload: Richest field types and hooks
  • SonicJS: Simplest API, edge-optimized

Pricing Comparison

Directus

  • Self-hosted: Free (GPL v3)
  • Cloud: Starting at $99/month
  • Hidden costs: Database hosting, server management

Payload

  • Self-hosted: Free (MIT)
  • Cloud: Starting at $35/month
  • Hidden costs: High memory requirements increase hosting costs

SonicJS (Cloudflare)

  • Free tier: 100,000 requests/day, 10GB D1
  • Paid: $5/month flat + minimal usage
  • Typical site: $5-20/month total

When to Choose Each

Choose Directus If:

  • You have an existing database to wrap
  • Multiple applications share the same data
  • You need maximum database flexibility
  • Performance at scale isn't critical

Choose Payload If:

  • You're building with Next.js
  • TypeScript DX is paramount
  • You have resources for higher memory usage
  • MongoDB is your preferred database

Choose SonicJS If:

  • Global performance is critical
  • You want predictable, low costs
  • Zero cold starts matter
  • Edge-first architecture appeals to you

Migration Considerations

Migrating to SonicJS

From Directus:

  1. Export data via Directus API
  2. Map collections to SonicJS schemas
  3. Import via SonicJS API
  4. Main challenge: SQL dialect differences

From Payload:

  1. Export collections and content
  2. Convert Payload config to SonicJS
  3. Migrate MongoDB documents to D1
  4. Main challenge: MongoDB → SQLite data transformation

FAQ

Can SonicJS wrap my existing database like Directus?

No. SonicJS is designed for D1 (edge SQLite) to provide consistent global performance. If you need to wrap an existing database, Directus is the right choice.

Is Payload's memory usage really that bad?

During development, yes. Production deployments are more reasonable, but you'll need adequate RAM for the dev server. This is documented in community discussions.

How does Directus handle high traffic?

It requires careful configuration—connection pooling, caching layers, and potentially read replicas. Out of the box, it can struggle under load per community reports.

What about GraphQL support?

Directus and Payload both support GraphQL. SonicJS focuses on REST for edge performance, with GraphQL on the roadmap.

Conclusion

Three different philosophies:

  • Directus excels at database flexibility but struggles with performance at scale
  • Payload offers best-in-class TypeScript DX but requires significant resources
  • SonicJS delivers edge-first performance with architectural simplicity

For new projects prioritizing global performance and cost efficiency, SonicJS provides a compelling modern alternative.

Key Takeaways

  • Directus can wrap existing databases but performance degrades with scale
  • Payload offers excellent TypeScript but needs 13GB+ RAM for development
  • SonicJS delivers under 50ms global latency with zero cold starts
  • All three are genuinely open source
  • Edge-first architecture eliminates geographic latency

Ready to try edge-first CMS? Get started with SonicJS in under 5 minutes.


Sources & References

Directus Issues

Payload Issues

#directus#payload#comparison#headless-cms#open-source#typescript

Share this article

Related Articles