Most white-label SaaS teams evaluating a CMS compare the wrong things. Rich-text editors, localization support, GraphQL versus REST - these matter, but they don't decide whether the platform survives at scale. The decisive questions are architectural: how is tenancy modelled, where does tenant data actually live, and what happens to your provisioning pipeline and your AWS bill when you go from 5 customers to 500.
Strapi's own multi-tenancy guide recommends you run one Strapi project per client. If you're building a white-label SaaS and planning to use Strapi for 500 tenants, that's 500 deployments to monitor, upgrade, and bill against. This is the kind of detail that falls out of a feature-comparison spreadsheet and into your on-call rotation eighteen months later.
This post walks through five architecture questions you should be asking on your vendor calls, then ranks four self-hostable CMS platforms against them: Webiny, Payload, Strapi, and Directus.
Question 1: Is multi-tenancy native, or bolted on via plugin?
"Native" means the platform was designed around the concept of a tenant. Tenants appear in the data model, the API, the permissions system, and the admin UI without additional packages. "Bolted on" means multi-tenancy is a layer added over a single-tenant core, usually workable, sometimes well-maintained, but carrying the structural debt of a system that didn't originally think in those terms.
- Webiny: native. Tenants are a first-class concept in Webiny's core. Every content model, user, role, and workflow belongs to a tenant. Tenant Manager is a built-in product, not an add-on.
- Payload: official plugin. Payload CMS provides an official
@payloadcms/plugin-multi-tenantpackage that lets multiple tenants be managed from a single admin panel. It's free, maintained by Payload itself, and production-proven. - Strapi: not supported in a single instance. Strapi's own documentation states it intentionally does not support true multi-tenancy in one instance and recommends one deployment per client.
- Directus: build-it-yourself with roles. Tenancy in Directus is implemented by adding a
tenant_idfield to every collection and writing role-based rules that filter reads and writes. There is no tenancy abstraction above that.
Conclusion: For a white-label SaaS, native tenancy and an official plugin are both defensible starting points. Strapi's recommended pattern, one project per tenant, is a different architecture entirely and should be evaluated as such. Directus works, but the tenancy model is something you own and maintain.
Question 2: Where does tenant data actually live?
There are three common answers: one shared database with a tenant_id column on every row; one database per tenant; or a hybrid, where some tenants share and others get their own.
Shared databases are cheap and operationally simple. The failure mode is specific and well-documented: when tenant isolation depends entirely on a tenant_id column and application-level filtering, a single missing WHERE clause - introduced by a developer, a third-party plugin, or a CMS upgrade - can return records across tenant boundaries. Database-per-tenant provides hard isolation where the database itself is the security boundary, at the cost of operational complexity around migrations and backups.
- Webiny: shared backend, logical isolation enforced in core. Tenants share the underlying DynamoDB and S3 infrastructure on AWS, with tenancy enforced at the framework level, not left to each developer's queries.
- Payload: shared database, isolation via the plugin's access control. The multi-tenant plugin adds a tenant field and enforces filtering through Payload's access-control functions. Isolation is correct as long as the access-control layer is correct.
- Strapi: typically database-per-project, because the recommendation is one project per tenant. This gives you hard isolation by default, and the operational cost that comes with it.
- Directus: shared database, isolation via roles and filters. You write the filter rules yourself for every collection.
Conclusion: If you need to demonstrate tenant isolation to an auditor, common in healthcare, financial services, and regulated SaaS, a shared-database model requires you to prove the application layer is correct everywhere. Database-per-tenant moves that proof to the infrastructure layer, where it's easier to demonstrate but more expensive to run.
Question 3: How do you provision a new tenant, and how long does it take?
For a white-label SaaS, tenant provisioning is a product feature. When a customer signs up on your pricing page, a new tenant needs to exist within seconds, pre-configured with their branding, default content, and user accounts. Manual provisioning doesn't scale past the first dozen customers.
- Webiny: programmatic via a GraphQL API. Tenant Manager exposes a programmatic API for creating, configuring, and tearing down tenants, with lifecycle events you can hook into for provisioning side effects. See the Tenant Manager docs.
- Payload: programmatic via Payload's Local API. The multi-tenant plugin treats tenants as a regular collection, so you create them with
payload.create()calls, including from webhooks triggered by your billing system. - Strapi: a new deployment. Provisioning a Strapi tenant means standing up a new instance - a container, a database, and a pipeline. This is automatable with Terraform or similar, but the unit of provisioning is infrastructure, not a database row.
- Directus: write it yourself. You insert a tenant row, configure roles and permissions, and set up any default content in code you maintain.
Conclusion: Platforms that treat tenants as data provision in milliseconds. Platforms that treat tenants as infrastructure provision in minutes. The difference compounds: at 500 customers, a two-minute provisioning step blocks sign-up flows and complicates recovery drills.
Question 4: Can content inherit from a root tenant to all child tenants?
In a white-label SaaS, you almost always want a mechanism for pushing shared content - default page templates, a base component library, standard legal copy - from a central root to every tenant. Without it, each new tenant starts empty and your onboarding team becomes a copy-paste operation.
- Webiny: built-in. Content inheritance from a root tenant is a documented feature, with the ability to propagate updates selectively. See content inheritance.
- Payload: not out of the box; build it with hooks. Payload's hook system lets you implement inheritance, but there is no shipped abstraction for "root tenant" or "propagate this update to all child tenants."
- Strapi: not applicable at the single-instance level, because tenants are separate projects. Shared content between projects is a sync problem solved at the deployment layer.
- Directus: build it yourself with flows or custom logic. There is no root-tenant concept.
Conclusion: If your product model includes a shared base of content that every customer starts with, and most white-label SaaS products do, inheritance is either a core feature or a six-week engineering project. Price it accordingly.
Question 5: What happens to your infrastructure cost at tenant #500?
Infrastructure cost scales differently depending on the model. Shared infrastructure scales roughly with aggregate usage. Dedicated-infrastructure-per-tenant scales linearly with tenant count, regardless of whether those tenants are active. SaaS CMS pricing scales with tenants, seats, API calls, or all three.
- Webiny: serverless on AWS in your own account, so costs scale with actual traffic and storage, not with tenant count. Webiny claims infrastructure costs up to 80% lower than comparable alternatives, that's Webiny's own figure, so treat it as a vendor claim, and use the hosting calculator to model your specific case. On AWS it's serverless (Lambda, DynamoDB, S3, CloudFront), so there are no servers to patch and it scales with traffic. Webiny can now also be deployed in containerized environments such as Docker and Kubernetes, giving teams greater flexibility in how they run and manage their Webiny deployments.
- Payload: depends on your host. Shared database means shared infrastructure, so cost scales with usage. You pay no per-tenant licensing to Payload.
- Strapi: linear with tenant count. One project per tenant means one database, one Node process, and one deployment per tenant. At 500 tenants, that's 500 of each.
- Directus: depends on your isolation model. With shared infrastructure, costs scale with usage; the licence changed in v12 to a source-available model with key enforcement, so verify the current terms against your business model.
Conclusion: For a white-label SaaS planning to reach hundreds of tenants, a shared-infrastructure model with per-tenant isolation at the framework level is almost always the cheaper operating model. Dedicated-infrastructure-per-tenant is defensible for high-value, low-volume tenants with strict isolation requirements, and painful otherwise.
Scorecard
| Webiny | Payload | Strapi | Directus | |
|---|---|---|---|---|
| Native tenancy | Yes | Official plugin | No | DIY with roles |
| Isolation model | Shared backend, framework-enforced | Shared DB, plugin-enforced | DB-per-project | Shared DB, role-enforced |
| Provisioning | Programmatic API | Local API | New deployment | DIY |
| Root-tenant inheritance | Built-in | DIY with hooks | N/A | DIY |
| Cost scaling | With usage | With usage | With tenant count | With usage |
What to ask on your next vendor call
Three questions will surface most of what matters:
- Show me the API call that creates a new tenant and the one that deletes one. If the answer involves spinning up infrastructure, you're looking at a one-project-per-tenant architecture.
- How does tenant isolation get enforced, and where in the stack? Framework-level enforcement is harder to break by accident than application-level filtering.
- What's the shipped mechanism for pushing shared content from a central source to every tenant? If the answer is "you can build that with hooks," price in the build.
A CMS that answers all three cleanly was designed for your use case. Everything else is a CMS you'll be adapting.
If white-label is specifically where you're heading, Webiny's embedded CMS use case and Tenant Manager pages cover the architecture in more detail.
Frequently Asked Questions
Is one-project-per-tenant ever the right architecture?
Yes, for a narrow set of cases. If you have a small number of high-value customers with strict data-isolation or data-residency requirements, think healthcare systems or regulated financial platforms, the operational cost of running separate deployments is defensible, because the per-tenant revenue supports it. For a white-label SaaS targeting hundreds or thousands of tenants at lower price points, the economics break down.
Can you add multi-tenancy to a single-tenant CMS later?
Technically yes, practically rarely well. The patterns needed for tenant isolation - a tenant discriminator on every query, tenant-aware caching, tenant-scoped webhooks and events - touch almost every layer of the system. Retrofitting them to a codebase that didn't originally think in tenants is a rewrite wearing a refactor's clothes. If multi-tenancy is in your product plan, choose for it on day one.
How does multi-tenancy affect upgrade risk?
In a shared-instance model, one upgrade touches every tenant at once. That's efficient, but it also means a bad migration or a breaking schema change is a bad day for all 500 customers simultaneously, not one. In a one-project-per-tenant model, you can roll upgrades out gradually and catch problems on a handful of tenants before they hit the rest, at the cost of running multiple versions of your CMS in production at any given time. Neither model removes the risk. They just decide whether it's concentrated or distributed.

