← All posts

Multi-tenant or one deployment per client? Choosing a SaaS architecture

When you sell software to several companies, you can serve them all from one shared system or give each its own deployment. The trade-offs in isolation, cost, updates, customization and operations.

Author
Elie Chaaban
Published
Reading time
5 min
Topics
Architecture, SaaS, DevOps, Consulting

When a product serves several business customers, one of the first architecture decisions is how to separate them. Should every client company share one application and database, with their data separated by a tenant identifier? Or should each client get its own deployment: its own app instance, its own database, sometimes its own server?

Both approaches run successful products. The right choice depends on your clients, your team and how you expect the product to grow. For NeonTask, the field-service platform I designed, built and run, each client company runs on its own deployment. This post explains the trade-offs and why that choice fit.

The two models

Multi-tenant (shared). One application and usually one database serve every client. Each row of data carries a tenant identifier, and every query filters by it. A new client is a new record, created in seconds.

Single-tenant (per-client deployment). Each client gets its own instance of the application and its own database. The code is the same for everyone; the data and runtime are separated. A new client means provisioning a new deployment, ideally automatically.

There are hybrids too, such as one application with a separate database per client, or a separate schema per client in a shared database.

Data isolation

This is often the deciding factor.

In a shared system, isolation depends on every query in the code filtering by tenant correctly. One missed filter, in one endpoint or one report, can expose one client's data to another. Good frameworks and patterns reduce the risk, such as row-level security in the database or a global filter applied automatically, but it never disappears completely.

With per-client deployments, a bug in a query can only expose data within the same client. Isolation is structural, not a matter of discipline. For clients who are sensitive about their data, who compete with each other, or whose contracts require separation, this is a strong argument.

Cost

Shared systems are cheaper per client at scale. Resources are pooled, and a client with little activity costs almost nothing.

Per-client deployments carry a base cost for each client: memory, a database, backups, monitoring. Containers make this much lighter than it used to be, because many small deployments can run on the same server, but the overhead is real. The model fits best when you have a moderate number of clients, each paying enough to justify it, rather than thousands of small accounts.

Updates and versions

In a shared system, everyone is on the same version. You deploy once, and every client gets the change. Simple, but also risky: a bad release affects everyone at once.

With per-client deployments, you can:

The cost is discipline. Without automation, deployments drift apart and you end up maintaining several versions. The answer is a CI/CD pipeline that builds once and deploys the same image to every client, with the version tracked per deployment. NeonTask uses Dockerized services with a CI/CD pipeline that builds and ships every change, which is what keeps per-client deployments manageable. See a CI/CD pipeline for a small team.

Customization

Clients ask for different things: their own branding, extra fields, different workflows, specific reports.

In a shared system, every customization must be built as configuration, because all clients run the same code. That is healthy discipline, but some requests become awkward.

Per-client deployments make configuration per client natural, since each has its own settings and database. The danger is the opposite: it becomes tempting to fork the code for one client. Avoid that. Keep one codebase, and express differences through configuration and feature flags.

Performance and noisy neighbours

In a shared system, one client running a heavy report or importing a large dataset can slow down everyone else. You mitigate it with limits, queues and careful query design.

With separate deployments, a heavy client mostly affects itself, and you can give a large client more resources without touching the others. See how far a single server can take your product.

Operations

Shared systems have fewer moving parts: one app, one database, one set of backups. Per-client deployments multiply them: many databases to back up, many instances to monitor, many migrations to run.

This is manageable only with automation:

Data residency and client requirements

Some clients need their data stored in a particular country or region, or on infrastructure they approve. Larger organizations, including many in the GCC, may also ask for their own environment as a condition of purchase. Per-client deployments make these requests straightforward: you deploy that client where it needs to be. In a shared system, they can require a separate installation anyway.

Security beyond the data

Isolation is not only about the database. In a shared system, file uploads, caches, search indexes, background jobs and logs must all be tenant-aware as well. Photos uploaded by one client should never be reachable through another client's links, and an error log should not mix sensitive details from several companies. With per-client deployments, these concerns are separated by default, which removes a whole category of subtle mistakes.

Leaving

When a client leaves, a per-client deployment can be exported and handed over cleanly, then deleted. In a shared system, extracting and deleting one client's data across shared tables takes more care.

How to choose

Lean towards multi-tenant when:

Lean towards per-client deployments when:

For NeonTask, which serves several facility-maintenance companies that each manage their own clients, sites and finances, per-client deployments were the natural fit. For a consumer-facing booking app like Pro Clean+, the question does not arise in the same way, because there is one business and many customers.

Designing so you can change later

Whichever model you start with, a few habits keep options open:

That way, moving from per-client to shared, or offering a dedicated deployment to a large client of a shared product, is a project rather than a rewrite.

Summary

Multi-tenant systems win on cost and simplicity at scale. Per-client deployments win on isolation, flexibility and client trust, at the price of automation work. Choose based on who your customers are, not on what is fashionable.

If you are designing a B2B product and want help with the architecture, read about me, see the NeonTask case study, and get in touch.

More from the blog

Let's work
together