#[Scheduled] attribute. Rather than managing cron jobs externally, you embed timing logic inside your application code, and the framework handles process lifecycle and execution. Scheduled tasks run inside a dedicated worker process separate from the HTTP workers — this means a slow or long-running task never blocks web request handling. All you need is the Swoole extension and a single annotation on your application class to activate the feature.
Prerequisites
Scheduling is powered by the Swoole PHP extension. Install and enable it before using#[Scheduled].
1
Install the Swoole extension
2
Enable Swoole in php.ini
Enable Scheduling on Your Application Class
Add#[EnableScheduling] to your #[WinterBootApplication] class. The framework validates at startup that #[WinterBootApplication] is also present and that Swoole is loaded — a TypeError or AnnotationException is raised if either condition is not met.
MyApplication.php
The #[Scheduled] Attribute
Place #[Scheduled] on any public, non-final, non-abstract, zero-argument void method on a #[Service] or #[Component] bean. You must supply exactly one of the interval parameters (fixedDelay or fixedRate); combining conflicting options throws an AnnotationException at boot.
Parameters
int
Seconds to wait after the previous execution completes before starting the next. Use this when you want to avoid overlapping runs and the task duration may vary.
string
Property placeholder (e.g.
${my.delay}) that resolves to the fixedDelay value from your application configuration.int
Seconds between the start of successive executions, regardless of how long each run takes. Use this when you need a consistent heartbeat.
string
Property placeholder resolving to the
fixedRate value from your application configuration.int
Seconds to wait after application startup before the first execution fires.
string
Property placeholder resolving to the
initialDelay value from your application configuration.Fixed Delay vs. Fixed Rate
The two core scheduling modes behave differently when a task takes longer than its interval. Choose the one that matches your task’s requirements.- fixedDelay
- fixedRate
fixedDelay introduces a gap between the end of one execution and the start of the next. Use this when you want to avoid overlapping runs and the task duration may vary.CacheWarmer.php
[startup] → 10s delay → run → 60s delay → run → 60s delay → run → …Externalise Timing with Property Placeholders
Timing values can be externalised toapplication.yml using the String variants of each parameter. This lets you adjust schedules per environment without redeploying code.
application.yml
SomeScheduler.php
Configuration
Configure the scheduling worker pool inapplication.yml under winter.task.scheduling:
application.yml
int
Total number of worker processes dedicated to executing scheduled tasks.
int
Maximum number of concurrent scheduled task invocations that can be queued at once.
Scheduled tasks run inside a separate worker process managed by Swoole. They are entirely non-blocking with respect to incoming HTTP requests — web workers and scheduling workers never share execution time.