---
title: "Multi-Tenancy"
space: "Frappe Framework"
url: "https://www.prilk.com/docs/frappe-framework/multi-tenancy"
updated: "2026-05-14"
---

## Multi-Tenancy

A single Frappe **bench** can host many **sites**. Each site is fully isolated — its own database, files, users, and installed apps. That's how Frappe Cloud and Prilk-managed serve many customers off shared infrastructure.

### Bench vs Site

| Term | What |
|---|---|
| **Bench** | The working directory: Python env, app source code, common config |
| **Site** | One isolated installation: own DB, own files, own users |
| **App** | Code shared across the bench; install per site |

### Site isolation
Each site has:
- Its own MariaDB / PostgreSQL database (`<site>_xxxxxxx` convention)
- Its own `sites/<site>/public/files/` and `private/files/`
- Its own `site_config.json`
- Potentially different apps installed than the next site

Two sites on the same bench can run different minor versions of the same app (though usually they're aligned).

### URL routing
Nginx routes by hostname:

```
customer-a.example.com → site "customer-a"
customer-b.example.com → site "customer-b"
```

For local development: edit `/etc/hosts` to map hostnames to localhost; Frappe reads the `Host` header to pick the site.

### Cross-site operations
Sites don't share data. For cross-site reporting or admin operations, run a process per site:

```bash
for site in $(bench --site all list-apps | cut -d' ' -f1 | sort -u); do
    bench --site $site execute my_app.report.run_summary
done
```

### When to add a bench vs a site

| Need | Add |
|---|---|
| New isolated customer, same Frappe version | **New site** |
| Different Frappe version | **New bench** |
| Different Python / OS environment | **New bench** |

Multiple benches on one server is common during upgrades — old bench keeps running while new bench is set up alongside.
