I work on a project that sometimes require data change for all customers. Since each customer have it’s own database, we always end up working on a script to run it across the whole client-base. Another common thing during these script development is that you want to run for a specific customer (testing database) first, see the results before you roll it out for every customer. On this article, I’m going to show how I built an abstract command that makes these processes easier. 1- The Abstract Command The abstract command will be the one actually implementing the method. It consists in running a job (synchronously) for a specific or dispatching one job per This allows to check the result of the script immediately during tests while being able to run multiple workers to process every in parallel when it’s ready to roll out. handle tenant tenant. tenant 2- The Concrete Command A concrete command will have to do 2 things: Setup the command signature; Instantiate the Job to be executed; The following snippet is an example of how simple it is to create a new upgrade command. 3- The Abstract Job Just like the upgrade command, every job class will have some pieces of code that I don’t want to duplicate. Let’s extract all of that into an abstract Job. It is the Job’s responsibility to: Make sure a Tenant is provided. Run the migration process inside a database transaction. Define the amount of attempt to only once. If you want to see how I establish the database connection, check out this article: . Multi Tenancy with Laravel 4- The Concrete Job The Concrete Job should extend the abstract (obviously) and implement the method, which should contain the data migration logic. run 5- Wrapping it up To get everything up and running, just make sure to register the on class and run it through artisan. commands App\Console\Kernel.php php artisan upgrade:menu --database=my_test_database Once the script is ready to go live, just run it with the flag and get the workers up. --all php artisan upgrade:menu --allphp artisan queue:work Of course, you can always run multiple to run it in parallel. queue:work