Skip to content

Basic Usage

Tasks are configured with the app/Config/Tasks.php config file, inside the init() method. Let's start with a simple example:

<?php

namespace Config;

use CodeIgniter\Tasks\Config\Tasks as BaseTasks;
use CodeIgniter\Tasks\Scheduler;

class Tasks extends BaseTasks
{
    /**
     * Register any tasks within this method for the application.
     *
     * @param Scheduler $schedule
     */
    public function init(Scheduler $schedule)
    {
        $schedule->call(function() {
            DemoContent::refresh();
        })->mondays();
    }
}

In this example, we use a closure to refresh demo content at 12:00 am every Monday morning. Closures are a simple way to handle quick functions like this. You can also execute server commands, execute custom CLI commands you have written, call a URL, or even fire off an Event of your choosing. Details are covered below.

Scheduling

This is how we can schedule our tasks. We have many options.

Scheduling CLI Commands

If you have written your own CLI Commands, you can schedule them to run using the command() method.

$schedule->command('demo:refresh --all');

The only argument is a string that calls the command, complete with an options or arguments.

Scheduling Shell Commands

You can call out to the server and execute a command using the shell() method.

$schedule->shell('cp foo bar')->daily()->at('11:00 pm');

Simply provide the command to call and any arguments, and it will be executed using PHP's exec() method.

Note

Many shared servers turn off exec access for security reasons. If you will be running on a shared server, double-check you can use the exec command before using this feature.

Scheduling Events

If you want to trigger an Event you can use the event() method to do that for you, passing in the name of the event to trigger.

$schedule->event('Foo')->hourly();

Scheduling URL Calls

If you need to ping a URL on a regular basis, you can use the url() method to perform a simple GET request using cURL to the URL you pass in. If you need more dynamism than can be provided in a simple URL string, you can use a closure or command instead.

$schedule->url('https://my-status-cloud.com?site=foo.com')->everyFiveMinutes();

Scheduling Queue Jobs

If you want to schedule a Queue Job, you can use the queue() method and specify the queue name, job name and data your job needs:

$schedule->queue('queue-name', 'jobName', ['data' => 'array'])->hourly();

Note

To learn more about queues, you can visit the Queue package.

The singleInstance() option, described in the next section, works a bit differently than with other scheduling methods. Since queue jobs are added quickly and processed later in the background, the lock is applied as soon as the job is queued - not when it actually runs.

$schedule->queue('queue-name', 'jobName', ['data' => 'array'])
    ->hourly()
    ->singleInstance();

This means:

  • The lock is created immediately when the job is queued.
  • The lock is released only after the job is processed (whether it succeeds or fails).

We can optionally pass a TTL to singleInstance() to limit how long the job lock should last:

$schedule->queue('queue-name', 'jobName', ['data' => 'array'])
    ->hourly()
    ->singleInstance(30 * MINUTE);

How it works:

  • The lock is set immediately when the job is queued.
  • The job must start processing before the TTL expires (in this case, within 30 minutes).
  • Once the job starts, the lock is renewed for the same TTL.
  • So, effectively, you have 30 minutes to start, and another 30 minutes to complete the job.

Single Instance Tasks

Some tasks can run longer than their scheduled interval. To prevent multiple instances of the same task running simultaneously, you can use the singleInstance() method:

$schedule->command('demo:heavy-task')->everyMinute()->singleInstance();

With this setup, even if the task takes more than one minute to complete, a new instance won't start until the running one finishes.

Setting Lock Duration

By default, the lock will remain active until the task completes execution. However, you can specify a maximum lock duration by passing a TTL (time-to-live) value in seconds to the singleInstance() method:

// Lock for a maximum of 30 minutes (1800 seconds)
$schedule->command('demo:heavy-task')
    ->everyFifteenMinutes()
    ->singleInstance(30 * MINUTE);

This is useful in preventing "stuck" locks. If a task crashes unexpectedly, the lock might remain indefinitely. Setting a TTL ensures the lock eventually expires.

If a task completes before the TTL expires, the lock is released immediately. The TTL only represents the maximum duration the lock can exist.

Frequency Options

There are a number of ways available to specify how often the task is called.

Method Description
->cron('* * * * *') Run on a custom cron schedule.
->daily('4:00 am') Runs daily at 12:00am, unless a time string is passed in.
->hourly() / ->hourly(15) Runs at the top of every hour or at specified minute.
->everyHour(3, 15) Runs every 3 hours at XX:15.
->betweenHours(6,12) Runs between hours 6 and 12.
->hours([0,10,16]) Runs at hours 0, 10 and 16.
->everyMinute(20) Runs every 20 minutes.
->betweenMinutes(0,30) Runs between minutes 0 and 30.
->minutes([0,20,40]) Runs at specific minutes 0,20 and 40.
->everyFiveMinutes() Runs every 5 minutes (12:00, 12:05, 12:10, etc)
->everyFifteenMinutes() Runs every 15 minutes (12:00, 12:15, etc)
->everyThirtyMinutes() Runs every 30 minutes (12:00, 12:30, etc)
->days([0,3]) Runs only on Sunday and Wednesday ( 0 is Sunday , 6 is Saturday )
->sundays('3:15am') Runs every Sunday at midnight, unless time passed in.
->mondays('3:15am') Runs every Monday at midnight, unless time passed in.
->tuesdays('3:15am') Runs every Tuesday at midnight, unless time passed in.
->wednesdays('3:15am') Runs every Wednesday at midnight, unless time passed in.
->thursdays('3:15am') Runs every Thursday at midnight, unless time passed in.
->fridays('3:15am') Runs every Friday at midnight, unless time passed in.
->saturdays('3:15am') Runs every Saturday at midnight, unless time passed in.
->monthly('12:21pm') Runs the first day of every month at 12:00am unless time passed in.
->daysOfMonth([1,15]) Runs only on days 1 and 15.
->everyMonth(4) Runs every 4 months.
->betweenMonths(4,7) Runs between months 4 and 7.
->months([1,7]) Runs only on January and July.
->quarterly('5:00am') Runs the first day of each quarter (Jan 1, Apr 1, July 1, Oct 1)
->yearly('12:34am') Runs the first day of the year.
->weekdays('1:23pm') Runs M-F at 12:00 am unless time passed in.
->weekends('2:34am') Runs Saturday and Sunday at 12:00 am unless time passed in.
->environments('local', 'prod') Restricts the task to run only in the specified environments.
->singleInstance() / ->singleInstance(HOUR) Prevents concurrent executions of the same task.

These methods can be combined to create even more nuanced timings:

$schedule->command('foo')
    ->weekdays()
    ->hourly()
    ->environments('development');

This would run the task at the top of every hour, Monday - Friday, but only in development environments.

Naming Tasks

You can name tasks so they can be easily referenced later, such as through the CLI with the named() method:

$schedule->command('foo')->nightly()->named('foo-task');