How We Build Multi-Tenant SaaS Applications and Client Portals in Laravel
Ivan
Lead Engineer & Strategist at Softlimes

Single Database vs Database-Per-Tenant Architecture
Every multi-tenant Laravel project starts with an architectural decision between shared database tables with a tenant_id column or isolated databases per customer. A single shared PostgreSQL database is simpler to migrate and cheaper to run when you have hundreds of small tenants with uniform data structures.
On the other hand, enterprise healthcare, finance, and legal clients often require physical data isolation, custom backup schedules, or region-specific residency. For those platforms, we use a control-plane database that stores tenant routing records and provisions a dedicated PostgreSQL database for each organization automatically.
Preventing Cross-Tenant Data Leaks With Global Eloquent Scopes
In a shared-database portal, the most dangerous bug is a developer forgetting a WHERE tenant_id clause on a report query or export job. Relying on engineers to remember manual query filters on every controller method guarantees a data leak eventually.
We enforce tenant scoping at the base Eloquent model level using a BelongsToTenant trait that applies a global query scope automatically on every read and write operation. When an authenticated request enters the application, middleware resolves the active tenant from the subdomain or session token and binds it to the service container.
- Enforce NOT NULL foreign key constraints on tenant_id across every tenant-owned table in PostgreSQL.
- Prefix all Redis cache keys and Horizon queued job payloads with the active tenant identifier.
- Isolate uploaded customer files in S3 using tenant-specific bucket prefixes and signed temporary download URLs.
- Write automated PHPUnit feature tests that assert User A from Tenant 1 receives a 404 when requesting any resource ID from Tenant 2.
Keeping Tenant Context Intact Inside Queues and Scheduled Commands
Web requests have an obvious logged-in user and subdomain, but background jobs and nightly cron tasks run outside the HTTP lifecycle. If a queued invoice generator runs without explicit tenant context, global model scopes may fail or query the wrong connection.
We configure our queue serialization middleware to attach the tenant ID to every dispatched job payload. When a Horizon worker picks up the job, it initializes the tenant database connection, sets the S3 storage root, and scopes the logger before executing a single line of business logic.
Role Permissions, Audit Logs, and Stripe Billing Hooks
B2B client portals also need granular internal permissions so a client manager can invite their own accounting clerk or field technician with restricted access. We pair tenant scoping with role-based permission tables and an immutable activity log that records who viewed, edited, or exported any record.
By combining automated Stripe subscription webhooks with per-tenant feature flags, your team can launch new pricing tiers, onboard enterprise organizations in seconds, and pass third-party security audits with confidence.
Before any new multi-tenant release ships to production, our continuous integration pipeline runs automated tenant-isolation assertions against every API route. That automated safety net guarantees that new features never introduce cross-account data exposure.
Related Softlimes Service
Laravel Development
See how our engineering team scopes, builds, and supports this workflow in production.
Related articles by Ivan
Custom Website Development vs Page Builders When Traffic Grows
Drag-and-drop page builders help new businesses launch fast, but they create heavy DOM trees and plugin conflicts as traffic scales. We compare page builder overhead against clean custom code in Next.js, Laravel, and WordPress.
Integrating Bullhorn CRM With a Custom Laravel Recruitment Website
Recruitment websites need fast job board filtering and reliable candidate application syncing with Bullhorn CRM. We break down how we handle Bullhorn OAuth token refresh, two-way job syncing, and candidate resume uploads in Laravel.
Offline-First Mobile Apps and PWAs for Field Dispatch and Fleet Operations
Field technicians and delivery drivers work in basements, rural highways, and warehouses where cellular signal drops out. Here is how we engineer offline-first mobile apps and PWAs that store jobs locally and sync cleanly.