PHPackages                             directorytree/cadence - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. directorytree/cadence

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

directorytree/cadence
=====================

Model-based scheduling for Laravel

v1.1.0(1mo ago)581.4k↓75.7%3MITPHPPHP ^8.2CI passing

Since May 4Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/DirectoryTree/Cadence)[ Packagist](https://packagist.org/packages/directorytree/cadence)[ Docs](https://github.com/directorytree/cadence)[ GitHub Sponsors](https://github.com/directorytree)[ RSS](/packages/directorytree-cadence/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (4)Dependencies (26)Versions (7)Used By (0)

[![](https://github.com/DirectoryTree/Cadence/raw/master/art/logo.svg)](https://github.com/DirectoryTree/Cadence/blob/master/art/logo.svg)

Model-based scheduling for Laravel.

[![](https://camo.githubusercontent.com/389d74894d81f8ee1a13159ab3e38991662c53099ff00d73c93d5429aedd4934/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6469726563746f7279747265652f636164656e63652f72756e2d74657374732e796d6c3f6272616e63683d6d6173746572267374796c653d666c61742d737175617265)](https://github.com/directorytree/cadence/actions)[![](https://camo.githubusercontent.com/0c9874db67bc223160ea2ff82a97fdbd49598b6c03f0c4214c5e356478f53372/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6469726563746f7279747265652f636164656e63652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/directorytree/cadence)[![](https://camo.githubusercontent.com/c86962c2cada46dae260542365f92b31234a0bc8e7ae65a0f752a2441f6f4c7c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6469726563746f7279747265652f636164656e63652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/directorytree/cadence)[![](https://camo.githubusercontent.com/4721502c2656d26abe80b0414764eb08a0ed52812d7c3a164c5d2e5d7f652313/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6469726563746f7279747265652f636164656e63652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/directorytree/cadence)

---

Cadence provides a driver-based scheduling system for your Eloquent models using cron expressions or RRULE recurrence patterns. Attach one or many schedules to any model, and Cadence will track and dispatch events when they're due.

Index
-----

[](#index)

- [Requirements](#requirements)
- [Installation](#installation)
- [Setup](#setup)
- [Usage](#usage)
    - [Adding Schedules](#adding-schedules)
    - [Timezones](#timezones)
    - [Disabling Schedules](#disabling-schedules)
    - [Running Due Schedules](#running-due-schedules)
    - [Listening for Triggered Schedules](#listening-for-triggered-schedules)
- [Drivers](#drivers)
    - [Cron](#cron)
    - [RRULE (php-rrule)](#rrule-php-rrule)
    - [RRULE (Recurr)](#rrule-recurr)
    - [Custom Drivers](#custom-drivers)
- [Customizing Drivers](#customizing-drivers)

Requirements
------------

[](#requirements)

- PHP &gt;= 8.2
- Laravel &gt;= 11.0

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

[](#installation)

You can install the package via composer:

```
composer require directorytree/cadence
```

Then, install at least one schedule driver:

```
# Cron (recommended for simple schedules)
composer require dragonmantank/cron-expression

# RRULE via php-rrule
composer require rlanvin/php-rrule

# RRULE via Recurr
composer require simshaun/recurr
```

Publish and run the migrations:

```
php artisan vendor:publish --provider="DirectoryTree\Cadence\CadenceServiceProvider"
php artisan migrate
```

This creates a `schedules` table with the following columns:

- `schedulable_type` / `schedulable_id` — polymorphic relation to your model
- `type` — the driver type (e.g. `cron`, `rrule`, `recurr`)
- `expression` — the schedule expression
- `timezone` — optional timezone for the schedule
- `next_run_at` — precomputed next occurrence for efficient querying
- `last_run_at` — timestamp of the last run
- `disabled_at` — timestamp indicating the schedule is disabled

If you're upgrading from an existing Cadence installation, publish and run the new migration before using the schedule enable / disable APIs:

```
php artisan vendor:publish --provider="DirectoryTree\Cadence\CadenceServiceProvider"
php artisan migrate
```

Setup
-----

[](#setup)

Implement the `Schedulable` interface and use the `HasSchedules` trait on any model you want to schedule:

```
// app/Models/Report.php

namespace App\Models;

use DirectoryTree\Cadence\HasSchedules;
use DirectoryTree\Cadence\Schedulable;
use Illuminate\Database\Eloquent\Model;

class Report extends Model implements Schedulable
{
    use HasSchedules;
}
```

Usage
-----

[](#usage)

### Adding Schedules

[](#adding-schedules)

Create a driver instance and add it to your model:

```
use DirectoryTree\Cadence\Drivers\CronSchedule;

$report = Report::find(1);

// Every day at noon
$report->addSchedule(new CronSchedule('0 12 * * *'));

// Every Monday at 9am
$report->addSchedule(new CronSchedule('0 9 * * 1'));
```

With RRULE expressions:

```
use DirectoryTree\Cadence\Drivers\RruleSchedule;

// Every weekday
$report->addSchedule(new RruleSchedule('FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR'));

// Monthly on the 15th, starting from a specific date
$report->addSchedule(new RruleSchedule('DTSTART=20260101T000000;FREQ=MONTHLY;BYMONTHDAY=15'));
```

### Timezones

[](#timezones)

Schedules can be timezone-aware. Pass the timezone as the second argument:

```
// Every day at 9am Eastern
$report->addSchedule(
    new CronSchedule('0 9 * * *', 'America/New_York')
);
```

Or set it via the `setTimezone()` method:

```
$schedule = new CronSchedule('0 9 * * *');

$schedule->setTimezone('America/New_York');

$report->addSchedule($schedule);
```

### Disabling Schedules

[](#disabling-schedules)

Schedules may be disabled without deleting them:

```
$schedule->disable();
```

Disabling a schedule sets `disabled_at` and clears `next_run_at`, so the schedule will not be picked up by the `schedules:run` command.

Enable the schedule again to compute its next occurrence from the current time:

```
$schedule->enable();
```

You may also check or query schedule state:

```
use DirectoryTree\Cadence\Schedule;

$schedule->isEnabled();
$schedule->isDisabled();

Schedule::enabled()->get();
Schedule::disabled()->get();
```

### Running Due Schedules

[](#running-due-schedules)

Register the `schedules:run` command in your application's scheduler to run every minute:

```
// routes/console.php

use Illuminate\Support\Facades\Schedule;

Schedule::command('schedules:run')
    ->withoutOverlapping()
    ->everyMinute();
```

This command queries all schedules where `next_run_at schedule->schedulable_type = Report::class;
    }

    public function handle(ScheduleTriggered $event): void
    {
        $event->schedulable->generate();
    }
}
```

Register it in your `EventServiceProvider` or use event discovery.

Drivers
-------

[](#drivers)

Cadence uses a driver-based architecture. Drivers are automatically registered when their backing library is installed.

### Cron

[](#cron)

Requires [`dragonmantank/cron-expression`](https://github.com/dragonmantank/cron-expression):

> This package is already required by the Laravel framework core.

```
use DirectoryTree\Cadence\Drivers\CronSchedule;

new CronSchedule('0 12 * * *');         // Every day at noon
new CronSchedule('*/15 * * * *');       // Every 15 minutes
new CronSchedule('0 9 * * 1-5');        // Weekdays at 9am
```

### RRULE (php-rrule)

[](#rrule-php-rrule)

Requires [`rlanvin/php-rrule`](https://github.com/rlanvin/php-rrule):

```
use DirectoryTree\Cadence\Drivers\RruleSchedule;

new RruleSchedule('FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR');
new RruleSchedule('FREQ=MONTHLY;BYMONTHDAY=1;COUNT=12');
```

### RRULE (Recurr)

[](#rrule-recurr)

Requires [`simshaun/recurr`](https://github.com/simshaun/recurr):

```
use DirectoryTree\Cadence\Drivers\RecurrSchedule;

new RecurrSchedule('FREQ=WEEKLY;BYDAY=MO,WE,FR');
new RecurrSchedule('FREQ=YEARLY;BYMONTH=1;BYMONTHDAY=1');
```

### Custom Drivers

[](#custom-drivers)

Create a class that extends the base `Schedule` driver:

```
namespace App\Drivers;

use Carbon\CarbonInterface;
use DirectoryTree\Cadence\Drivers\Schedule;

class CustomSchedule extends Schedule
{
    protected function resolveNextOccurrence(CarbonInterface $after): ?CarbonInterface
    {
        // Your recurrence logic here
    }
}
```

Then register it in your `AppServiceProvider`:

```
use App\Drivers\CustomSchedule;
use DirectoryTree\Cadence\Schedule;

Schedule::driver('custom', CustomSchedule::class);
```

Customizing Drivers
-------------------

[](#customizing-drivers)

Each driver exposes a static `tap` method to configure the underlying library instance before it's used:

```
use Cron\CronExpression;
use DirectoryTree\Cadence\Drivers\CronSchedule;

CronSchedule::tap(function (CronExpression $cron) {
    // Configure the CronExpression instance
});
```

```
use Recurr\Rule;
use Recurr\Transformer\ArrayTransformer;
use Recurr\Transformer\ArrayTransformerConfig;
use DirectoryTree\Cadence\Drivers\RecurrSchedule;

RecurrSchedule::tap(function (Rule $rule, ArrayTransformer $transformer) {
    $transformer->setConfig(
        (new ArrayTransformerConfig)->enableLastDayOfMonthFix()
    );
});
```

Pass `null` to clear the callback:

```
RecurrSchedule::tap(null);
```

###  Health Score

50

—

FairBetter than 95% of packages

Maintenance91

Actively maintained with recent releases

Popularity33

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 81.5% 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 ~13 days

Total

4

Last Release

41d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/c6dd082636ff8a08df8dfdcd622ea242374d1d76dd33bceec5a6cd3ae26dc24f?d=identicon)[stevebauman](/maintainers/stevebauman)

---

Top Contributors

[![stevebauman](https://avatars.githubusercontent.com/u/6421846?v=4)](https://github.com/stevebauman "stevebauman (44 commits)")[![SantosVilanculos](https://avatars.githubusercontent.com/u/95357132?v=4)](https://github.com/SantosVilanculos "SantosVilanculos (7 commits)")[![Copilot](https://avatars.githubusercontent.com/in/1143301?v=4)](https://github.com/Copilot "Copilot (2 commits)")[![onurege3467](https://avatars.githubusercontent.com/u/78586675?v=4)](https://github.com/onurege3467 "onurege3467 (1 commits)")

---

Tags

laravelschedulingdirectorytreecadence

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/directorytree-cadence/health.svg)

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

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[laravel/ai

The official AI SDK for Laravel.

1.0k3.2M246](/packages/laravel-ai)[api-platform/laravel

API Platform support for Laravel

58174.6k17](/packages/api-platform-laravel)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5022.6k](/packages/simplestats-io-laravel-client)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

255.2k](/packages/aedart-athenaeum)

PHPackages © 2026

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