# A Multi-Tenant Laravel Admin Panel With Laravilt: Single Database or One Database per Tenant

> Laravilt panels can be tenant-aware in two ways: records scoped to a team in one database, or a separate database and subdomain per tenant. How to set up each, and how to choose.

*2026-10-12T12:32:35Z*

Every SaaS admin panel hits the same question early: how do you keep one customer's data away from another's? Laravilt panels answer it in the panel provider, with one of two tenancy modes.

**The short answer:** for most apps, use **single-database tenancy**: call `->tenant(Team::class, 'team', 'slug')` on your panel and records are scoped to the current team automatically, at `/admin/{tenant}/...`. When you need strict isolation, compliance or per-tenant backups, use **multi-database tenancy**: `->multiDatabaseTenancy(Tenant::class, 'myapp.com')` gives each tenant its own database and subdomain, managed with `tenant:create` and `tenants:migrate`.

## The two modes

| Mode | How data is stored | Routing |
|------|-------------|---------|
| Single database | One shared database, records scoped to a tenant | Path: `/admin/{tenant}/...` |
| Multi-database | A separate database per tenant | Subdomain: `{tenant}.myapp.com/admin/...` |

## Single database: teams as tenants

Publish the teams migration, model and trait, then migrate:

```bash
php artisan vendor:publish --tag=laravilt-teams-migration
php artisan vendor:publish --tag=laravilt-teams-model   # app/Models/Team.php
php artisan vendor:publish --tag=laravilt-teams-trait   # app/Concerns/HasTeams.php
php artisan migrate
```

Your `User` implements `HasTenants` and `HasDefaultTenant` and uses the `HasTeams` trait, which gives you `teams()`, `currentTeam()`, `switchTeam()`, `ownsTeam()`, `teamRole()` and the methods the panel needs to decide who can open which tenant.

Then turn it on in the panel:

```php
use App\Models\Team;
use Laravilt\Panel\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        ->tenant(Team::class, 'team', 'slug')   // model, ownership relationship, slug attribute
        ->tenantRegistration()
        ->tenantProfile();
}
```

Resources are scoped to the current team automatically. `tenantRegistration()` lets users create a team, and `tenantProfile()` gives team owners a settings page at `/{panel}/tenant-settings` to manage the name and members.

## Multi-database: a database per tenant

Publish the config and the migrations for the central `tenants`, `domains` and tenant-user tables:

```bash
php artisan vendor:publish --tag=laravilt-tenancy-config
php artisan vendor:publish --tag=laravilt-tenancy-migrations
php artisan migrate
```

Then tell the panel which models live where:

```php
use Laravilt\Panel\Models\Tenant;

public function panel(Panel $panel): Panel
{
    return $panel
        ->multiDatabaseTenancy(Tenant::class, 'myapp.com')
        ->tenantModels([
            \App\Models\Customer::class,
            \App\Models\Product::class,
        ])
        ->centralModels([
            \App\Models\User::class,
            \App\Models\Plan::class,
        ])
        ->tenantRegistration()
        ->tenantProfile()
        ->tenantMenu();
}
```

`tenantModels()` live in each tenant's database. `centralModels()`, such as users and plans, stay in the central one. `tenantMenu()` adds a tenant switcher.

Tenants are managed from the command line:

```bash
php artisan tenant:create "Acme Corp" --slug=acme --email=admin@acme.com --seed
php artisan tenants:migrate                       # every tenant
php artisan tenants:migrate --tenant=acme --fresh --seed
php artisan tenant:delete acme --keep-database
```

The config file, `config/laravilt-tenancy.php`, reads the mode from `TENANCY_MODE` and the tenant database prefix from `TENANT_DB_PREFIX` (default `tenant_`).

## How to choose

**Single database** fits small and medium apps, keeps database overhead low, and works when tenants share some data.

**Multi-database** fits when you need strict data isolation, have compliance requirements, or want to back up, restore or scale one tenant on its own.

If you're not sure, start with single database. It's simpler to run, and many SaaS products never need more.

## Honest limits

- **Multi-database means more to run.** Every migration runs once per tenant, and backups, monitoring and connection limits all scale with the number of tenants.
- **Moving between modes is a data migration.** The panel config changes in a few lines, but moving existing records into per-tenant databases (or back) is real work. Choose early.
- **Laravilt is young.** If you need a large set of ready-made tenancy plugins today, check what exists first.

## FAQ

### Does Laravilt support multi-tenancy?
Yes. It supports single-database tenancy, with records scoped to a tenant such as a team, and multi-database tenancy, with a separate database and subdomain for each tenant.

### How do I make teams the tenant in a Laravel admin panel?
Publish Laravilt's teams migration, model and trait, add `HasTeams` to your `User` model, and call `->tenant(Team::class, 'team', 'slug')` on the panel.

### Can each tenant have its own database?
Yes. Use `->multiDatabaseTenancy(Tenant::class, 'myapp.com')`. Each tenant gets its own database and a subdomain such as `acme.myapp.com`.

### How do I run migrations for every tenant?
Run `php artisan tenants:migrate`. Add `--tenant=acme` to migrate one tenant, and `--fresh --seed` to rebuild it.

## Next steps

- [Multi-tenancy docs](/en/docs/panel/tenancy) · [teams tenancy](/en/docs/panel/tenancy/teams)
- [Laravilt vs Filament](/en/blog/laravilt-vs-filament)
- [Live demo](https://demo.laravilt.com)

Building a multi-tenant SaaS on Laravel? I design and build them, including white-label for agencies. See [product engineering](https://fadymondy.com/en/services/product-engineering?utm_source=laravilt&utm_medium=referral&utm_campaign=seo-content-oct26) or [get in touch](https://fadymondy.com/en/contact?utm_source=laravilt&utm_medium=referral&utm_campaign=seo-content-oct26).

---

Source: https://laravilt.com/en/blog/laravel-multi-tenant-admin-panel-laravilt
