Skip to content

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:

php artisan tinker
> $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.

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.

config/tenancy.php
/**
* 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.

config/tenancy.php
'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_CONNECTION tells Laravel what the default connection is
  • Tenancy uses DB_CONNECTION as the central connection
  • the central connection is then used as the default template connection
  • tenant connections are based on the template connection, merged with any tenant-specific tenancy_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.

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).

  1. This behavior can be customized using the tenancy.database.prefix and tenancy.database.suffix configuration keys.