Queues for Laravel 5.1

I wrote a post about using’s Push Queues with Laravel 4.2, and of course it became obsolete a couple weeks after upgrading to Laravel 5.1.

Since were the only ones to be using “Push” queues, it added complexity to the other queue types, and the Laravel gods decided to give it the ax.

A “Push” queue was essentially a queue job, that would then get a ping back from to a queue worker that would handle the queued job. Laravel would accept the ping from, and handled accordingly with the Queue::marshal() command (deprecated in Laravel 5.1)

So here is how we re-setup Queues in Laravel 5.1.

Sign up for a free account #

Create a new Queue #

Click on the credentials icon. This will show you your Project ID and Token.

Screen Shot 2015-08-05 at 1.19.26 PM.png

Create a new Queue #

Within your account, create a new Queue.


Select “pull” as the Queue Type.


Update Laravel’s queue driver to use iron #

Add your credentials in the /config/queue.php file.

'iron' => array(
    'driver'  => 'iron',
    'host'    => '',
    'token'   => 'xxx',
    'project' => 'xxx',
    'queue'   => 'Your Queue Name',
    'encrypt' => true,

Set the Queue Driver to Iron in the .env file:


For the local .env file, I kept to sync to make testing easier:


Install dependency through composer #

I was still getting an 'IronMQ' not found error when trying to using version 3 of iron_mq.

Screen Shot 2015-11-17 at 10.13.02 AM.png

This time the solution was to use v2, by adding "iron-io/iron_mq": "2.*" into the /composer.json file.

Then, through the command line, in your laravel project’s root, run composer update to pull that in.

Push a Queue #

Let’s push a new task onto the queue. For us, we are going to be creating a task to export out the results. So in our app, when a visitor requests to export the results, we will add the following into our “export” controller.

$data = ['user_id' => $user_id =>, 'file' => $file];
$this->dispatch(new Export($data));

This will dispatch a new job named “Export,” and send with it the required data (in our case, the user_id and file name), to Iron.

Create Job Class #

Next we’ll create a Job Class to do the work of exporting the results. We can do that through artisan:

php artisan make:job Export --queued

This command will generate a new class in the app/Jobs directory, which I modified slightly to look like this.


namespace App\Jobs;

use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Mail;

class ExportContacts extends Job implements SelfHandling, ShouldQueue
    use InteractsWithQueue, SerializesModels;

    protected $data;

     * Create a new job instance.
     * @return void
    public function __construct($data)
        $this->data = $data;

     * Execute the job.
     * @return void
    public function handle()
        //a bunch of code to export out the results & notify user when it's completed

Test Queue #

Before moving any farther, let’s check to make sure everything is working as expected. Working in your local env, let’s add something to the queue. In our case, we will trigger the export. Then, from the project’s root, run php artisan queue:work iron. This command will do nothing if the queue is empty, but if there’s an item on the queue it will fetch the item and attempt to execute it. In our case, we should see that the export get’s successfully processed.

With the queue working as expected locally, we can now sync this up with

Setting up Queue Listener with Supervisor #

Unlike the “push” queues, will hold all of the queued jobs until our app requests them to be processed. It’s the Listener’s job to run new jobs as they are pushed onto the queue.

Supervisor is a process monitor for the Linux operating system, and will automatically restart your queue:listen or queue:work commands if they fail. To install Supervisor on Ubuntu, we use the following command:

sudo apt-get install supervisor

After it is installed you need to configure it. At first you need to create configuration file

vi /etc/supervisor/conf.d/worker.conf

And add the following to the new worker.conf file.

command=php /PATH/TO/artisan queue:work iron --sleep=3 --tries=3 --daemon
You should replace /PATH/TO/PROJECT/ROOT

You should replace YOUR-USER with your ssh user (i.e. root)

With the configuration file created, update the Supervisor configuration and start the processes using the following commands:

 sudo supervisorctl reread
 sudo supervisorctl update
 sudo supervisorctl start worker:*

Handling Failed Jobs #

I’ve found that debugging the jobs can be a bit of a pain in the ass. Things that work locally, sometimes fail when integrated with Iron. This could happen for a number of reasons, but I’ve found it to be helpful to receive an email when a failed event happens. You can do this through the AppServiceProvider.php file, within the boot function.

public function boot()
    \Queue::failing(function ($connection, $job, $data) {
        $info['data'] = $data;
        \Mail::send('', $info, function($message) {
            $message->to('')->subject('Job failed');

And you can trigger the failed job within Job itself, by throwing an exception:

 throw new \Exception('Job Failed');

What I haven’t figured out yet it how to pass the Exception message to the email notification. Hope to get that worked out soon as it would be very helpful with debugging.

Important note #

Since daemon queue workers are long-lived processes, they will not pick up changes in your code without being restarted. So, the simplest way to deploy an application using daemon queue workers is to restart the workers during your deployment script. You may gracefully restart all of the workers by including the following command in your deployment script:

 php artisan queue:restart

This command will gracefully instruct all queue workers to restart after they finish processing their current job so that no existing jobs are lost.


Now read this

Tag the Most Engaging Contacts in Highrise

I’ve been using Highrise as my CRM for the last several years. I have it deeply integrated (via their API) with Purlem to track Purlem’s users, their subscription status, and to set alerts for on-boarding. I’m also been forwarding all... Continue →