Kritim Yantra
May 06, 2025
If you’re building a SaaS (Software as a Service) product with Laravel, where each customer has isolated data (like a CRM, School Management System, or Project Tool), you’ve likely come across the term multi-tenancy.
Multi-tenancy means one Laravel application serves multiple tenants (clients). Each tenant can have its own users, data, and even design.
In this guide, we'll learn how to implement multi-tenancy using the Tenancy for Laravel package, created by Stancl.
Imagine you're building an app like Notion or Slack. Each company (tenant) should:
This is where multi-tenancy comes in. You don't create a new Laravel project for each customer — you use one app and separate the data per tenant.
Tenancy for Laravel supports two types:
All tenants share one database but their records are separated using a tenant_id
.
✔️ Easy to set up
❌ Data not physically isolated
Each tenant has a separate database.
✔️ Full data isolation
✔️ Better for large clients
❌ Slightly complex setup
We’ll focus on multi-database as it’s the most powerful and scalable.
Let’s start from scratch.
composer create-project laravel/laravel multi-tenancy-app
cd multi-tenancy-app
composer require stancl/tenancy
Now publish the config file:
php artisan tenancy:install
This creates:
config/tenancy.php
Run migrations:
php artisan migrate
Tenancy uses a Tenant
model (stored in the central database) to store tenant metadata like domains.
You already have a tenants
table created after install.
You can create a tenant like this:
use Stancl\Tenancy\Database\Models\Tenant;
$tenant = Tenant::create([
'id' => 'acme', // Unique ID
]);
$tenant->domains()->create([
'domain' => 'acme.localhost', // Map domain
]);
🎯 Tip: Use
.localhost
for testing subdomains locally.
To test subdomains locally, edit your hosts
file:
127.0.0.1 acme.localhost
127.0.0.1 globex.localhost
Start Laravel server:
php artisan serve --host=localhost --port=8000
To isolate tenant data, you need tenant-specific tables (e.g., users
, projects
, etc.).
Create a migration using:
php artisan tenancy:make:migration create_users_table
It will be saved in database/migrations/tenant/
.
Example:
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamps();
});
Now run it for all tenants:
php artisan tenants:migrate
Tenancy will automatically detect the tenant based on the subdomain or domain.
You can configure this in config/tenancy.php
:
'identification_middleware' => [
\Stancl\Tenancy\Middleware\InitializeTenancyByDomain::class,
],
You can also use InitializeTenancyBySubdomain
.
By default, routes inside routes/tenant.php
are only accessible under tenant domains.
// routes/tenant.php
Route::get('/', function () {
return 'Tenant Home: ' . tenant('id');
});
Visit:
http://acme.localhost
It will show: Tenant Home: acme
To create seeders for tenants:
php artisan make:seeder TenantUserSeeder
Run for a specific tenant:
$tenant->run(function () {
\App\Models\User::factory()->count(10)->create();
});
If you're running artisan commands or jobs, you may want to switch tenants manually:
use Stancl\Tenancy\Tenant;
$tenant = Tenant::find('acme');
$tenant->run(function () {
// Code runs in tenant DB
\App\Models\User::create(['name' => 'Test']);
});
Tenancy fires many events during tenant lifecycle.
Example: Seed user after tenant creation
Event::listen(TenantCreated::class, function ($event) {
$event->tenant->run(function () {
User::create([
'name' => 'Admin',
'email' => 'admin@demo.com',
]);
});
});
Sometimes you want shared models like Plan
, Subscription
, etc.
Use UsesTenantConnection
trait for tenant models, and avoid it for central ones.
// Tenant Model
use Stancl\Tenancy\Database\Concerns\UsesTenantConnection;
// Central Model (normal Eloquent model)
class Plan extends Model {
// uses central database
}
Main App (central) — auth, pricing, subscription
When a user signs up:
Redirect to subdomain login
Each tenant has its own DB with user, projects, etc.
Tenancy for Laravel makes building multi-tenant SaaS platforms a breeze. It’s flexible, event-driven, and supports both single and multi-database setups.
You now have the tools to build:
Drop your questions or share your SaaS idea in the comments — happy to help!
Transform from beginner to Laravel expert with our personalized Coaching Class starting June 23, 2025. Limited enrollment ensures focused attention.
1-hour personalized coaching
Build portfolio applications
Industry-standard techniques
Interview prep & job guidance
Complete your application to secure your spot
Thank you for your interest in our Laravel mentorship program. We'll contact you within 24 hours with next steps.
No comments yet. Be the first to comment!
Please log in to post a comment:
Sign in with Google