TYPO3 Scheduler

Extension key

scheduler

Package name

typo3/cms-scheduler

Version

13.4

Language

en

Author

TYPO3 contributors

License

This document is published under the Open Content License.

Rendered

Tue, 08 Jul 2025 09:29:20 +0000


The Scheduler supports one-time or periodic execution of tasks that can be delivered by any extension.


Table of Contents:

Introduction

What does it do?

The Scheduler is designed to be the central place to manage all kind of tasks that need to be executed on a regular basis, without needing someone to actually press a button.

Screenshots

This is a view of the BE module's main screen, where you can see all tasks that are currently registered with the Scheduler.

Scheduler main screen

Main screen of the Scheduler BE module

Credits

The Scheduler derives from extension Gabriel, originally developed by Christian Jul Jensen and further developed by Markus Friedrich.

Overview of the system extension EXT:scheduler

Why a scheduling tool?

When running and maintaining a complex system like TYPO3, there are a number of tasks that need to be automated or executed in the small hours, when no one is around to press the button. Indeed quite a few extensions come with some command-line scripts meant to be run regularly using cron jobs. When each of these scripts need their separate entry in the server's crontab, maintenance complexity increases, as well as the cost of migration. Furthermore there's no simple way to keep an overview of and manage these tasks inside TYPO3.

The Scheduler aims to address this issue.

Tasks management

Scripts can be developed as Scheduler tasks by extending a base class provided by the Scheduler. They can then be registered with the Scheduler. At that point it becomes possible to set up a schedule for them by using the Scheduler's BE module.

The BE module provides an overview of all scheduled tasks and some indication of their status, e.g. are they currently running or are they late, did something wrong happen during last execution, etc. It is also possible to manually start the execution of tasks from the BE module.

Tasks execution

The Scheduler provides a command-line tool to be run by TYPO3's command-line dispatcher. Only this script needs to be registered in the server's cron tab for all other recurring tasks to be executed. Indeed every time the Scheduler is launched by the cron daemon, it will look for all tasks that are due (or overdue) and execute them.

When a task is executed by the Scheduler it is marked as being executed in the corresponding database record (in the field called "serialized_executions"). When the task has finished running, the execution is removed from the database record. This mechanism makes it possible to know that a given task is currently running and also helps prevent multiple executions. Indeed it may be that a task requires more time to run than the frequency it is set up for. In such a case a new run may be started which is not always desirable. It is possible to deny such parallel (or multiple) executions.

Follow-up

Whenever a task starts or ends a message is written to TYPO'3 system log (viewable in SYSTEM > Log). A message is also written when a parallel execution has been blocked. This makes it possible to follow what happens, since the main purpose of the Scheduler is to run things when nobody is watching.

A task that fails may report on the reasons for failure using exceptions. Such a message will be logged in the Scheduler's database table and will be displayed in the BE module.

There's no default output to the command-line as scheduled tasks are designed to run in the background.

Glossary

A few terms need to be defined more precisely:

Task
This word is used quite generally throughout this document, sometimes to cover different meanings. A task is really a piece of code that does a precise task and can be registered with the Scheduler in order to execute that piece of code at a precise time, recurrently or not.
Task class
this is the type of task. The "IP Anonymization" task is one particular task class. Its function is to anonymize IP addresses to enforce the privacy of the persisted data. The "Optimize MySQL database tables" executes "OPTIMIZE TABLE" statements on the selected database tables.
Registered task
An instance of a task class that has been registered with the Scheduler. A given task class may be registered several times, for example if it needs to be executed with different parameters.

Installation

This extension is part of the TYPO3 Core, but not installed by default.

Installation with Composer

Check whether you are already using the extension with:

composer show | grep scheduler
Copied!

This should either give you no result or something similar to:

typo3/cms-scheduler       v12.4.11
Copied!

If it is not installed yet, use the composer require command to install the extension:

composer require typo3/cms-scheduler
Copied!

The given version depends on the version of the TYPO3 Core you are using.

Classic installation without Composer

In an installation without Composer, the extension is already shipped but might not be activated yet. Activate it as follows:

  1. In the backend, navigate to the Admin Tools > Extensions module.
  2. Click the Activate icon for the Scheduler extension.
Extension manager showing Scheduler extension

Extension manager showing Scheduler extension

Next steps

Once the extension is installed, the following setting is available:

  • Maximum lifetime : it may happen that a task crashes while executing. In this case it will stay in a state marked as "running". That may prevent it from being executed again, if parallel executions are denied (see "Tasks execution" above). The maximum lifetime parameter ensures that old executions are removed after a while. The lifetime is expressed in minutes . The default is 15 minutes.
Extension configuration

Configuring the extension settings

Checking the setup of the scheduler extension

After installing the Scheduler, go to its BE module and call up the "Setup check" screen which runs a couple of basic checks on your installation. It will probably look something like this:

Setup check screen

Checking the setup of the Scheduler

The first message shows a warning that the Scheduler has never run yet or an information about the last run.

The second message should normally be okay. If there's an error instead, it means that permissions to execute TYPO3's command-line dispatcher must be checked (this is not strictly related to the Scheduler).

The third message shows information about the current server time.

Setting up the cron job to run the scheduler tasks

Tasks registered with the Scheduler can be run manually from the backend module. However this is of limited use. To really benefit from the Scheduler, it must be set up on the server to run regularly. The following chapters describe how to set this up on Unix or Unix-like system (including Mac OS X) and on Windows.

Choosing a frequency

Whatever system the Scheduler will run on, the first step is to define the frequency at which it should run. The Scheduler script should set up to run pretty often, but not unnecessarily often either. The frequency should be that of the most often running task or some frequency that fits all tasks.

For example, if you have some tasks running every quarter of an hour and some others running every hour, it is useless to have the Scheduler run every 5 minutes. On the other hand, if you have tasks scheduled to run every 10 minutes and others every 15 minutes, you will want to run the Scheduler every 5 minutes. Indeed, if you run it only at 10-minute intervals, it will run – assuming it is 8 o'clock – at 08:10, 08:20, 08:30, etc. So the tasks that should run at 08:15 will actually run 5 minutes late.

On Unix and Mac OS X

On such systems the Scheduler must be set up as a cron job. There are several ways to achieve this, although the simplest is probably to add it to some user's crontab. Edit that user's crontab using:

crontab -e
Copied!

and add a line like

*/15 * * * * /usr/local/bin/php /home/user/www/vendor/bin/typo3 scheduler:run
Copied!
*/15 * * * * /usr/local/bin/php /home/user/www/typo3/sysext/core/bin/typo3 scheduler:run
Copied!

Save the modified crontab. Obviously, the paths have to be adapted to your system. The above command will call up the Scheduler every 15 minutes.

If you are editing system crontabs (for example /etc/crontab and /etc/cron.d/* ), there will be one additional parameter to enter, i.e. the user with which the job should run. Example:

*/15 * * * * www /usr/local/bin/php /home/user/www/vendor/bin/typo3 scheduler:run
Copied!
*/15 * * * * www /usr/local/bin/php /home/user/www/typo3/sysext/core/bin/typo3 scheduler:run
Copied!

This will run the job as user "www".

If you are not familiar with cron syntax, refer to some Unix administration book or start with the Wikipedia page about it (https://en.wikipedia.org/wiki/Cron).

On Windows

On Windows, cron jobs are called "Scheduled tasks" and run with the schtasks utility. SchTasks.exe performs operations similar to those provided by Scheduled Tasks in the Control Panel. You can use either tool to create, delete, configure, or simply display scheduled tasks.

Assuming you want to run the TYPO3 Scheduler every 15 minutes, use the following command line to create a new task:

schtasks /create /sc minute /mo 15 /tn "T3scheduler" /tr "c:\winstaller\php\php.exe c:\winstaller\htdocs\quickstart\vendor\bin\typo3 scheduler:run"
Copied!
schtasks /create /sc minute /mo 15 /tn "T3scheduler" /tr "c:\winstaller\php\php.exe c:\winstaller\htdocs\quickstart\typo3/sysext/core/bin/typo3 scheduler:run"
Copied!

At task creation you will be prompted to give a password or you can use the /u and /p switches to provide user and password information. Note that the user must be a member of the Administrators group on the computer where the command will run.

The full reference for schtasks is available at: https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/schtasks

The base tasks provided by the TYPO3 Core

The Scheduler comes by default with several tasks:

  • Caching framework garbage collection : some cache backends do not have an automatic garbage collection process. For these it is useful to run this Scheduler task to regularly free some space.
  • Fileadmin garbage collection : empties _recycler_ folders in the fileadmin.
  • Table garbage collection : cleans up old records from any table in the database. See related section below for more information on configuration.

Table garbage collection task

The table garbage collection task can take a more elaborate configuration which is detailed below.

The task can be registered to clean up a particular table, in which case you simply choose the table and the minimum age of the records to delete from the task configuration screen.

Table Garbage Collection task configuration

Configuring the table garbage collection task

It's also possible to clean up all configured table by checking the "Clean all available tables" box. The configuration for the tables to clean up is stored in $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][\TYPO3\CMS\Scheduler\Task\TableGarbageCollectionTask::class]['options']['tables'] . The syntax is the following:

  • option expireField can be used to point to a table field containing an expiry timestamp. This timestamp will then be used to decide whether a record has expired or not. If its timestamp is in the past, the record will be deleted.
  • if a table has no expiry field, one can use a combination of a date field and an expiry period to decide which records should be deleted. The corresponding options are dateField and expirePeriod. The expiry period is expressed in days.

Example

config/system/additional.php | typo3conf/system/additional.php
<?php

use TYPO3\CMS\Scheduler\Task\TableGarbageCollectionTask;

$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][TableGarbageCollectionTask::class]['options']['tables']['tx_realurl_errorlog'] = [
    'dateField' => 'tstamp',
    'expirePeriod' => '180',
];
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['scheduler']['tasks'][TableGarbageCollectionTask::class]['options']['tables']['tx_realurl_uniqalias'] = [
    'expireField' => 'expire',
];
Copied!

The first part of the configuration indicates that records older than 180 days should be removed from table tx_realurl_errorlog , based on the timestamp field called "tstamp". The second part indicates that old records should be removed from table tx_realurl_uniqalias directly based on the field "expire" which contains expiration dates for each record.

Custom tasks

More tasks are provided by system extensions, such as the Extension Manager, which defines one for updating the available extensions list.

The base tasks are also there to serve as examples for task developers (see Scheduler task development).

The "Scheduler" backend module

The setup check screen

This screen has already been mentioned in the Installation chapter. It is mostly useful when setting up the Scheduler, as it indicates whether the CLI script is executable or not. When everything is running fine, it contains mostly one useful piece of information: when the last run took place, when it ended and whether it was started manually (i.e. from the BE module) or automatically (i.e. from the command line).

The information screen

This screen shows a list of all available tasks in the current TYPO3 installation. When the Scheduler has just been installed, this will be limited to the two base tasks provided by the extension. The screen shows the name and description of the task. Clicking on the "Add" icon on the right side of each row will open up the new task registration screen, with the task class already predefined.

Scheduler information screen

List of available tasks in the Scheduler's information screen

The scheduled tasks screen

This is the main screen when administering tasks. At first it will be empty and just offer a link to add a new task. When such registered tasks exists, this screen will show a list with various pieces of information.

Scheduler main screen

Main screen of the Scheduler BE module

Disabled tasks have a gray label sign near the task name. A disabled task is a task that will not be run automatically by the command-line script, but may still be executed from the BE module.

A late task will appear with an orange label sign near the task name:

A late task in the Scheduler main screen

A late task in the main screen of the Scheduler BE module

The task list can be sorted by clicking the column label. With every click it switches between ascending and descending order of the items of the associated column.

The table at the center of the above screenshot shows the following:

  • The first column contains checkboxes. Clicking on a checkbox will select that particular scheduled task for immediate execution. Clicking on the icon at the top of the column will toggle all checkboxes. To execute the selected tasks, click on the "Execute selected tasks" button. Read more in "Manually executing a task" below.
  • The second column simply displays the id of the task.
  • The third column contains the name of the task, the extension it is coming from and any additional information specific to the task. It also shows a summary of the task's status with an icon.
  • The fourth column shows whether the task is recurring or will run only a single time.
  • The fifth column shows the frequency.
  • The sixth columns indicates whether parallel executions are allowed or not.
  • The seventh column shows the last execution time and indicates whether the task was launched manually or was run via the command-line script (cron).
  • The eighth column shows the planned execution time. If the task is overdue, the time will show up in bold, red numbers. A task may have no future execution date if it has reached its end date, if it was meant to run a single time and that execution is done, or if the task is disabled. The next execution time is also hidden for running tasks, as this information makes no sense at that point in time.
  • The last column contains possible actions, mainly editing, disable or deleting a task. There are also buttons for running the task on the next cron job or run it directly. The actions will be unavailable for a task that is currently running, as it is unwise to edit or delete it a task in such a case. Instead a running task will display a "stop" button (see "Stopping a task" below).

Note that all dates and times are displayed in the server's time zone. The server time appears at the bottom of the screen.

At the top of the screen is a link to add a new task. If there are a lot of tasks that appear late, consider changing the frequency at which the cron job is running (see "Choosing a frequency" above).

Occasionally the following display may appear:

A broken task

A scheduled task missing its corresponding class

This will typically happen when a task provided by some extension was registered, then the extension was uninstalled, but the task was not deleted beforehand. In such a case, this task stays but the Scheduler doesn't know how to handle it anymore. The solution is either to install the related extension again or delete the registered task.

Adding or editing a task

When adding or editing a task, the following form will show up:

Add task form

Adding a new scheduled task

Some fields require additional explanations (inline help is available by moving the mouse over the field labels):

  • A disabled task will be skipped by the command-line script. It may still be launched manually, as described above.
  • The class selector is available only when adding a new task. The class cannot be changed when editing a task, since there's no sense in that.
Select a class

Select the class of the scheduled task

New in version 13.3

Similar to editing regular content elements, it is now possible to save scheduler tasks being edited via keyboard shortcuts as well.

It is possible to invoke the Ctrl/Cmd + s hotkey to save a scheduler task, altogether with the hotkey Ctrl/Cmd + Shift + S to save and close a scheduler task.

  • A task must have a start date. The end date is not mandatory, though. A task without end date will run forever. Dates and times must be entered in the server's time zone. The server's time appears at the bottom of the form.
  • The frequency needs be entered only for recurring tasks. It can be either an integer number of seconds or a cron-like schedule expression. Scheduler supports ranges, steps and keywords like @weekly. See en.wikipedia.org for more information. See \TYPO3\CMS\Scheduler\CronCommand\CronCommand and \TYPO3\CMS\Scheduler\CronCommand\NormalizeCommand class references in the TYPO3 CMS source code for definitive rules.
  • Parallel executions are denied by default (see "Tasks execution" above). They must be allowed explicitly.
  • At the bottom of the form (highlighted area) there may be one or more additional fields. Those fields are specific to each task and will change when a different class is selected.

If there are some input errors, the form will reload upon submission and display the relevant error messages. When the input is finished and correct, the view switches back to the list view and displays a confirmation message.

Input validation

Input validation failed when adding a new scheduled task or editing an existing one

Input validation OK

Input validation succeeded when adding a new scheduled task or editing an existing one

If an error occurs when validating a cron definition, the Scheduler's built-in cron parser tries to provide an explanation about what's wrong.

Deleting a task

When choosing to delete a task, a pop-up window will appear requesting confirmation. If confirmed, the deletion is final. There is no "deleted" flag in the Scheduler's table, deleted task registrations cannot be recovered.

Grouping tasks together in the Scheduler backend module

In case of a high number of different tasks, it may be useful to visually group similar tasks together:

Overview of tasks with grouped

Grouping related tasks together

Scheduler task groups are records stored on the root page (pid=0). They may be created, edited and sorted with module Web > List:

Task group records

Management of scheduler task groups

It is also possible to create a new task group from within the edit task form by clicking on the + icon next to the task group select box.

Individual tasks may then be edited as usual and associated to a given scheduler task group.

The individual groups can be sorted independent of each other by clicking the column label. With every click it switches between ascending and descending order of the items of the associated column in the corresponding group.

Stopping a task in the Scheduler backend module

As was explained above, a task is marked as being executed while it is running. If the process running the task crashes or is killed for some reason, the task will stay marked as being executed. This will be cleaned up automatically according to the maximum lifetime parameter (also described previously), but this may be inconvenient in some circumstances.

Stopping a task

Stopping a running task from the main screen

In such cases it is possible to use the "stop" button to clean up marked executions for the given task. This will make it possible to run this task again. However please note that this will not kill a corresponding still running or continuously hanging process.

Manually executing a task from the Scheduler backend module

As mentioned above, it is possible to manually execute one or more registered tasks from the BE module. When the selected tasks have finished running, feedback is given about success or failure of each task's run. There's one important thing to note: if the task was overdue, a new execution date will be calculated. If the task was not overdue, the previously calculated next execution date stays.

A single task can be started by pressing the appropriate button in the row of the task. Multiple tasks can be started by selecting the checkboxes on the left side of the task row and then pressing the appropriate button beneath the task list.

There is one button for directly starting the task and another button for starting the task with the next cron job.

Executing a task for next Scheduler run

It is possible to manually set the next execution time of one or more registered tasks from the BE module to the current time. The selected tasks will then be running on the next cron job.

Running the scheduler: typo3 scheduler:run

The scheduler provides a PHP shell script designed to be run using TYPO3's command-line dispatcher. To try and run that script a first time, type the following command.

vendor/bin/typo3 scheduler:run
Copied!
typo3/sysext/core/bin/typo3 scheduler:run
Copied!

See also TYPO3 Explained: Run a command from the command line.

Show help

In order to show help:

vendor/bin/typo3 scheduler:run --help
Copied!
typo3/sysext/core/bin/typo3 scheduler:run --help
Copied!

Providing options to the shell script

The shell scripts accepts a number of options which can be provided in any order.

--task (-i)

To run a specific scheduler task you need to provide the uid of the task:

# Run task with uid 42
vendor/bin/typo3 scheduler:run --task=42

# Run tasks with uid 3 and 14
vendor/bin/typo3 scheduler:run --task=3 --task=14
Copied!
# Run task with uid 42
typo3/sysext/core/bin/typo3 scheduler:run --task=42

# Run tasks with uid 3 and 14
typo3/sysext/core/bin/typo3 scheduler:run --task=3 --task=14
Copied!

The tasks will be executed in the order in which the parameters are provided.

-f

To run a task even if it is disabled (or not scheduled to be run yet), you need to provide the force option:

# Run task with uid 42, even if disabled
vendor/bin/typo3 scheduler:run --task=42 -f
Copied!
# Run task with uid 42, even if disabled
typo3/sysext/core/bin/typo3 scheduler:run --task=42 -f
Copied!

This will also run the task with uid 42 if it is disabled.

-v

A single -v flag will output errors only. Two -vv flags will also output additional information:

# Run task with uid 42, with detailed stack traces
vendor/bin/typo3 scheduler:run --task=42 -vv
Copied!
# Run task with uid 42, with detailed stack traces
typo3/sysext/core/bin/typo3 scheduler:run --task=42 -vv
Copied!

Scheduler task development

The Scheduler makes it very easy to create a new task class. Furthermore the tasks packaged with this extension provide a good basis to learn by example.

Creating a custom scheduler task

The preferred method for creating a scheduler task is as a symfony command. Read about how to create and use symfony commands in TYPO3 here.

Working with serialized objects

When a task is registered with the Scheduler the corresponding object instance is serialized and stored in the database (see Appendix A for more details). This is not a very common practice. There are advantages but also some pitfalls, so please read this section carefully.

A serialized object may happen to be "out of sync" with its class if the class changes some of its variables or methods. If a variable's name is changed or if variables are added or removed, the serialized object will not reflect these changes. The same goes if a method is renamed, added or deleted. Problems will also arise if the number or order of arguments used to call a method are changed. In such cases weird errors may appear, which can be very difficult to track. The only solution is to delete the registered task and register it anew.

To minimize such risks it is worth to consider implementing the business logic in a separate class, so that the task class itself changes as little as possible. The execute() should be as simple as possible. Consider the following:

packages/my_extension/Classes/MyTask.php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Tasks;

use MyVendor\MyExtension\BusinessLogic;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Scheduler\Task\AbstractTask;

final class MyTask extends AbstractTask
{
    public function execute(): bool
    {
        # Dependency injection cannot be used in scheduler tasks
        $businessLogic = GeneralUtility::makeInstance(BusinessLogic::class);
        return $businessLogic->run('arg1', 'arg2', '…');
    }
}
Copied!

In such a setup the execute() is kept to the strict minimum and the operations themselves are handled by a separate class.

Also remember that the constructor is not called when unserializing an object. If some operations need to be run upon unserialization, implement a __wakeup() method instead.

Saving a task's state

The task's state is saved automatically at the start of its execution. If you need to save a task's state at some point during its execution, you can simply call the task's own save() method.

Scheduler API

It is possible to refer to the Scheduler from other extensions. Once a \TYPO3\CMS\Scheduler\Scheduler object has been instantiated all of its public methods can be used. The PHPdoc of the methods should be enough to understand what each is to be used for.

The extension ships with a \TYPO3\CMS\Scheduler\Domain\Repository\SchedulerTaskRepository class, which provides some helpful methods, for example:

  • findByUid(int $uid): this method is used to fetch a registered task from the database given an ID.
  • findNextExecutableTask(): this method returns the next due task. The return value is the unserialized task object.
  • findRecordByUid(int $uid): is also used to retrieve a registered task from the database, but it returns the record corresponding to the task registration and not the task object itself.

These are the main methods that will be used from outside the Scheduler as they can retrieve registered tasks from the database. When a task has been fetched, all public methods from the \TYPO3\CMS\Scheduler\Task\AbstractTask class can be used.

Known problems

The main problem currently is that a running task cannot be killed, because no relation exists to the (cron) process that is running the Scheduler. The process pid could be retrieved, but that may not work on all platforms. And can the process be killed afterwards? Anyway it may not be safe to do that.

Technical background of the scheduler extension

This section aims to give some more in-depth information about what happens behind the scene in the Scheduler.

When a task is registered with the Scheduler, an instance of the task class is created and stored in a database record as a serialized object. The database record itself contains additional information about the registration, mostly about past and future executions. The theory is that all the information that is really proper to the task should be defined as member variables of the task class and is thus encapsulated inside the task object. The information which relates to executing a registered task is stored in the Scheduler's database table.

That being said, a task also contains information about its execution. Indeed each task class has an instance of TYPO3\CMS\Scheduler\Execution as a member variable, which contains information such as start and end date and is used to calculate the next execution date.

When a task is running, its start time is stored into an array, which is serialized and stored in the corresponding database record. If several executions are running at the same time, the array will contain several timestamps. Thus the "serialized_executions" field actually contains an array of integers and not serialized instances of TYPO3\CMS\Scheduler\Execution objects.

Sitemap