Payload CMS emerges as the clear winner for building a website platform serving thousands of tenants. Its native multi-tenancy plugin enables a single deployment to serve unlimited tenants efficiently, while most competitors either lack multi-tenancy entirely or become prohibitively expensive at scale. For teams prioritizing full control and cost efficiency, self-hosted Directus ranks second; Firebase/Firestore offers a viable path for those willing to build custom CMS features on top of proven infrastructure.
The fundamental challenge is that most headless CMS solutions were designed for single-tenant use cases. Strapi, Ghost, and even enterprise platforms like Contentful hit architectural walls when scaled to thousands of separate tenant websites. The comparison below reveals which platforms can actually handle this demanding use case.
The website builder use case fundamentally requires true multi-tenancy—serving thousands of isolated tenant websites from shared infrastructure. This requirement immediately eliminates several popular options.
Payload CMS delivers native multi-tenancy through its official @payloadcms/plugin-multi-tenant plugin. A single codebase, single database, and single deployment can serve unlimited tenants with complete data isolation. The plugin automatically adds tenant fields to collections, enforces role-based access control (super-admins vs. tenant users), and supports custom domains per tenant. One agency reports successfully running 500+ tenants on this architecture. Three isolation strategies are available: user-based (shared login), path-based (URL routing), and domain-based (hostname detection).
Strapi has no native multi-tenancy support—a critical finding confirmed in official documentation. The recommended architecture is "one Strapi instance per tenant," meaning thousands of separate Node.js processes and databases. A community plugin (strapi-plugin-multi-tenant) provides workarounds, but Strapi explicitly states true multi-tenancy is not implemented as of v5. This effectively disqualifies Strapi for the website builder use case without massive custom infrastructure investment.
| CMS | Multi-tenancy approach | Tenant limit | Practical for 1000s? |
|---|---|---|---|
| Payload CMS | Native plugin, single deployment | Unlimited | ✅ Yes |
| Directus | RBAC + tenant_id filtering (self-hosted) | Unlimited | ✅ Yes (with effort) |
| Firebase/Firestore | Collection-based isolation + Security Rules | Unlimited | ✅ Yes (custom build) |
| Sanity | Datasets OR document filtering | 4 datasets (Growth), custom (Enterprise) | |
| Contentful | Spaces | 750 max per organization | ❌ Not viable |
| Hygraph | Enumeration + roles (Enterprise only) | Enterprise required | |
| Strapi | Separate instances required | N/A | ❌ Not viable |
| Ghost | Separate instances required | N/A | ❌ Not viable |
Sanity and Contentful have structural limits that prevent thousands-of-tenants scale. Sanity's Growth plan allows only 4 datasets maximum ($999/month per additional dataset), forcing either Enterprise pricing or a complex single-dataset approach with document-level filtering. Contentful caps organizations at 750 spaces, and space pricing ranges from $8,000 to $75,000+ annually per space—making multi-space architectures financially impossible at scale.
Self-hosted open-source solutions offer order-of-magnitude cost savings compared to managed platforms when serving thousands of tenants.
Payload CMS pricing is the most favorable for this use case:
- Self-hosted core is free forever (MIT license) with no seat limits, no entry limits
- Payload Cloud had tiers from $35-$199/month but new sign-ups are currently paused following Figma acquisition
- Estimated infrastructure cost for thousands of tenants: $500-2,000/month (single deployment scaling with database/storage, not per-tenant)
Strapi Cloud pricing demonstrates why multi-instance approaches fail at scale:
- Essential tier: $15-18/project/month (50,000 API requests)
- Pro tier: $99/project/month
- 1,000 tenants × $15-99 = $15,000-99,000/month just for CMS hosting
Firebase/Firestore offers predictable usage-based pricing:
- Free tier: 50,000 reads/day, 20,000 writes/day, 1GB storage
- Blaze plan: $0.06 per 100,000 reads, $0.18 per 100,000 writes
- Realistic estimate for 1,000 tenant sites with moderate traffic: $250-500/month
- Hidden costs: international egress ($0.12-0.23/GB), Cloud Functions compute, Security Rules evaluation counting as reads
Managed CMS enterprise pricing becomes prohibitive:
| Platform | Enterprise starting price | Notes |
|---|---|---|
| Sanity | $60,000-100,000+/year | Custom datasets, RBAC at scale |
| Contentful | $60,000+/year (list), ~$37,620 (negotiated median) | Per-space costs additional |
| Hygraph | $15,000-50,000+/year estimated | Multi-tenancy Enterprise-only |
Directus self-hosted offers a middle path:
- Free for organizations under $5M annual revenue
- Commercial license: ~$1,200-6,000/year (Vendr data average: $3,600/year)
- Directus Cloud: $15-99/month per project (not viable for thousands)
CDN caching strategy becomes critical for all platforms—both Sanity and Contentful offer unlimited cached requests from their CDNs, meaning proper cache configuration determines actual costs and performance.
Payload CMS performance benefits from its TypeScript-first architecture, claiming 40-60% faster response times than traditional CMS. Native Next.js integration enables ISR/SSG patterns. Horizontal scaling works naturally—one deployment, multiple serverless instances via Vercel or Cloudflare.
Directus performance requires careful optimization:
- Simple queries: 40-72ms with caching
- Complex queries (15 relations + permissions): ~1.5s for 10 req/sec without cache
- Permission evaluation adds ~30% overhead in benchmarks
- Node.js single-threaded architecture requires horizontal scaling via Redis for high concurrency
Firebase/Firestore latency varies considerably:
- Simple document read: 50-200ms
- Complex query: 200-500ms
- Real-time listener roundtrip: 600-1,500ms
- Cold Cloud Function + Firestore: 5-12 seconds (major gotcha)
- Mitigation: Keep 1-5 minimum instances warm, use 2nd-gen functions with concurrency up to 1,000
Rate limits comparison (uncached API requests):
| Platform | Rate limit | Notes |
|---|---|---|
| Sanity | 25 mutations/sec; CDN unlimited | API CDN requests unlimited for cached |
| Contentful | Free: 55/s, Paid: 78/s (per space) | CMA: 7-10/s |
| Hygraph | Hobby: 5/s, Growth: 25/s, Enterprise: 500/s | Cached unlimited |
| Firebase | ~1 write/sec per document sustained | 500/50/5 warmup rule for new collections |
Strapi's known performance issue (GitHub #13288): queries with populate=* on complex relations can spike to 9-20 seconds with 3,500+ entries—a significant concern for content-heavy tenant sites.
For multi-language website support, the platforms split between those with native i18n and those requiring custom implementation.
Native i18n leaders:
- Sanity: Unlimited locales included (all plans), but attribute limits constrain practical usage (10,000 attributes on Growth)
- Strapi v5: Built-in field-level localization, 500+ pre-created locales, AI translation on Growth plan
- Payload CMS: Field-level OR document-level localization, automatic fallback handling, 30+ admin UI languages, no locale limits
- Hygraph: Native per-field localization with independent publishing, but 2-3 locales on lower tiers; 8+ locales require Enterprise
Contentful's locale structure provides flexibility but tier-locks features:
- Free: 2 locales
- Lite: 3 locales
- Premium: Up to 500 per environment
- Fallback chains configurable (e.g., es-MX → es-ES → en-US)
Firebase requires manual implementation:
- No built-in i18n—must structure documents/collections manually
- Pattern options: locale-based collections or embedded translations within documents
- Firebase Hosting supports i18n rewrites based on Accept-Language header
- Translate Text Extension available (Cloud Translation API, ~$20 per 1M characters)
Ghost's i18n is notably weak:
- Single-language sites only
- No multi-language content from one installation
- Admin interface not internationalized
- Official workaround: separate Ghost instances per language
The website builder use case demands flexible APIs for menus, forms, and dynamic UI components.
Best API flexibility:
- Payload CMS: REST + GraphQL native, Local API (direct database access without HTTP overhead), official
@payloadcms/plugin-form-builderfor native form handling, 2-4 webhooks (more on Enterprise) - Sanity: GROQ query language enables powerful projections, joins across references in single queries, GraphQL supported, 2-4 webhooks by plan
- Directus: REST + GraphQL + Flows automation system, visual workflow builder for webhooks, 9 extension types for custom functionality
GraphQL-native options:
- Hygraph: GraphQL-only (no REST), real-time subscriptions, union types for flexible content modeling, content federation connecting external APIs
- Contentful: Full REST APIs (CDA, CMA, CPA) plus GraphQL, Sync API for delta updates, cross-space references on Premium
Firebase's webhook limitation: No native webhooks—must implement via Cloud Functions triggers, adding complexity and cold-start latency concerns.
Form handling comparison:
| Platform | Native forms | Approach |
|---|---|---|
| Payload CMS | ✅ Official plugin | Form builder with submissions collection |
| Directus | ❌ | Model as collection + M2A field components |
| Sanity | ❌ | Custom content types + external service |
| Contentful | ❌ | Custom content types + external service |
| Firebase | ❌ | Cloud Functions + custom collection |
For thousands of tenants, self-hosting becomes economically necessary.
Fully self-hostable (recommended for this use case):
| Platform | Requirements | Notes |
|---|---|---|
| Payload CMS | Node.js 20+, MongoDB/PostgreSQL/SQLite | 1-click deploy to Vercel/Cloudflare, serverless-friendly |
| Directus | Node.js 18+, PostgreSQL/MySQL/SQLite/etc | Docker recommended, Redis required for horizontal scaling |
| Strapi | Node.js 18+, PostgreSQL/MySQL | Per-tenant instances make this impractical |
| Ghost | Node.js 20, MySQL 8 (production) | Single-node only, multi-server clustering unsupported |
Managed-only platforms:
- Sanity: Studio can be self-hosted (React app), but Content Lake is managed—queries always go to Sanity's cloud
- Contentful: Fully managed, no self-hosting option
- Hygraph: Fully managed, no self-hosting option
- Builder.io: SaaS only, no self-hosting
Firebase positioning: Google-managed infrastructure with no self-hosting, but usage-based pricing makes it more predictable than per-seat/per-space models. Data portability concerns exist due to proprietary query syntax.
Directus self-hosting advantages include full database access (work with existing schemas), no artificial limits on users/entries/API calls, and database-agnostic support (PostgreSQL, MySQL, MariaDB, SQLite, MS-SQL, CockroachDB, OracleDB).
Setup complexity and community support significantly impact time-to-production.
Lowest development effort for multi-tenant setup:
| Platform | Setup time | Multi-tenant complexity | Documentation |
|---|---|---|---|
| Payload CMS | ~10-20 min | Low (native plugin) | Excellent |
| Firebase | ~30 min (basic) | Medium (custom rules/structure) | Excellent |
| Directus | ~15-30 min | Medium (RBAC setup) | Good |
| Sanity | ~15-30 min | High (Enterprise features) | Good |
| Strapi | ~15-30 min | Very High (no native support) | Comprehensive |
Community and ecosystem size:
| Platform | GitHub stars | Plugin ecosystem | Learning resources |
|---|---|---|---|
| Strapi | 70,800+ | 150+ marketplace plugins | Extensive |
| Directus | 33,000+ | Vue-based extensions | Growing |
| Payload CMS | 32,000+ | Smaller but high-quality official plugins | Excellent docs |
| Sanity | N/A | 500+ plugins/tools | Good |
| Contentful | N/A | ~100 marketplace apps | Comprehensive |
TypeScript support (critical for large codebases):
- Payload CMS: TypeScript-first with full type generation
- Strapi: Supported but not TypeScript-first
- Directus: Good TypeScript SDK, composable architecture
- Sanity: Excellent TypeScript support
Admin UI considerations:
- Firebase has no admin UI out of box—requires FireCMS, Rowy, or custom build (4-8 weeks for basic CMS features)
- Directus and Payload provide polished admin UIs
- Sanity Studio is highly customizable but code-based schema increases initial setup time
Website builders need flexible schemas for menus, page blocks, forms, and dynamic components.
Page builder patterns:
Payload CMS excels here with blocks that can nest within blocks (with maxDepth prevention for infinite recursion), @payloadcms/plugin-nested-docs for parent/child hierarchies, and full React component customization for admin UI.
Strapi's Dynamic Zones provide reusable components but have a critical limitation: Dynamic Zones cannot nest inside components (GitHub #5798, still unimplemented). This restricts complex page builder layouts.
Directus uses Many-to-Any (M2A) relationships for component-based pages—each component type is a separate collection with ordering preserved. This requires more manual setup but offers full flexibility.
Hygraph provides Union Types (GraphQL-native) perfect for varied block types, plus nestable Components—but model limits apply (40 models on Growth, 500 on Enterprise).
Content type limits comparison:
| Platform | Content types | Fields per type | Records |
|---|---|---|---|
| Payload CMS | Unlimited | Unlimited | Unlimited (self-hosted) |
| Directus | Unlimited | Unlimited | Unlimited (self-hosted) |
| Sanity | Unlimited | Attribute limits apply | 10M per project |
| Contentful | Free: 25, Premium: 1,000 | 50 per type | 5M per space |
| Hygraph | Hobby: 20, Growth: 40 | Varies | Growth: 10,000 entries |
| Strapi | Unlimited | Varies | Depends on infrastructure |
Rich text flexibility:
- Sanity's Portable Text: JSON-based, fully extensible, custom blocks allowed—can embed forms, videos, callouts directly in rich text
- Contentful Rich Text: Proprietary format, limited to linked entries (cannot add arbitrary custom blocks)
- Payload CMS: Lexical editor with custom block support
Payload CMS gotchas:
- Payload Cloud sign-ups currently paused (Figma acquisition)—self-hosting required
- MongoDB is the first-class database; PostgreSQL support via adapter is newer
- Smaller plugin ecosystem than Strapi
- Code-first approach less accessible for non-developers
Strapi gotchas:
- Multi-tenancy requires thousands of separate instances—operationally untenable
populate=*queries can take 9-20 seconds with complex relations- Dynamic Zones cannot nest inside components
- Linear cost scaling with tenant count
Firebase/Firestore gotchas:
- No admin UI—significant development investment required
- Cold start delays of 5-12 seconds for Cloud Functions
- Query limitations: only one inequality filter per query, no JOINs, no full-text search without Algolia/Elasticsearch
- Security Rules complexity scales with multi-tenant requirements
- 30+ minutes offline triggers full re-query charges on reconnect
Sanity gotchas:
- Only 4 datasets maximum on Growth plan ($999/month each additional)
- Attribute limits (10,000 on Growth) can be hit with many content types × locales
- Per-seat pricing escalates with many tenant admins
- Enterprise required for custom roles/RBAC at scale
Contentful gotchas:
- 750 spaces maximum per organization—mathematically insufficient for thousands of tenants
- Space costs are $8,000-75,000+ annually per space
- 25 content types limit on starter spaces
- Premium required for cross-space references
Directus gotchas:
- Permission evaluation adds ~30% latency overhead
- No automatic indexes on foreign keys (must create manually)
- $5M revenue threshold triggers commercial license requirement
- Single-threaded Node.js requires horizontal scaling for high concurrency
For a multi-tenant website builder serving thousands of tenants, the recommendation hierarchy is:
-
Payload CMS (self-hosted) — Native multi-tenancy plugin designed exactly for this architecture, single deployment efficiency, excellent TypeScript support, and nested blocks for flexible page builders. The paused Cloud service means self-hosting is required, but Vercel/Cloudflare 1-click deploys minimize operational burden.
-
Directus (self-hosted) — Best alternative if PostgreSQL preference or database-first approach is required. Full database control enables optimization at scale, but requires manual RBAC setup for tenant isolation and careful indexing strategy.
-
Firebase/Firestore — Viable for teams comfortable building custom CMS features. Usage-based pricing scales predictably, real-time capabilities are excellent, but requires FireCMS/Rowy or custom admin development. Best when paired with existing Firebase/GCP infrastructure.
-
Sanity (Enterprise) — Worth evaluating if managed infrastructure is non-negotiable and budget allows $60,000+/year. Single-project document filtering can work at scale with proper access control, but requires Enterprise for the necessary RBAC features.
Platforms to avoid for this use case:
- Strapi — No native multi-tenancy makes it fundamentally unsuited for thousands of tenants
- Ghost — Blog-focused architecture with no custom content types or multi-tenancy
- Contentful — Space limits (750 max) and per-space pricing make it economically impossible
- Hygraph — Enterprise-only multi-tenancy with managed-only deployment; entry limits constrain scale