Customizing databases
You can customize most parts of the tenant connection by setting tenancy_db_* keys on a tenant. For instance:
Tenant::create(['tenancy_db_name' => 'foo']);will create a database called foo, and every time this tenant is used, that database will be what the tenant connection
connects to.
If you do not specify a database name, it is by default1 created by combining tenant + $tenant->id:
> $tenant = App\Models\Tenant::create();= App\Models\Tenant {#5941 data: null, id: "b37609c7-035c-4a68-aff5-ac60ff334699", updated_at: "2025-09-26 12:29:39", created_at: "2025-09-26 12:29:39", tenancy_db_name: "tenantb37609c7-035c-4a68-aff5-ac60ff334699", }You can set tenancy_db_* attributes for most keys used in database connection configuration. Notably,
tenancy_db_name is an exception since it ultimately sets the database key. Some keys may also be ignored
or are better suited for template connections than direct attributes on individual tenants — as explained below.
Template connection
Section titled “Template connection”Besides values you specify directly on the tenant — on a tenant-by-tenant basis — you can also make tenant connections
use some common config. An example use case would be to place all tenant databases on a different server than your primary
central database.
To achieve this, take a look at the “template connection” config.
/** * Connection used as a "template" for the dynamically created tenant database connection. * Note: don't name your template connection tenant. That name is reserved by package. */'template_tenant_connection' => null,If you create a separate connection in config/database.php (connections section), say tenant_template, you’d set the
host for the tenant connections there, then just change this template_tenant_connection to tenant_template.
Then, all tenant connections created for your tenants will be using this host (unless the tenant overrides the default
set in the template connection).
By default, the template connection is null, which means that the central connection is used as the template. And what’s
the central connection by default? It’s your DB_CONNECTION.
'central_connection' => env('DB_CONNECTION', 'central'),This may be slightly confusing at first, but ultimately it just means that, in the absence of any customizations:
- your
DB_CONNECTIONtells Laravel what the default connection is - Tenancy uses
DB_CONNECTIONas the central connection - the central connection is then used as the default template connection
tenantconnections are based on the template connection, merged with any tenant-specifictenancy_db_*attributes
Which is how the package creates tenant databases on the same DB host as your central database — if you don’t tell the package to use anything else, it will use the defaults outlined above.
To customize the template connection, you don’t actually need a named connection in config/database.php. You can directly
set template_tenant_connection to an array with your customizations.
The template connection is never created as a standalone connection, it’s only used to provide the connection definition foundation
for the tenant connection. It’s then merged with the tenant’s specific tenancy_db_* attributes (such as tenancy_db_name) to create
the tenant connection.
You can also use different (named) template connections on specific tenants. To do that, simply set tenancy_db_connection.
Host connection
Section titled “Host connection”The template connection is used as the foundation for the tenant connection when connecting to an existing tenant.
However, when creating a tenant, we need to create a special connection: the host connection.
The host connection is used to connect to the database server that will host the tenant’s database.
Since the tenant’s database may be on a different server than the default/central connection, and the tenant’s database does not exist yet, we need a database to connect to on the remote server — so that we can establish a connection in the first place — and then we create the tenant’s database on that connection.
The template connection is also used as the foundation for the host connection. Therefore, when establishing the host connection, server details will be taken from the template connection. And as mentioned above, we need some database to connection to, so that database name will be taken from the template connection, which by default is just the central database.
All that is to say: if you create a tenant on a different database server than your central database, e.g. using
Tenant::create(['tenancy_db_host' => 'eu.database_servers.acme.com']), Tenancy will by default use your central
database name and credentials to connect to that server.
You can deal with this in two main ways:
- You could simply create the central database there (and keep it empty), with the same credentials as on your main server.
- Or, as a better solution, you can just create separate template connections (which all define the right database names and credentials for the “dummy” databases that we initially connect to) as explained above.
We may provide some special tenancy_db_* keys to improve the ergonomics of this in the future. But for now, it’s
recommended to simply have pre-defined named connections that you can use as template connections.
The main takeaway from this section is that the database creation/deletion step (anything database
managers do) runs on a separate connection, which is mainly based on the template connection. It’s also based on some
tenancy_db_* keys but trying to affect the host connection that way can be fragile, as many of those keys are ignored in this
step (for details see the DatabaseConfig class in the package source code).
Footnotes
Section titled “Footnotes”-
This behavior can be customized using the
tenancy.database.prefixandtenancy.database.suffixconfiguration keys. ↩