#Laravel

One application, several businesses, and separate sets of keys

Zulu Shack illustration for “One application, several businesses, and separate sets of keys”: separate keys on separate hooks

Reusing an application for several businesses can be a sensible product strategy. Reusing the wrong customer’s records is a rather less appealing interpretation of efficiency.

A multi-tenant Laravel application serves multiple organizations through a shared product while maintaining the intended boundaries between them.3 The organizations may share application code and some infrastructure, but each needs appropriate access to its own information and settings.

That is a design responsibility across the whole system. Adding a company identifier to the main table is a start, not a complete tenancy model.

Decide how much should really be shared

For a business considering a reusable platform, the first decision is how much should actually be shared.

One option is to run separate installations from a common maintained codebase. Another is a shared application with separate databases. A further option places tenant records in shared tables with consistent tenant scoping.

Each arrangement has operational tradeoffs. Separate installations can simplify some isolation decisions while increasing deployment and maintenance work. Shared infrastructure can centralize product updates while making the correctness of tenant boundaries especially important.

How it worksTradeoff
Separate installationsEach business runs its own copy of a common maintained codebaseSimplifies some isolation decisions, but adds deployment and maintenance work
Shared application, separate databasesOne application, with each tenant’s data in its own databaseProduct updates stay central; tenant boundaries must be resolved correctly
Shared tablesTenant records sit in shared tables with consistent tenant scopingCentralized updates; the correctness of every tenant boundary matters most
Three ways to serve several businesses from one product

A series of independently modified copies creates another problem: the copies can drift into separate products. A reusable platform benefits from deliberate configuration and extension points, with a clear policy for customer-specific changes.

This is the kind of problem our custom development team enjoys.

Follow the tenant beyond the browser request

The application needs a reliable way to identify the organization for each action, then check the user’s authority within it. A tenant identifier supplied by the browser is information to validate, not permission in itself.

A useful review follows that context through:

  • Record queries, exports and search results.
  • Files, generated documents and download links.
  • Cache entries and other shared application state.
  • Queued jobs, scheduled work and notifications.
  • Administrative actions and support access.

Consider a hypothetical application serving two independent event organizers. Both can have an event numbered 42 in their own context. A background export needs to know which organizer’s event it is processing.

That context must survive dispatch and retry. If the organization can no longer be resolved, the job should fail into an understandable state rather than proceed under whichever context happens to be available.

Spatie’s Laravel multitenancy tooling includes tenant-aware queue support, illustrating that this concern extends beyond page routing.4 Its configuration still needs to match the application’s intended behavior.

Cache and file naming need similar care. A key called “current-events” can be perfectly clear within one organization and ambiguous in a shared service. Include the relevant scope where data belongs to a tenant, and treat genuinely shared information deliberately.

Permissions remain a separate layer. Two staff members in the same tenant may have different responsibilities. Cross-tenant support access should also be controlled and recorded rather than quietly bypassing every boundary for convenience.

Diagram: in a multi-tenant application every action identifies its organization and checks the user’s permissions, and that tenant context has to reach record queries and search, files and download links, cache keys, queued jobs and notifications, and administrative and support access.
A company ID on the main table is a start. The tenant has to follow the work everywhere.

Test the walls before a second business moves in

Before offering the product to another business, test the isolation directly. Use accounts from different tenants, attempt access through known identifiers and exercise background processing. Check denied requests as well as successful ones.

This is architecture for a proposed reusable application, not a claim that a multi-tenant poker service has already launched.

I would choose the deployment and data model around the expected customers, support capacity and required isolation. Sharing code can be valuable even when separate deployments are the better fit.

The useful result is a product that can grow without making its customers accidental housemates. Common infrastructure is fine. Everyone should still have the right keys.

Turn reading into results

Like what you’re reading? Let’s put it to work on your brand.