Running a SaaS on a single server feels safe at first. One code base, one DB, one dashboard. But growth soon knocks on the door. You need more clients, more regions, more data, and you don’t want to rebuild everything. In this guide we walk through a usable path to go from one instance to many, all while keeping your existing data intact.
By the end you’ll know how to design tenant isolation, flip feature flags, spin up new tenants automatically, shard your database, and watch each tenant’s health in real time. No big migrations, no downtime, just a clean scale‑out that lets you add customers like you add new rows in a spreadsheet.
Step 1: Design a Tenant Isolation Strategy
Isolation is the foundation. If one tenant can see another’s data, you risk compliance breaches and lost trust. Start by asking: does each client need its own user store, its own file system, or just a logical partition?
We recommend a three‑layer model:
- Network layer, separate VPCs or subnets for high‑risk tenants.
- Application layer, use a tenant‑ID column on every table and enforce it in code.
- Access layer, RBAC (role‑based access control) and audit logs per tenant.
Donely already builds RBAC and audit logs into every instance, which saves you a lot of custom work. That’s why it shows up as the only platform with native audit‑log capability in our recent survey.
When you map out the isolation model, sketch a quick diagram. Write down each tenant’s boundary and the data flows that cross it. This visual helps you spot hidden dependencies before you code.
Next, decide the granularity of your RBAC. Do you need role groups per tenant, or a global admin that can jump between tenants? Most early‑stage teams start with a per‑tenant admin and a global read‑only auditor. That keeps the permission matrix simple.
Finally, make sure your logging solution tags every log entry with the tenant ID. That way you can pull an audit trail for any client without sifting through unrelated records.
Once you’ve locked down the design, you can move to the next step with confidence.
For a deeper dive on isolation best practices, see our multi‑tenant SaaS platform guide. It walks you through VPC setup, RBAC patterns, and audit‑log wiring in a hands‑on way.
According to Wikipedia’s definition of multitenancy, the goal is to share resources while keeping data separate. That principle drives every decision we make here.
Step 2: Implement Multi‑Tenant Architecture with Feature Flags
Feature flags let you turn on or off code for a specific tenant without redeploying. They’re a safety net when you roll out new features to a single client first.
Start by adding atenant_idfield to your flag store. Each flag record should have a list of tenant IDs it applies to. When a request comes in, look up the flag set for that tenant and branch accordingly.
This approach lets you test a beta feature on one tenant, collect feedback, and then expand. It also helps you meet compliance needs , you can disable a feature for regulated customers instantly.
Donely’s dashboard includes a built‑in flag manager. You can click a button and the flag is live for the chosen instance in seconds. That speed is a big win for agencies that need to show clients rapid iteration.
Here’s a quick checklist for flag implementation:
- Store flags in a fast KV store (Redis or DynamoDB).
- Cache flag look‑ups per request to avoid extra latency.
- Provide an admin UI that lists flags per tenant.
- Log every flag change with tenant ID for audit purposes.
When you design the flag schema, avoid hard‑coding tenant IDs in code. Keep them in config files or a database table. That way you can add new tenants without touching the source.
Feature flags also help you phase out legacy code. Turn off the old path for a tenant once the new path proves stable.
Imagine you have a payment integration that only works in the EU. You can enable it for EU tenants via a flag, while keeping US tenants on the old gateway.
Our next internal link shows how a solo founder used Donely to spin up isolated instances without any DevOps hassle: AI‑Powered Desktop Assistant for macOS. The post details the one‑click instance creation that powers the flag system.
For a technical deep dive on flagging patterns, see the MDN documentation on cache control headers. It explains how to use HTTP caching to keep flag checks fast.

Step 3: Automate Tenant Provisioning and Infrastructure
Manual setup kills speed. Automation gives you a repeatable, error‑free flow that can handle dozens of new tenants a day.
Begin with an IaC (Infrastructure as Code) tool like Terraform or Pulumi. Define a template that includes:
- Network resources (subnet, security groups).
- Compute resources (container cluster, autoscaling rules).
- Database schema (tenant‑specific schemas or row‑level security).
- Monitoring hooks (alerts, dashboards).
Store the template in a repo. When a sales team signs a new client, trigger a CI/CD pipeline that runs the template with the newtenant_id. The pipeline should also create the RBAC roles and audit‑log bindings automatically.
Donely’s platform offers an API that can spin up a new instance in under two minutes. By calling that API from your pipeline you get the same speed without building the infra yourself.
To keep costs in check, use a “pay‑as‑you‑grow” model. Provision only what the tenant needs , a small container for a starter client, a larger cluster for an enterprise. Tag resources with the tenant ID so you can track spend.
Automation also helps with secret management. Pull secrets from a vault (e.g., HashiCorp Vault) during provisioning and inject them as environment variables. That way no secret lives in code.
Finally, add a post‑provisioning test step. Spin up a health check that confirms the new tenant can connect to the DB, that the flag set is loaded, and that logs are flowing. If any check fails, the pipeline rolls back automatically.
Here’s a simple Bash snippet that could start the process:
#!/bin/bash
TENANT=$1
terraform apply -var tenant_id=$TENANT
curl -X POST https://api.donely.ai/instances -d "{"tenant_id": "$TENANT"}"
Remember to store the script in a secure location and give it only the permissions it needs.
Step 4: Use Database Sharding and Caching per Tenant
When you add tenants, a single monolithic DB can become a bottleneck. Sharding spreads the load across multiple nodes, keeping each tenant’s data fast and isolated.
Two common sharding patterns work well for SaaS:
Pick the pattern that matches your DB technology and expected scale. For PostgreSQL, schema‑per‑tenant is easy to manage with row‑level security. For MySQL or DynamoDB, horizontal sharding is more natural.
Cache frequently accessed tenant data at the edge. Use a CDN‑backed cache for static assets and an in‑memory cache like Redis for dynamic look‑ups. Make sure the cache key includes the tenant ID, otherwise you risk serving one client’s data to another.
Donely’s platform already adds a Redis layer per instance, so you can enable caching with a single toggle. That reduces latency for AI agents that need quick access to recent conversation history.
Don’t forget to set TTLs (time‑to‑live) on cached entries. Short TTLs keep data fresh, while longer TTLs reduce DB hits for rarely changed reference data.
Monitoring cache hit rates per tenant helps you spot when a tenant’s workload is causing cache thrashing. If hit rate drops below 80% for a tenant, consider adding more cache nodes or splitting that tenant onto its own shard.
Here’s a quick diagram you can sketch on a whiteboard:
Client → Load Balancer → API Layer (tenant_id) → Shard Router → DB Shard
Now embed a short video that walks through setting up a sharded Postgres cluster:
After the video, you’ll see how to add a new tenant to the router table, spin up a new cache bucket, and verify the data path.
Donely’s own documentation on multi‑instance scaling shows a real‑world example of sharding across AWS Aurora. It’s a good reference if you want to copy the pattern.
For more on sharding fundamentals, check the Scaleway blog on multi‑tenant vs multi‑instance. The article explains why sharding is essential when you move beyond a handful of tenants.
Step 5: Monitor, Optimize, and Iterate Per Tenant
Scaling isn’t a one‑time task. Each tenant will have its own performance profile, error patterns, and usage spikes.
Start with a unified monitoring stack. Pull metrics from every instance into a central Prometheus server, then use Grafana dashboards that filter by tenant ID.
Key metrics to watch per tenant:
- CPU and memory usage of the tenant’s containers.
- Database query latency and error rates.
- Cache hit‑rate.
- Feature‑flag toggle frequency.
- Audit‑log volume.
Set alerts that fire only for the affected tenant. That avoids noisy alerts that swamp the on‑call team.
When you notice a tenant consistently hitting a limit, consider autoscaling that tenant’s resources instead of a global scale‑up. Many cloud providers let you set per‑service scaling policies based on custom labels.
Regularly run a health‑check script that verifies RBAC settings, flag consistency, and backup integrity for each tenant. Schedule it to run nightly and send a summary report to the tenant admin.
Iterate based on feedback. If a tenant requests a new integration, add it to that tenant’s scope only. Donely’s per‑instance integration catalog lets you do this without affecting other clients.
Finally, keep the audit logs searchable. Offer a simple UI where a tenant admin can filter logs by date, action, or user. That builds trust and reduces support tickets.
Our third internal link gives a concrete example of how agencies use Donely’s multi‑instance dashboard to keep tabs on dozens of clients: AI Employee Hosting: 7 Platforms That Cut DevOps Work. The guide walks through the admin view that shows all instances at once.
Pro tip: rotate logs daily and archive them to cheap cold storage. That saves money and keeps your primary DB lean.

Frequently Asked Questions
Can I add a new tenant without redeploying my code?
Yes. By designing your app to read the tenant ID from the request and by using feature flags, you can spin up a new tenant via an API call. The code base stays the same, and the new tenant gets its own DB schema or shard automatically.
What’s the difference between multi‑tenant and multi‑instance?
Multi‑tenant shares a single code base and database with logical separation, while multi‑instance runs separate copies of the app for each client. Multi‑instance gives stronger isolation but can increase cost. The choice depends on compliance needs and expected scale.
Do I need a separate VPC for each tenant?
Not always. For high‑risk or regulated clients, an isolated VPC adds a strong network boundary. For lower‑risk tenants, subnet‑level segmentation plus RBAC is often enough. Start with a shared VPC and move high‑risk tenants to their own VPC as you grow.
How do I handle secret management across many tenants?
Store secrets in a vault that supports per‑tenant namespaces. When you provision a tenant, generate a unique secret path and grant the tenant’s service account read access only to that path. Rotate secrets regularly and log every access.
Is there a performance penalty for using feature flags?
Minimal if you cache flag values per request. Look up the flag once, store it in request context, and reuse it throughout the call. The biggest impact comes from database look‑ups, so keep the flag store in a fast KV engine like Redis.
What monitoring tools work best for per‑tenant metrics?
Prometheus with multi‑tenant label support works well. Pair it with Grafana dashboards that filter by tenant label. If you prefer a hosted solution, Datadog and New Relic both let you tag metrics with a tenant ID.
How do I back up data for each tenant?
Back up at the shard or schema level. Schedule daily snapshots and retain them for at least 30 days. Store backups in a separate bucket with encryption and access controls that limit who can restore a specific tenant’s data.
Can I migrate existing tenants to this new architecture later?
Yes, but plan a phased migration. Export each tenant’s data, spin up a new instance using the automated pipeline, import the data, and switch DNS or API endpoints. Run both old and new stacks in parallel for a short window to verify no data loss.
Scaling a SaaS without a migration nightmare is all about planning isolation, automating provisioning, and keeping an eye on each tenant’s health. By following these steps you’ll grow from a single sandbox to a fleet of secure, independent instances that you can manage from one dashboard.
Ready to see a real‑world example? for agencies that need to juggle dozens of AI agents. It shows how Donely’s per‑instance billing and RBAC make the operational side painless.
For further reading on scaling patterns, the Wikipedia article on scalability offers a solid overview of horizontal vs vertical growth strategies.
- Horizontal sharding by tenant ID, each shard holds a range of tenant IDs. Queries stay simple because the tenant ID tells you which shard to hit.
- Schema‑per‑tenant, each tenant gets its own schema within the same database server. This gives strong isolation but can hit the max‑schema limit on some engines.