Backend Development 7 min read

Implementing Multi‑Tenant Architecture in Laravel with the Stancl Tenancy Package

This guide walks through installing the Stancl Tenancy package, configuring Laravel for multi‑tenant support, defining a custom tenant model, setting central and tenant domains, adjusting route providers, running migrations, and creating tenants via Artisan, enabling fully isolated SaaS databases without altering existing application code.

Laravel Tech Community
Laravel Tech Community
Laravel Tech Community
Implementing Multi‑Tenant Architecture in Laravel with the Stancl Tenancy Package

The article introduces the Stancl Tenancy package, a plug‑and‑play solution that adds multi‑tenant capabilities to a Laravel application without requiring extensive code changes.

Installation is performed via Composer:

composer require stancl/tenancy

After installing, run the package’s installer:

php artisan tenancy:install

This command generates migration files, configuration files, route files, and a service provider.

Next, execute the migrations to create the necessary tables:

php artisan migrate

Register the newly created service provider in config/app.php (add the provider to the providers array):

/* Application Service Providers... */
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Providers\TenancyServiceProvider::class,

Define a custom tenant model ( app/Tenant.php ) that extends the base tenant and uses the HasDatabase and HasDomains traits:

Tell the package to use this model by editing
config/tenancy.php
:
'tenant_model' => \App\Tenant::class,
The application is split into two logical parts: a
central
app (login page, admin dashboard) and a
tenant
app (business logic). Adjust the route service provider so that routes are only loaded for the appropriate domain:
protected function mapWebRoutes()
{
    foreach ($this->centralDomains() as $domain) {
        Route::middleware('web')
            ->domain($domain)
            ->namespace($this->namespace)
            ->group(base_path('routes/web.php'));
    }
}

protected function mapApiRoutes()
{
    foreach ($this->centralDomains() as $domain) {
        Route::prefix('api')
            ->domain($domain)
            ->middleware('api')
            ->namespace($this->namespace)
            ->group(base_path('routes/api.php'));
    }
}

protected function centralDomains(): array
{
    return config('tenancy.central_domains');
}
Define the central domains in
config/tenancy.php
(e.g.,
saas.test
) and protect tenant routes with the
PreventAccessFromCentralDomains
middleware:
Route::middleware(['web', InitializeTenancyByDomain::class, PreventAccessFromCentralDomains::class])
    ->group(function () {
        Route::get('/', function () {
            return 'This is your multi-tenant application. The id of the current tenant is '.tenant('id');
        });
    });
Optionally dump all users for debugging:
Route::get('/', function () {
    dd(\App\User::all());
    return 'This is your multi-tenant application. The id of the current tenant is '.tenant('id');
});
Move tenant‑specific migrations to
database/migrations/tenant
so that tables are created per tenant database.
Finally, create tenants via Artisan Tinker:
$tenant1 = Tenant::create(['id' => 'foo']);
$tenant1->domains()->create(['domain' => 'foo.saas.test']);

$tenant2 = Tenant::create(['id' => 'bar']);
$tenant2->domains()->create(['domain' => 'bar.saas.test']);
Populate each tenant’s database with users:
App\Tenant::all()->runForEach(function () {
    factory(App\User::class)->create();
});
Visiting
foo.saas.test
or
bar.saas.test
now shows isolated user data, demonstrating that the application code remains unchanged while the tenancy package handles database switching automatically.
DatabaseSaaSMulti-tenancyLaravelTenancy
Laravel Tech Community
Written by

Laravel Tech Community

Specializing in Laravel development, we continuously publish fresh content and grow alongside the elegant, stable Laravel framework.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.