Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

Building Multi-Tenant SaaS Applications in Laravel — 2026 Expert Guide

By Kokil Thapa | Last reviewed: September 2026

Deploying a multi-tenant Laravel SaaS is not the same as shipping a single-tenant app. You must resolve tenants on every request, isolate data and files, run migrations safely across hundreds of databases, and roll out code without breaking active customer sessions. The best way to deploy a multi tenant Laravel app starts with picking the right tenancy model, then wiring deployment automation that treats tenant provisioning as part of the pipeline — not a manual ops task. I've maintained production Laravel systems since 2010, including platforms on shared Linux VPS infrastructure with GitLab CI and Deployer. This guide covers architecture, deployment workflows, packages, security, and scaling for 2026.

What Is the Best Way to Deploy a Multi Tenant Laravel App?

Start with one deployable application and one central database for tenants, billing, and domains. Tenant-specific data lives in shared tables, separate schemas, or dedicated databases depending on your isolation needs. Your deployment pipeline must do four things on every release: run central migrations, run tenant migrations, clear tenant-scoped caches, and reload PHP workers so opcache picks up new code.

On real client projects, I use Deployer 7 with symlinked releases for VPS deployments. The same pattern powers several sister sites on shared EC2 infrastructure. For rapid-growth SaaS, Laravel Vapor on AWS Lambda removes server management while Aurora handles database scaling.

Multi-Tenant Laravel Deploy PipelineGit Pushmain branchGitLab CItest + buildDeployerzero downtimeProductionPHP 8.3 + NginxPost-Deploy Tenant TasksCentral migrateTenant migrateCache purgeQueue restartPHP-FPM reload
Best way to deploy a multi tenant Laravel app: CI test, Deployer release, then tenant-aware post-deploy steps

For most SaaS products on Laravel 12 or 13, this stack works well on Ubuntu 22/24:

  1. PHP 8.3 or 8.5 with PHP-FPM behind Nginx
  2. MySQL 8.4 LTS or PostgreSQL 18 for central and tenant databases
  3. Redis 8.10 for cache, sessions, and queues
  4. GitLab CI pipeline: lint, PHPUnit, asset build, then Deployer deploy
  5. Horizon for queue monitoring across tenant-specific queues

See the step-by-step walkthrough in our GitLab CI deploy guide for Laravel VPS and zero-downtime Deployer setup. For Nginx configuration details, read how to deploy Laravel on Ubuntu VPS with Nginx.

Sample Deployer hook for tenant migrations

task('tenants:migrate', function () {
    run('{{bin/php}} {{release_path}}/artisan tenants:migrate --force');
});

after('artisan:migrate', 'tenants:migrate');
after('deploy:symlink', 'php-fpm:reload');

Run central migrations first, then tenant migrations. Never skip the PHP-FPM reload after symlink swap. Stale opcache is a common post-deploy failure I've seen on production servers.

How Do You Choose a Multi-Tenant Architecture Before Deployment?

Your tenancy model determines how complex deployment becomes. Pick wrong and every release gets harder. For database-layer specifics, read our multi-tenant database architecture guide. Here is a practical comparison from production systems.

1. Single database, shared schema (tenant_id column)

All tenants share the same tables. Every row includes a tenant_id column that scopes queries.

AspectDetails
ProsSimplest to build, lowest cost, single migration path, easy cross-tenant reporting
ConsWeakest isolation, data leak risk if scoping is missed, harder beyond 10,000+ heavy tenants
Best forEarly-stage SaaS, MVPs, low-compliance industries

The critical risk is a missing where('tenant_id', ...) clause. Global scopes mitigate this:

// App\Models\Traits\BelongsToTenant.php
protected static function booted()
{
    static::addGlobalScope('tenant', function ($query) {
        $query->where('tenant_id', app('tenant')->id);
    });
}

2. Single database, separate schemas

Each tenant gets its own schema. The app switches schema context at runtime.

AspectDetails
ProsBetter isolation, per-tenant backup, lower cross-tenant leak risk
ConsSchema management complexity, migrations per tenant, impractical beyond ~500 tenants
Best forB2B SaaS with moderate tenant counts

3. Multiple databases (one database per tenant)

Each tenant gets a separate database. The app resolves the connection dynamically.

AspectDetails
ProsStrongest isolation, compliance-ready, independent scaling per tenant
ConsHighest cost, connection pooling complexity, deployment automation required
Best forEnterprise SaaS, fintech, healthcare, strict data residency
config(['database.connections.tenant' => [
    'driver'   => 'mysql',
    'host'     => $tenant->db_host,
    'database' => $tenant->db_name,
    'username' => $tenant->db_user,
    'password' => decrypt($tenant->db_password),
]]);

DB::purge('tenant');
DB::reconnect('tenant');
Tenancy Architecture ComparisonShared Schematenant_id columnFastest deployWeakest isolationSeparate Schemasone schema eachMid complexity~500 tenant limitDedicated DBsfull isolationEnterprise readyHighest ops costHybrid Deploy Pattern (Recommended)Free/starter plans on shared schemaEnterprise tenants migrate to dedicated DBsSame codebase, different connection config
Choose your multi-tenant architecture before deployment — hybrid models balance cost and isolation

How Does Tenant Identification Work in a Deployed Laravel SaaS?

Before tenant logic runs, the app must identify the current tenant. This happens in middleware, early in the request lifecycle.

Subdomain-based identification

The most common SaaS pattern: acme.yourapp.com, globex.yourapp.com.

// TenantMiddleware.php
public function handle($request, Closure $next)
{
    $subdomain = explode('.', $request->getHost())[0];
    $tenant = Tenant::where('slug', $subdomain)->firstOrFail();
    app()->instance('tenant', $tenant);

    return $next($request);
}

Custom domain identification

Enterprise tenants often want app.clientcompany.com via CNAME.

$tenant = Tenant::where('custom_domain', $request->getHost())->first();

This requires SSL automation with Let's Encrypt and Certbot. Verify domain ownership during onboarding to prevent DNS rebinding attacks.

Path-based identification

Pattern: yourapp.com/acme/dashboard. Less common for production SaaS but useful for internal tools.

Tenant Request ResolutionHTTP Requestsubdomain/hostMiddlewareresolve tenantSwitch DBset connectionAppProduction SaaS ComponentsAuth layerBillingFile storageQueuesCache prefixRate limitsRBAC scope
Deployed multi-tenant Laravel apps resolve tenant context before database, cache, and queue operations

What Are the Essential Components of a Production Multi-Tenant SaaS?

Beyond database architecture, a deployable multi-tenant system needs interconnected components. Plan these before your first production release.

Tenant-aware authentication

Two patterns exist. Choosing wrong is expensive to reverse.

  • Central authentication (SSO) — users sign in once and access multiple workspaces. Store users centrally with a pivot table linking users to tenants.
  • Tenant-scoped authentication — each tenant has its own user table or scoped tenant_id. Users cannot cross tenant boundaries.

Most SaaS products use central auth with tenant switching. It gives the best UX while keeping security boundaries intact.

Automated tenant onboarding

Onboarding should need zero manual ops intervention:

  1. New customer registers on the central domain
  2. System creates a tenant record in the central database
  3. Subdomain or custom domain is provisioned
  4. Tenant database or schema is created and migrated
  5. Default roles, permissions, and settings are seeded
  6. First admin user is assigned to the tenant
  7. Welcome email triggers with login credentials
  8. First billing cycle initiates (trial or paid)

With stancl/tenancy, steps 3–5 happen through tenant lifecycle events. The official Laravel deployment documentation covers environment and optimization flags you should set before going live.

Subscription billing

Laravel Cashier handles Stripe or Paddle integration. Critical rule: billing data always lives in the central database, never in tenant databases. This prevents data loss if a tenant DB is deleted.

  • Per-seat pricing with automatic proration
  • Usage metering (API calls, storage, bandwidth)
  • Plan upgrades and downgrades with grace periods
  • Trial periods with automatic conversion
  • Webhook handling for failed payments
  • Invoice generation with tenant branding

Tenant resource isolation

Beyond the database, isolate these resources at deploy time:

  • File storage — tenant-prefixed paths: s3://bucket/tenants/{tenant_id}/uploads/
  • Cache — prefix keys: cache()->put("tenant_{$id}_settings", $value)
  • Queues — tag jobs: dispatch($job)->onQueue("tenant-{$id}")
  • Redis — per-tenant key prefixes or separate Redis databases

Projects like Ajako Deal — a multi-user marketplace — show why role isolation and resource scoping matter from day one. For SaaS stack decisions, see choosing a tech stack for a new SaaS and why Laravel fits SaaS products in Nepal.

Which Laravel Packages Should You Use for Multi-Tenant Deployment in 2026?

The package ecosystem has matured. These are the production-proven options for Laravel 12 and 13 on PHP 8.3+.

stancl/tenancy — the production standard

The most maintained multi-tenant package for Laravel. It supports multi-database tenancy, automatic provisioning, custom domains, tenant-aware caching, queues, and filesystem, plus central and tenant route separation.

composer require stancl/tenancy
php artisan tenancy:install
php artisan migrate

Spatie Laravel Permission — tenant-scoped RBAC

I use Spatie Permission regularly for per-tenant roles. Combined with tenant context, each tenant defines roles without affecting others. See Kokil Thapa's background for the full stack I ship in production.

Laravel Cashier — billing engine

Handles Stripe or Paddle subscriptions, trials, invoicing, and webhooks. Install in the central application context only.

Laravel Octane — performance layer

For high-traffic SaaS, Laravel Octane with FrankenPHP or Swoole cuts response times. Critical: reset tenant state between requests to prevent data leakage in long-running workers.

How Do You Secure and Scale a Deployed Multi-Tenant Laravel App?

Security is non-negotiable. One vulnerability can expose every tenant simultaneously. Scaling strategy depends on your tenancy architecture.

Mandatory tenant scoping

// WRONG — returns any user regardless of tenant
User::find($id);

// CORRECT — scoped to current tenant
User::where('tenant_id', tenant()->id)->findOrFail($id);

// BEST — automatic via global scope
User::findOrFail($id);

Cross-tenant request prevention

  • Validate every resource ID belongs to the current tenant before processing
  • Never share sessions or tokens across tenant boundaries
  • Sanitize custom domain inputs during onboarding
  • Encrypt tenant secrets (API keys, DB credentials) with Laravel encryption

Read our guide on securing your website and server for Nginx hardening and SSL configuration. Use the JSON formatter tool to inspect webhook payloads during billing integration testing.

Scaling shared database tenancy

  • Add composite indexes on (tenant_id, primary_key)
  • Implement query caching with tenant-scoped keys
  • Use read replicas for reporting queries
  • Consider table partitioning by tenant_id beyond 100M rows

Scaling separate database tenancy

  • Move high-traffic tenants to dedicated RDS instances
  • Use connection pooling (PgBouncer or ProxySQL)
  • Automate DB provisioning with Terraform
  • Run a data warehouse for cross-tenant analytics

Application layer scaling

  • Laravel Octane — sub-millisecond responses for hot paths
  • Horizontal scaling — multiple app instances behind a load balancer
  • Queue workers — scale via Laravel Horizon
  • CDN — serve static assets via CloudFront or Cloudflare

Serverless scaling with Laravel Vapor

For rapid tenant growth, Laravel Vapor on AWS Lambda auto-scales without server management. Combined with Aurora Serverless, costs stay proportional to usage. See our serverless Laravel deployment guide for the full walkthrough.

Deploy Architecture by SaaS StageMVP / Early StageShared DB + VPS + DeployerGrowing B2BSchemas + GitLab CI + HorizonEnterpriseDedicated DB per tenantHybrid (Recommended)Shared free + dedicated enterpriseDeploy Checklist Before Go-LiveStaging mirrors prod · tenant migrate tested · rollback plan readyBackups per tenant · monitoring per queue · rate limits per tenant
Best way to deploy a multi tenant Laravel app changes as your SaaS matures from MVP to enterprise

Which architecture should you choose?

SaaS StageRecommended ArchitectureWhy
MVP / Early-stageSingle DB + tenant_idFastest to build, lowest cost, easy to iterate
Growing B2BSingle DB + separate schemasStronger isolation, manageable complexity
Enterprise / ComplianceDedicated DB per tenantMaximum security, GDPR/HIPAA/PCI ready
HybridShared for free + dedicated for enterpriseBalances cost with enterprise isolation

The hybrid approach is common in 2026. Start with shared tenancy for cost efficiency. Migrate high-value tenants to dedicated databases when they upgrade. Laravel's ecosystem — stancl/tenancy, Cashier, Octane, Vapor, and Spatie Permission — covers production needs. You can start simple and evolve architecture as revenue grows. For a shipped example, see Nepal Gift Card, a Laravel platform with isolated customer data flows.

Key Takeaways

  • Pick your tenancy model before writing deploy scripts — shared schema for MVPs, hybrid for growth, dedicated DBs for enterprise.
  • Run central migrations first, then tenants:migrate, then reload PHP-FPM on every release.
  • Store billing, tenant records, and domains in the central database only.
  • Prefix cache keys, queue names, and S3 paths with tenant IDs to prevent cross-tenant leaks.
  • Use GitLab CI plus Deployer for VPS, or Vapor plus Aurora for serverless auto-scaling.
  • Test tenant isolation in staging with at least two tenants before every production deploy.

People Also Ask

Can you deploy a multi-tenant Laravel app on shared hosting?

Shared hosting works for early MVPs with subdomain tenancy and a single shared database. Once you need custom domains, per-tenant migrations, or dedicated queue workers, move to a VPS or cloud platform. Shared hosting cannot run Horizon, Octane, or reliable zero-downtime deploys.

How do you run migrations for hundreds of tenant databases?

Use php artisan tenants:migrate from stancl/tenancy inside your Deployer or CI post-deploy hook. Run it after central migrations complete. For large tenant counts, batch migrations in queue jobs and monitor failures per tenant.

Is Laravel Vapor better than VPS for multi-tenant SaaS?

Vapor suits unpredictable traffic and rapid tenant growth because Lambda scales automatically. VPS with Deployer suits predictable workloads and gives you full server control at lower baseline cost. Many teams start on VPS and move hot paths to Vapor later.

What is the biggest deployment mistake in multi-tenant Laravel?

Deploying code without running tenant migrations. Central migrations succeed, but tenant databases stay on old schema versions. Automate tenant migrations in every pipeline and block deploys if any tenant migration fails.

Deploy Your Multi-Tenant Laravel SaaS With Confidence

The best way to deploy a multi tenant Laravel app combines the right architecture with automated pipelines that treat tenant provisioning and migration as first-class steps. Start with shared tenancy and GitLab CI on a VPS if budget is tight. Add hybrid database isolation and Horizon queues as paying customers arrive. Laravel 12 on PHP 8.3 gives you a stable foundation through 2027.

Need help architecting or reviewing your tenancy implementation? Contact us for a deployment audit. For full-stack engineering support, see our enterprise application development services in Nepal. You can also explore more Laravel guides on the blog or review our portfolio of production platforms.

Frequently Asked Questions

Multi-tenancy means hosting multiple customers inside one Laravel application while keeping their data, configuration, and users isolated.

The stancl/tenancy package is the production standard for Laravel multi-tenancy in 2026.

A well-optimized shared database with proper indexing can handle 5,000 to 10,000+ tenants before requiring sharding or migration to separate databases.

Single database tenancy uses a tenant_id column to separate data within shared tables — simpler but weaker isolation. Multi-database tenancy gives each tenant their own database — strongest isolation but higher infrastructure cost and complexity. Most early-stage SaaS products start with single database and migrate high-value tenants to dedicated databases as they grow.

The three common identification strategies are subdomain-based (acme.yourapp.com), custom domain (app.clientcompany.com via CNAME), and path-based (yourapp.com/acme/dashboard). Subdomain identification is the most widely used pattern for SaaS because it is clean, scalable, and easy to provision automatically during tenant onboarding.

Billing data must always live in the central database, never in tenant databases. This prevents data loss if a tenant's database is removed, keeps billing logic independent of tenant state, and simplifies subscription management. Laravel Cashier integrates directly with the central application for Stripe or Paddle billing.

Use Laravel global scopes on every tenant model to automatically add tenant_id conditions to all queries. Additionally, validate that every resource ID in requests belongs to the current tenant, never share sessions across tenant boundaries, encrypt tenant-specific secrets, and run automated tests that verify isolation boundaries are enforced.

Yes. Laravel Vapor on AWS Lambda provides auto-scaling for multi-tenant SaaS without server management. Combined with Aurora Serverless for databases, this architecture handles traffic spikes automatically and keeps costs proportional to usage. The stancl/tenancy package is compatible with Vapor deployments.

Use tenant-prefixed paths for all file storage. For S3, structure paths as tenants/{tenant_id}/uploads/. For local storage, use storage/app/tenants/{tenant_id}/. Never allow tenants to access files outside their prefix. The stancl/tenancy package provides automatic filesystem tenancy that handles path prefixing.

Central authentication with tenant switching provides the best balance of user experience and security. Users sign in once to a central domain, then access their tenant workspaces. Store users in the central database with a pivot table linking users to tenants. This allows one person to work across multiple organizations without separate login credentials.

Separate migrations into central and tenant categories. Central migrations run once on the main database for shared tables like tenants, users, and billing. Tenant migrations run on every tenant's database or schema. With stancl/tenancy, the command php artisan tenants:migrate automatically runs pending migrations across all tenant databases.

Yes, multi-tenancy adds significant architectural complexity around data isolation, tenant discovery, scoped authentication, resource separation, and billing. However, Laravel packages like stancl/tenancy abstract most of this complexity. A competent Laravel developer can set up basic multi-tenancy in a few days — the ongoing challenge is maintaining isolation guarantees as the application grows.

Tag every dispatched job with its tenant context so workers can restore the correct tenant state before processing. Use dedicated queues for high-priority tenants or resource-intensive operations. Scale queue workers horizontally using Supervisor or Laravel Horizon. Monitor queue depth per tenant to identify performance bottlenecks before they affect other tenants.

GDPR requires the ability to fully delete a tenant's data on request — easier with dedicated databases. HIPAA and PCI-DSS mandate strict data isolation that shared databases may not satisfy without additional controls. Data residency laws may require tenant data to be stored in specific geographic regions. For compliance-heavy industries, dedicated database per tenant is the safest architecture choice.

Yes, but it requires careful planning. The migration involves creating individual databases for each tenant, copying their data from the shared tables, updating the tenant discovery logic to resolve the correct database, and running parallel systems during the transition period. Plan for this possibility early by keeping your tenant scoping logic abstracted behind interfaces so the switch does not require rewriting business logic.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: