goksagun/scheduler-bundle
A Symfony bundle for defining and running scheduled tasks in PHP. Register recurring jobs with simple configuration, then let the scheduler handle execution so you can keep cron logic inside your application instead of scattered server crontabs.
Architecture fit. The first-order finding is a naming and idiom mismatch that a TPM must flag before any engineering time is spent: scheduler-bundle follows Symfony's bundle convention (DI extension + compiler passes + config tree), not Laravel's package convention (service provider + facade + publishable config). Laravel already owns this problem space through Illuminate\Console\Scheduling\Schedule, which ships cron-expression parsing, withoutOverlapping, onOneServer, runInBackground, onSuccess/onFailure hooks, schedule:list/schedule:test, and first-class integration with the framework's cache locks and event dispatcher. For a Laravel codebase, this package is therefore not a gap-filler but a substitution candidate, and a substitution would have to clear a very high bar to justify displacing a framework-owned component with 7 stars and 0 dependents. Realistic architectural fit: low for direct adoption in Laravel, moderate as a concept source if it encodes scheduling patterns (task registry, priority queues, dependency ordering) that Laravel's scheduler lacks.
Integration feasibility. Feasible only as a library wrapped behind an internal abstraction, not as a framework integration. If the core is framework-agnostic PHP with Symfony components as peripheral glue, a thin adapter service provider plus our own SchedulerContract is roughly a 2–4 day spike for a mid-level engineer. If the core is bound to Symfony's container and event dispatcher, the adapter becomes a rewrite and the effort estimate collapses into "evaluate only."
Technical risk. Ranked:
symfony/console, symfony/process, symfony/finder, symfony/http-foundation, and symfony/error-handler. A bundle with tight Symfony version constraints is a plausible Composer resolution failure or, worse, a silent transitive pin that blocks future Laravel upgrades.Key questions for the maintainer / source audit.
Illuminate\Console\Scheduling\Schedule does not — dependency ordering between tasks, persistent task state, retry/backoff, sub-minute granularity, or cross-process coordination?composer.json, and does the constraint set intersect cleanly with our target Laravel version?Stack fit. Poor-to-marginal for direct use. For a Laravel shop the honest stack fit is: do not adopt as a scheduler replacement. Consider two narrower plays instead — (a) a scoped spike to harvest design ideas if we have a genuine scheduler gap (e.g., inter-task dependency graphs, which Laravel handles only crudely via chained commands), or (b) reuse of the package's cron-expression or registry logic as vendored source if a specific piece is genuinely better than the framework's. Any adoption decision should be recorded as "justified deviation from framework default," because that is what it is.
Migration path. If we proceed, migrate in this order and never in one step:
Illuminate\Console\Scheduling\Schedule as the registered execution path.TaskScheduler interface; implement a Laravel-backed adapter first (current behavior, zero risk) and a bundle-backed adapter second.schedule:list output.The migration is reversible by design; that reversibility is the main deliverable of the integration work, more than the integration itself.
Compatibility. Validate before committing engineering time: run a composer require --dry-run against each Laravel/PHP version in our support matrix, check that no symfony/* constraint moves, and confirm the package does not require a PSR or container version that conflicts with our framework minor. Treat any forced Symfony downgrade as an automatic no-go — it is a future upgrade tax on the whole application.
Sequencing. Source audit (0.5 day) → dependency dry-run against the support matrix (0.5 day) → go/no-go gate → throwaway spike behind the interface (2–4 days) → shadow-mode bake (2–4 weeks elapsed, low effort) → phased cutover per task. Total committed engineering before a real decision: under one week. Do not sequence this ahead of any framework-upgrade or observability work; it is a low-urgency evaluation competing against higher-leverage backlog items.
Maintenance. Budget for fork-and-own from day one. With a single maintainer and no dependent base, the realistic operating model is: vendor the package, pin the version, and accept that security patches and Laravel-compatibility fixes are ours to write. Carry an explicit line item of roughly 1–2 engineer-days per quarter for upkeep, plus a spike whenever we move Laravel minor versions. If that line item is not funded, the answer is no.
Support. There is no community to escalate to — no dependents means no one else has hit the failure mode you are about to hit. Internal runbooks and a named owner are prerequisites, not follow-ups. Contrast this with the framework scheduler, where the effective support surface is the entire Laravel ecosystem.
Scaling. The scaling question is not throughput (schedulers are control-plane, not data-plane) but multi-node correctness. On more than one app server, a scheduler without proper mutex and distributed-lock semantics produces duplicate executions — the classic double-send, double-charge, double-email incident. Confirm the package supports shared-cache locking equivalent to onOneServer, and confirm it degrades safely (skip, not run) when the lock backend is unavailable. Also verify behavior under runInBackground: unmonitored background children can accumulate if the package does not reap them, and long-running tasks must not block the per-minute schedule:run cron tick.
Failure modes. Ranked by blast radius and detectability:
onFailure and event hooks are the integration point for our monitoring; if the package bypasses them, failed tasks vanish into logs.Ramp-up. Conceptually cheap — a mid-level engineer who knows Laravel's scheduler will read this in a day if the documentation exists, and the documentation's existence is itself unverified. The real ramp-up cost is organizational: teaching the team that there are now two scheduling paths, which tasks use which, and how to debug each. That ambiguity, not the API, is the durable cost. If adoption happens, one engineer should own the internal adapter and its docs, and onboarding should include a "how to add a scheduled task" decision tree.
Bottom line for the roadmap. Given a composite score of 0.245, zero dependents, and a mature framework-native alternative, the recommendation is evaluate-only, gated at one week of engineering. Fund a source audit and a dependency dry-run; do not fund integration until those surface a capability Laravel genuinely lacks. The high opportunity score should be read as an untested niche, not as validated demand — a TPM's job here is to spend a week to close the question, not a quarter to answer it.
How can I help you explore Laravel packages today?