Laravel FIFO queue with Redis

Build a simple FIFO (First In, First Out) queue in Laravel with Redis.

Created on July 2021

Laravel FIFO queue with Redis

Recently I had the need to create a FIFO (First In, First Out) queue in Laravel to run specific actions inside a long-running worker from outside the worker itself. I had two possibilities:

  1. Database, creating a table, but I had also to create a Model, Service, Repository and many other things;
  2. Redis, already installed.

Of course I went with Redis, taking advantage of two main commands: RPUSH and LPOP.

Theory

The first one, RPUSH, will append an item to a given list (and create if it does not exist) and will be responsible for pushing new items to the list; LPOP, instead, will pop out the first item in the list, deleting it from our "queue". A quick visual explanation:

FIFO Queue

Code

Thanks to Laravel Redis facade we can use the Redis commands as static methods and, because LPOP will return false if the list is empty, we can easily loop until there are no more items to process:

<?php

use Illuminate\Support\Facades\Redis;

// Define our queue name
$queueName = 'fifo';

// Put some items in our queue
// You can run this code outside your long-running worker
Redis::rpush($queueName, 'item1');
Redis::rpush($queueName, 'item2');


// ---------------------- somewhere else ----------------------

// Process until there are no more elements
// Note that will close when the queue is empty
while ($item = Redis::lpop($queueName)) {
	echo 'Found: ' . $item . PHP_EOL;
}

// Output:
// "Found: item1"
// "Found: item2"

If you want to run it in a long-running worker, you'll need to slightly change the while loop into something like this (or use a library like the great ReactPHP) in order to not stop the script even if the queue is empty:

<?php

use Illuminate\Support\Facades\Redis;

// Define our queue name
$queueName = 'fifo';

// Process until there are no more elements
while (true) {
	if ($item = Redis::lpop($queueName)) {
		echo 'Found: ' . $item . PHP_EOL;
	}
}

// Output:
// "Found: item1"
// "Found: item2"

Next

Time travel after each Laravel Factory

Previous

Resovable trait for Laravel container