PHPackages                             dragonmantank/sched - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Queues &amp; Workers](/categories/queues)
4. /
5. dragonmantank/sched

ActiveLibrary[Queues &amp; Workers](/categories/queues)

dragonmantank/sched
===================

Lightweight scheduling and job running system

0.14.0(4y ago)06701[1 PRs](https://github.com/dragonmantank/sched/pulls)Apache-2.0PHPPHP ^8.0

Since Jan 22Pushed 2y ago1 watchersCompare

[ Source](https://github.com/dragonmantank/sched)[ Packagist](https://packagist.org/packages/dragonmantank/sched)[ RSS](/packages/dragonmantank-sched/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (13)Versions (22)Used By (0)

Sched
=====

[](#sched)

#### A simple queue-based job scheduler and runner

[](#a-simple-queue-based-job-scheduler-and-runner)

Sched is a simple job runner and scheduler to schedule and run jobs. Using beanstalkd as a backend, it can arbitrarily invoke code based on jobs that come into tubes as well as schedule jobs using a cron syntax.

Installation
------------

[](#installation)

Sched is designed to be installed with your application and use your vendor and autoload settings. It is not meant to be run on it's own as a standalone application, though it does have it's own daemon.

```
composer require dragonmantank/sched
```

If you are wanting to use the cron aspect of Sched, you will want to set up your system's cron to have Sched check every minute if a job is due:

```
* * * * /path/to/php /path/to/your/app/vendor/bin/sched-manager -c /path/to/sched-manager.config.php cron:process

```

### Requirements

[](#requirements)

- PHP 8.0 or higher
- [beanstalkd](https://beanstalkd.github.io/)

Usage
-----

[](#usage)

Running schedule requires starting the manager along with a configuration file. To run the the manager:

```
vendor/bin/sched-manager [-c /path/to/sched-manager.config.php] [-v] manager:run
```

The manager will loop through all of the configured queues and process them in lots of 5. For example, if there are 10 messages in the queue, Sched will start up 2 workers, each handling 5 jobs. It will loop through the queues and constantly check the number of jobs against the number of workers.

Configuration
-------------

[](#configuration)

Sched requires a configuration file to know how to process your queues, and will ignore any queues that are not configured. You can also schedule jobs and custom commands through this same configuration file.

```
return [
    'cron' => [
        [
            'name' => 'Name of cron job, for logging',
            'expression' => '* * * * *',
            'worker' => // Invokable that needs to run at this time
        ]
    ],
    'logger' => MyLoggingFactory::class,
    'custom_commands' => [MyCommand::class, MyOtherCommand::class],
    'manager' => [
        'max_workers' => 10,
        'max_workers_per_tube' => 5,
    ],
    'pheanstalk' => [
        'host' => '127.0.0.1',
        'port' => 113900,
        'timeout' => 10,
    ],
    'queues' => [
        'queueName' => [
            'worker' => // Invokable that processes the queue
        ],
    ],
];
```

### Queue Management

[](#queue-management)

The `queues` section of the config file lets you define which queues you want to watch, and what code to pass the payload to (called a Worker). It is assumed that each payload is a JSON object.

For example, if you want to watch the `download-payroll-report` queue and have it processed by `Me\MyApp\ReportDownloader\Payroll`, you can figure it as such:

```
use Me\MyApp\ReportDownloader\Payroll;

return [
    'queues' => [
        'download-payroll-report' => [
            'worker' => Payroll::class
        ],
    ],
];
```

`Me\MyApp\ReportDownloader\Payroll` just needs to be an invokable class and implement the `__invoke(array $payload): int` signature.

```
namespace Me\MyApp\ReportDownloader;

class Payroll
{
    // Assuming a payload originally of {"url": "https://payrollcorp.net/api/report/2021-01-01?apiKey=S3CR3T"}
    public function __invoke(array $payload): int
    {
        $ch = curl_init($payload['url']);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $report = curl_exec($ch);
        curl_close($ch);

        file_put_contents(
            (\new DateTime())->format('Y-m-d') . '.csv',
            $report
        );

        return 0;
    }
}
```

You can also control the number of jobs that spawn per manager instance as well as per queue. By default Sched limits itself to 10 total jobs and 5 total jobs per queue, but this can be tweaked under the `max_workers` and `max_workers_per_queue` options under the `manager` config section.

### Scheduling Jobs

[](#scheduling-jobs)

You can also schedule jobs to run at specific times. Much like a queue worker, you can designate a worker to run at a specific time. Let's say we want our report downloader to fire at 4:00am every Saturday, to give our payroll system long enough to process and generate the report. We can specify a cron expression and the worker to do that:

```
use Me\MyApp\Cron\GeneratePayrollDownload;

return [
    'cron' => [
        [
            'name' => 'Generate Payroll Download',
            'expression' => '0 4 * * SAT',
            'worker' => GeneratePayrollDownload::class
        ]
    ]
    'queues' => [ ... ]
];
```

Just like with the queue workers, the cron workers just need to be an invokable class that implements `public function __invoke(): int` (notice it does not take a `$payload`):

```
namespace Me\MyApp\Cron;

class GeneratePayrollDownload
{
    public function __construct(protected Pheanstalk $pheanstalk)
    {
    }

    public function __invoke(): int
    {
        $date = new \DateTimeImmutable();
        $url = 'https://payrollcorp.net/api/report/' . $date->format('Y-m-d') . '/?apiKey=S3C3R3T';
        $this->pheanstalk->useTube('download-payroll-report')
            ->put(json_encode([
                'url' => $url
            ]));
    }
}
```

While the above example adds a job for the queue system to pick up and process, you can also run workers that process whatever is needed at the time without using the queues.

### Custom Commands

[](#custom-commands)

There may come a time where you need to register a command directly with Sched instead of having it schedule jobs for you. For example, if you want to run a script every so often to queue up a bunch of files for processing but do not want it to be on a schedule, you can register a command with `sched-manager` that you can invoke. You can set a class name in the `custom_commands` array of the configuration file. This command must be a [Symfony Console Command](https://symfony.com/doc/current/console.html).

```
// sched-manager-config.php.dist
use Me\MyApp\Command\QueueFilesForProcessing;

return [
    'cron' => [ ...],
    'custom_commands' => [
        QueueFilesForProcessing::class,
    ]
    'queues' => [ ... ]
];
```

```
// QueueFieldsForProcessing.php
use Me\MyApp\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class QueueFilesForProcessing extends Command
{
    protected static $defaultName = 'app:customcommand';

    protected function configure(): void
    {
        $this
            ->setHelp('This is a sample command');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        // Do some stuff
        Return Command::SUCCESS;
    }

}
```

### Logging

[](#logging)

Sched supports PSR-3 compatible loggers in addition to writing to the console itself. If you supply an invokable class to the `logger` configuration key, Sched will inject that into the available commands where requested via dependency injection. Many of the commands will still write output to the console even if a proper logger is not used.

Sched makes available `Dragonmantank\Sched\LoggingTrait` as a trait to help write to the logger in your own commands. You can add this to your classes and then use `$this->log($output, LogLevel::INFO, "My Message");` to log to the logger itself. This function will also log to the console depending on level of verbosity (`-v`, `-vv`, `-vvv`) supplied to the command.

###  Health Score

26

—

LowBetter than 43% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity14

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Recently: every ~12 days

Total

20

Last Release

1489d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/8c2583b67d4e1a4ade23b6ce271980d18bf3facb4ea3f0610fded770f380d17d?d=identicon)[dragonmantank](/maintainers/dragonmantank)

---

Top Contributors

[![dragonmantank](https://avatars.githubusercontent.com/u/108948?v=4)](https://github.com/dragonmantank "dragonmantank (26 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/dragonmantank-sched/health.svg)

```
[![Health](https://phpackages.com/badges/dragonmantank-sched/health.svg)](https://phpackages.com/packages/dragonmantank-sched)
```

###  Alternatives

[laravel/framework

The Laravel Framework.

34.6k509.9M17.0k](/packages/laravel-framework)[matomo/matomo

Matomo is the leading Free/Libre open analytics platform

21.4k37.3k](/packages/matomo-matomo)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[laravel-zero/framework

The Laravel Zero Framework.

3371.4M369](/packages/laravel-zero-framework)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[crunzphp/crunz

Schedule your tasks right from the code.

2292.0M6](/packages/crunzphp-crunz)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
