Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ibarral's avatar

Multi-tenancy with database-per-tenant: how to handle lot of migrations efficiently

Hello,

We have a multi-tenancy with database-per-tenant Laravel app with lot databases and we are facing a problem: if a migration take 5 seconds to execute in one database, and we have 1.000 databases, it will take more than 83 minutes to run all migrations (and we need to put the app in maintenance mode for 83 minutes).

So, what’s the best way to minimize the time to run all the migrations?

I found this post that use Queues and Jobs to process the migrations in parallel:

https://medium.com/hackernoon/abstract-upgrade-command-for-multi-tenant-71089b9a838f

So, if we use 10 workers to run the migrations, it will take 8,3 minutes to run all the migrations.

This approach is ok? Or it can take MySQL service down if we run multiple migrations in parallel?

Thanks,

0 likes
18 replies
iftekhs's avatar

What do you mean by 1000 databases? Is your 1 app connected to 1000 databases?

ibarral's avatar

We have a multi-tenancy with database-per-tenant, so every Tenant has is own database. If we have 1.000 Tenants, we will have 1.000 databases (one per tenant) ;)

1 like
sr57's avatar

@ibarral

This approach is ok but the success will depend of your bottleneck, if disk io, network bandwith, ... running workers in // will not change the result.

Should be better to have a common db?

1 like
ibarral's avatar

@sr57 is not an option to have one common DB, we need to stick to database-per-tenant approach.

Thank you very much for your feedback!

rodrigo.pedra's avatar

A couple of questions:

  • Do you already have 1000 tenants, or are you planning ahead to prepare for it?
  • How are you currently routing the tenants? Subdomain, custom domain for each tenant, subfolder?
  • In case of custom domain, do you use a reverse proxy of any sorts?
  • Do you have a central storage that store minimal data for all tenants? For example, spatie/laravel-multitenancy package requires a landlord database to hold meta-data about each tenant.
ibarral's avatar

@rodrigo.pedra hello Rodrigo. Thank you for your help!

Here are the answer for your questions:

** Do you already have 1000 tenants, or are you planning ahead to prepare for it? **

Yes, we have almost 1.000 tenants right now.

** How are you currently routing the tenants? Subdomain, custom domain for each tenant, subfolder? **

We are routing with subdomain.

** Do you have a central storage that store minimal data for all tenants? For example, spatie/laravel-multitenancy package requires a landlord database to hold meta-data about each tenant.**

Yes, we have a "landlord" database, but it's a custom made implementation (not using spatie/laravel-multitenancy package).

rodrigo.pedra's avatar
Level 56

@ibarral

If you can afford any downtime I would experiment with the parallel solution.

If you prefer to try a near zero-downtime solution, follow along.

As you are routing with subdomain you could install a reverse or an application proxy, such as Traefik, that routes traffic to a different server depending of the subdomain.

  • Then you deploy the new code version to a second application server.
  • Traefik, or even nginx as a reverse proxy, can make the routing decision based on reading from a storage. I guess nginx can't query MySQL or any DBMS directly, but you could update a .conf file while your migration progresses.
  • In your tenant table, on your landlord DB, you add a column that holds the version.
  • The reverse/application proxy would redirect traffic for each subdomain based on the version on this storage. Current version to current application server, new version to newer application server.
  • While migrating a single tenant you could issue a 503 response for that specific subdomain requests. This would be the "near" zero-downtime, as you said the migrations runs for about 5 seconds for each tenant.
  • When finishing migrating a tenant you change the version in its landlord record, the proxy will start using the new server for this tenant.

For the 503 reponse while migrating, you could play with how Laravel handles the php artisan down command and customize it to allow traffic matching certain subdomains while responding with a 503 to subdomains being migrated. Current implementation adds a script to the public folder, so you could tweak this generated script.

For tracking when each migration starts or ends, you can listen for the Migration events. Check this docs page for reference: https://laravel.com/docs/9.x/migrations#events

Disclaimers:

  • While I worked on doing something similar on the past, it was a Symfony project, not a Laravel one, and some years ago.
  • So I am writing from memory this outline, but it is just an outline, if you need implementation details I probably won't remember them all.
  • By then we used Traefik to handle dynamic traffic routing between servers. I guess nowadays there might be other solutions than Traefik or using nginx directly.
  • We also used this approach to every new version deployment, you can search for blue/green deployment strategy for more info.

Postscript:

  • My question about if you already had 1,000 tenants or were planning ahead, was precisely to advise against premature optimization.
  • And also to advise you to hire an expert consultant to help you out with this in case you already had 1,000 tenants.
  • With close to 1,000 tenants I assume you (as a company) already have enough revenue to afford hiring one.
  • I am not offering any services, nor I am an expert on infra-structure. Although in the project I mentioned, I participated actively in implementing the solution, we had an infra-structure expert advising us at the time.
  • This is the kind of the problem I usually referred as "a good problem to have" when I used to give classes, as this means you (as a company) seems to be succeeding. Congratulations!

Hope I could make it clear, English is not my native language. Good luck =)

1 like
ibarral's avatar

@rodrigo.pedra thanks a lot for all your time and explanations Rodrigo! we will evaluate your recommendation to improve our app for zero-downtime on this kind of scenarios.

Thank you very much!!!

1 like
carlosmora's avatar

@ibarral is it possible to put maintenance mode on a per tenant basis? It may require to split the update in 2: the migration and new-features. (in case migration is compatible with previos schema status)

ibarral's avatar

@carlosmora we could do that, but the code is the same for all tenants, and some changes will broke the app until the migrations are complete :(

martinbean's avatar

@ibarral I don’t really know what you’re expecting, here? If you deliberately pick an architecture where hardware grows with the number of customers you have then yes, your maintenance burden is also going to grow with it.

1 like
jlrdw's avatar

Normally multi-tenant is the same database.

1 like
ibarral's avatar

@martinbean @jlrdw I know this architecture has some pros and cons... and one of the cons is that migrations are more difficult to handle.

Thanks anyway for your opinion! ;)

ShadyarBzharOthman's avatar

Hello, Sorry for this question but I have an application with multi-tenancy database-per-tenant and now I want to host it...

What's the best place to host the website that support multi-tenancy?

Please or to participate in this conversation.