Yii2 Background Jobs & Queue System

Handling long-running tasks synchronously in Yii2 can slow down your application. Yii2 Queue allows you to process tasks in the background, improving performance and user experience.


Why Use Yii2 Queue?

  • Asynchronous Processing – Avoid blocking user requests.
  • Scalability – Handle large volumes of tasks.
  • Retry Mechanism – Automatically retry failed jobs.
  • Supports Multiple Drivers – Works with MySQL, Redis, RabbitMQ, Beanstalk, etc.

Installing Yii2 Queue

Yii2 provides an official yii2-queue extension. Install it using Composer:

composer require yiisoft/yii2-queue

Configuring Queue in Yii2

Yii2 Queue supports multiple backends. Here’s how to set up a MySQL queue (you can replace it with Redis, RabbitMQ, etc.).

1. Database (MySQL) Configuration

Edit your Yii2 configuration file (config/console.php for Basic Template or console/config/main.php for Advanced Template):

'components' => [
    'queue' => [
        'class' => \yii\queue\db\Queue::class,
        'db' => 'db', // Database connection component
        'tableName' => '{{%queue}}', // Table storing the queue
        'channel' => 'default', // Queue channel
        'mutex' => \yii\mutex\MysqlMutex::class, // Avoid race conditions
    ],
],

Run migrations to create the queue table:

php yii queue/db/init
php yii migrate

2. Creating a Queue Job

Create a job class inside console/jobs/SendEmailJob.php:

namespace console\jobs;
use yii\base\BaseObject;
use yii\queue\JobInterface;
class SendEmailJob extends BaseObject implements JobInterface
{
    public $email;
    
    public function execute($queue)
    {
        \Yii::$app->mailer->compose()
            ->setTo($this->email)
            ->setFrom('admin@example.com')
            ->setSubject('Welcome Email')
            ->setTextBody('Thank you for signing up!')
            ->send();
        
        echo "Email sent to {$this->email}\n";
    }
}

3. Pushing a Job to the Queue

Add a job in your controller or service:

Yii::$app->queue->push(new \console\jobs\SendEmailJob([
    'email' => 'user@example.com'
]));

This does not execute the job immediately. It stores it in the queue to be processed later.


Running the Queue

There are two ways to run queue workers:

1. Running the Queue via Cron Job

You can set up a cron job to process the queue every minute by adding this command to crontab:

* * * * * php /path-to-your-project/yii queue/run --verbose=1

This approach works well for low to medium traffic applications.


2. Running the Queue as a Daemon (Supervisor)

For high-volume queues, it's better to run the worker as a long-running process instead of running it every minute via cron. This can be achieved using Supervisor.

Why Use Supervisor Instead of Cron?
  • Faster Execution – Jobs are processed immediately, rather than waiting for the next cron run.
  • Continuous Running – Unlike cron, Supervisor keeps listening for new jobs without restarting every minute.
  • Prevents Overlapping – If a cron job runs every minute and a job takes longer, multiple cron jobs may run simultaneously, causing conflicts.
  • Automatic Restart – If the queue crashes, Supervisor automatically restarts it.
Installing and Configuring Supervisor

1. Install Supervisor:

sudo apt install supervisor

2. Create a new Supervisor config file:

sudo nano /etc/supervisor/conf.d/yii2-queue.conf

3. Add the following configuration:

[program:yii2-queue]
command=php /path-to-your-project/yii queue/listen
autostart=true
autorestart=true
stderr_logfile=/var/log/yii2-queue.err.log
stdout_logfile=/var/log/yii2-queue.out.log

4. Reload Supervisor:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start yii2-queue

Now, the queue runs in the background without manual intervention!


Choosing Between Cron and Supervisor

FeatureCron JobSupervisor
Job Execution SpeedRuns jobs every minuteJobs run instantly
PerformanceCan be slow for high-traffic appsBest for high-volume processing
ReliabilityMay cause overlapping jobsAutomatically restarts on failures
Best ForLow to medium trafficHigh-performance applications

 Conclusion:

  • If your app has low to medium traffic, cron jobs are fine.
  • If you need real-time processing and high reliability, use Supervisor.

Handling Failed Jobs

If a job fails, Yii2 can retry it automatically:

Yii::$app->queue->push(new SendEmailJob([
    'email' => 'user@example.com'
]), 5); // Retry 5 times before failing permanently

View failed jobs:

php yii queue/info

Manually retry failed jobs:

php yii queue/retry 10  // Retry job with ID 10

Best Practices for Yii2 Queues

  • Use Supervisor for long-running jobs.
  • Retry failed jobs using Yii2 Queue retry mechanism.
  • Use Redis/RabbitMQ for high-performance queuing.
  • Avoid queueing large payloads (store large data in DB and pass only IDs).
  • Log queue failures for debugging.

Conclusion

Yii2 Queue makes background processing simple. Whether sending emails, processing payments, or running heavy computations, you can improve performance and scalability with background jobs.