Skip to content

Migrations

When using multi-database tenancy, migrations for tenant databases are located in database/migrations/tenant. Central (“regular”) migrations are in database/migrations as usual. (See the Getting started page for a visual example.)

To execute tenant migrations, you can use the php artisan tenants:migrate command.

This command supports most of the same options as the regular migrate command, as well as the --tenants option which may be used to provide the tenant keys of the tenants you wish to migrate.

To rollback tenant migrations, with the same usage as the regular rollback command, you can use the php artisan tenants:rollback command.

Again, most regular options as well as --tenants may be passed.

For an equivalent for migrate:fresh, you can use the php artisan tenants:migrate-fresh command.

Notably, unlike the two commands mentioned above, this command does not extend an existing Laravel command, instead it reimplements the logic manually so make sure to check out --help for a list of options that may be passed.

You can use the tenancy.database.drop_tenant_databases_on_migrate_fresh config to override the central migrate:fresh command such that it deletes tenants one by one — making sure to delete their databases — rather than just deleting the records. You can find more information on the Database managers page of our documentation, simply search for drop_tenant_databases_on_migrate_fresh to get to the relevant paragraph.

You can use php artisan tenants:seed to run the tenant seeders. This command extends the base Seed command, so again you can use most of the regular options as well as --tenants.

You can squash tenant migrations using the php artisan tenants:dump command:

Terminal window
$ php artisan tenants:dump
What tenant do you want to dump the schema for?:
> 7c27cc0f-8ed6-4d2e-ac86-2ae9ac36acf5
INFO Database schema dumped successfully.

This produces a database/schema/tenant-schema.dump file, which is by default passed to the tenants:migrate command as --schema-path. In other words, the tenants:migrate command looks for this file out of the box, with no extra configuration needed on your end.

config/tenancy.php
/**
* Parameters used by the tenants:migrate command.
*/
'migration_parameters' => [
'--force' => true, // This needs to be true to run migrations in production.
'--path' => [database_path('migrations/tenant')],
'--schema-path' => database_path('schema/tenant-schema.dump'),
'--realpath' => true,
],

You can also use the --prune argument to delete all of your tenant migrations, while keeping your central migrations untouched. Keep in mind that you should only use this if all of your tenants are fully migrated:

Terminal window
$ php artisan tenants:dump --tenant=7c27cc0f-8ed6-4d2e-ac86-2ae9ac36acf5 --prune
INFO Database schema dumped successfully.
INFO Tenant migrations pruned.

Most of these commands that operate on multiple commands support parallel execution. To confirm if an individual command supports that, use --help to see if the --processes option exists.

You can use parallel execution like this:

  • php artisan tenants:migrate -p 8 — Run tenants:migrate with 8 processes. It will split up the tenant list into 8 chunks and spawn 8 worker processes that independently operate on each chunk.
  • php artisan tenants:migrate -p — Run tenants:migrate with as many processes as you have logical cores. The package attempts to get this information from the operating system. This should work on most operating systems. Note that the number of processes here is capped to 24, in case the core count detection goes wrong, to prevent spawning too many processes.
  • php artisan tenants:migrate -P — Same as -p except without the 24 process limit. Can be used with core count autodetect (-P) or a specific process count (-P 32).

The ideal number of processes depends on whether your database server is on the same machine as the machine running this command, the number of logical and perhaps physical cores of each involved machine, and the complexity of your migrations. To get the “best number”, you should set up a staging environment with data and migrations matching your production environment and run actual benchmarks if the execution time of migrations is a big issue for you.

In most cases, using a value that matches the logical core count of the server running the command, or the physical core count of the machine hosting the database, is likely to be optimal.