Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Cron Bundle Laravel Package

lingoda/cron-bundle

Lingoda Cron Bundle adds cron job scheduling to Symfony applications, letting you define recurring tasks and run console commands on configured schedules from a single, centralized bundle.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Release under review: 2.3.1 — "prevent new scheduled jobs from firing immediately on deploy"

This is a patch release, but it is materially informative and changes two things in the prior assessment. First, the package owns runtime scheduling and job state, not merely cron-expression parsing — a first-run/deploy-semantics bug only exists in a component that persists per-job state and computes next-run times from it. Second, the version number (2.3.1) implies at least four prior minor releases, which partially contradicts the earlier reading of the registry snapshot as a single-release package. The earlier claim that we cannot assess design from metadata still holds for internals, but the design model is now visible: a catch-up-style scheduler keyed on job identity, with a stored baseline per job.

What this package appears to be

Unchanged: lingoda/cron-bundle is a Symfony bundle, not a Laravel package. No ServiceProvider, no facade, no Laravel auto-discovery. That framing mismatch remains the single biggest issue in this record. What we now know in addition is that it is a scheduler with state, which makes it a closer analogue to symfony/scheduler and Laravel's Schedule than to a bare expression parser — and therefore more directly competitive with, and redundant to, first-party options.

Architecture fit

  • Still poor as a direct Laravel dependency. Laravel owns this problem space via Schedule, schedule:run/schedule:work, and dragonmantank/cron-expression. A Symfony bundle cannot be consumed idiomatically.
  • The architectural difference is now nameable. A stored-last-run model implies catch-up/backfill behaviour: if the worker is down across a schedule window, the package may compute and fire missed runs on restart, whereas Laravel's Schedule simply evaluates the current minute and silently skips. That is a genuine behavioural divergence, and it is the first concrete answer to "what does this do that native scheduling does not." Whether it is a desirable divergence is a product decision, not a technical one.
  • New state-store coupling. The fix implies job definitions are identified by a stable key and tracked in a persistence layer (DB table, cache, or filesystem). In our architecture that store becomes a shared dependency across app instances and a second thing to back up, migrate, and reconcile. That is a real architectural cost the previous assessment did not capture.

Integration feasibility

  • Effort estimate is unchanged: 2–5 engineer-days for a bridge spike, plus the new work of understanding and provisioning the state store.
  • Practical value remains low for a Laravel shop — but the catch-up semantics are now a legitimate reason to run the spike if (and only if) we have a business requirement for missed-run backfill. Absent that requirement, we are paying a bridge cost to reproduce behaviour we deliberately do not have.

Technical risk

  • Deploy-time misfire is an incident-class bug, and it shipped. Anyone on ≤ 2.3.0 has jobs that fire immediately on deploy when new schedules are introduced. In a customer-facing context — invoice generation, notification fan-out, billing retries — that is duplicate side effects at exactly the moment the system is least stable. That 2.3.0 and below are affected should be stated plainly in any record we keep.
  • But the fix is a positive maintenance signal. A patch release addressing a deploy-lifecycle edge case implies real production usage and a maintainer who ships. This modestly improves the abandonment outlook from the prior "assume zero responsiveness" position — to "unproven but non-zero."
  • Release-date anomaly unresolved. Version 2.3.1 does not explain the 2026-03-30 timestamp on the prior release. Either the registry snapshot was wrong or there is a second release in the record we have not seen. Verify tag provenance and changelog continuity before trusting the version history.
  • Exposure profile unchanged. Single maintainer, ~1 star, 0 dependents, no CVE history, no third-party review, and a code path that plausibly shells out. MIT mitigates the legal risk only.
  • Composer constraint risk unchanged and, with four minors of history, now slightly more likely: a package that has iterated on minors may have moved its symfony/* floors, which is where Laravel install-time conflicts surface.

Key questions (revised)

  1. Where is per-job state stored, and is it shared across nodes? This is now the top question. DB-backed and shared is workable; per-host file or local cache is disqualifying for our multi-node estate.
  2. What is the defined first-run semantic for a newly added job? After 2.3.1, does a new job wait for its next cron window, run once at deploy, or something configurable? We need this documented explicitly, not inferred.
  3. Does it backfill missed runs after downtime, and is that bounded? If unbounded, a weekend outage becomes a thundering herd on Monday.
  4. Is the core framework-agnostic, or Symfony-coupled throughout?
  5. Who maintains it at Lingoda, and is there a stated support matrix for PHP 8.x / Symfony 7 / Laravel 11+?
  6. Does any path shell out, and how are arguments escaped?
  7. What is the real tag history — is 2026-03-30 a genuine release?
  8. Is there a test suite, and does it cover deploy/first-run transitions specifically? A regression test for 2.3.1 is the single best proxy for whether this codebase is safe to depend on.

Integration Approach

Stack fit

  • Laravel shop: still do not integrate, unless the catch-up/backfill requirement is confirmed as a business need. Default recommendation stands: dragonmantank/cron-expression + native Schedule + spatie/laravel-schedule-monitor.
  • Symfony shop: benchmark against symfony/scheduler, which is framework-native and covers the same ground. The bundle's differentiator is now specifically the persisted-state catch-up model — evaluate that, not the scheduling generally.
  • Hybrid: reference implementation only.

Migration path (if we proceed)

  1. Spike branch. Install against our PHP and framework majors; confirm the state store provisions cleanly.
  2. State store design review before any code. Decide the backing store, the key derivation for job identity, and the retention/pruning story. This is the step that did not exist before this release and it is not optional.
  3. Isolation layer. Keep the vendor type behind our own SchedulerGateway interface so removal is a one-file change.
  4. Deploy-semantics test matrix, added as a required gate. For each of: new job added, job renamed, job removed, node replaced, rollback to previous release — assert exactly-once and confirm no immediate fire. Run against a shared state store with ≥ 2 app instances. This test is directly derived from 2.3.1 and should be written before we trust 2.3.1.
  5. Parallel run for one full cycle against the existing scheduler, diffing computed run times and fired jobs. Include at least one deliberate outage window to observe backfill behaviour.
  6. Cutover behind a config flag, legacy path retained one cycle.

Compatibility

  • Pin to 2.3.1 exactly, not ^2.3. We now have evidence of behaviour changes landing in patch releases, which is defensible for a bug fix of this severity but means patch bumps must be read, not absorbed.
  • Do not deploy 2.3.0 or below in any environment where new jobs are added alongside a release.
  • Verify the symfony/* constraint ranges against Laravel's own pins before anything else — most likely install-time failure point.
  • Confirm whether 2.3.1 is a breaking change in disguise (state schema or key derivation). A "fix" that alters job identity would silently re-baseline every existing job — check the changelog and any migration notes.

Sequencing

  1. Source and changelog read, including 2.3.0 → 2.3.1 diff (½ day).
  2. State-store design review + install spike (1–2 days).
  3. Deploy-semantics test matrix against 2.3.1 (1 day, can run parallel to 3).
  4. Isolation layer + bridge (1–2 days).
  5. Parallel run (one sprint).
  6. Cutover or discard.

Decision checkpoint after step 2. If the state store cannot be made shared and multi-node-safe, stop. That is now the gating question, ahead of the capability question.

Operational Impact

Maintenance

  • We remain the de facto maintainer for compatibility purposes, but 2.3.1 justifies softening this from "assume zero upstream responsiveness" to "unproven, has shipped at least one production-driven fix." Budget stays ~2–4 engineer-days per year for PHP/framework bump compatibility.
  • New standing cost: the state store. It needs a schema, migrations, pruning, backup coverage, and reconciliation if it diverges from reality. Budget a further 2–3 days per year.
  • Patch-level pinning means every upstream patch is a small review task, not a no-op.

Support

  • No community, no corpus, no tutorials. Knowledge concentrates in whoever runs the spike.
  • The 2.3.1 changelog is a useful artefact — it is now the only known-behaviour document and should be captured in our runbook verbatim, because the bug it fixes will recur in any fork we take.

Scaling

  • Control-plane, scales with job count and instance count, not traffic. The multi-node question is now sharper: a shared state store is required for exactly-once, and the package's own deploy fix is evidence it has been exercised at more than one instance — but that is inference, not confirmation.
  • Confirm whether job execution is protected by a distributed lock (withoutOverlapping / onOneServer equivalents). If not, a shared state store prevents scheduling duplicates but not execution overlaps on slow jobs.

Failure modes (revised)

  • Deploy-time misfire / duplicate side effects — the bug 2.3.1 fixes. For us the risk is now inverted: the upstream fix exists, so the failure mode is running an older pin or a fork that predates the fix. Assert 2.3.1 minimum in any environment.
  • State-store divergence between nodes → duplicate execution, missed execution, or jobs that never establish a baseline. New, and the most likely operational incident with this package.
  • Unbounded backfill after an outage — mass simultaneous job firing, the mirror image of the misfire bug.
  • Silent non-execution — unchanged; mitigate with a heartbeat on the scheduler itself.
  • Duplicate execution / overlap storms absent a distributed lock — unchanged.
  • Command injection via unescaped arguments — unchanged, unaudited.
  • Composer conflict blocking a framework upgrade — slightly increased likelihood given four minors of constraint drift.
  • Abandonware drift — unchanged.

Ramp-up

  • Unchanged at 1–2 days for a Symfony-fluent engineer, plus ~1 additional day to understand the state model and first-run semantics, which are now the non-obvious part of the system.
  • Laravel-only team: add 2–3 days for Symfony bundle/container idioms.
  • Runbook must be authored by us; 2.3.1's behaviour should be documented as a known-issue class, not just a fixed bug.

Recommendation summary

Unchanged in direction, sharpened in condition. Do not adopt as a Laravel dependency by default. The release adds one credible reason to reconsider — persisted-state catch-up scheduling, if we have a business requirement for missed-run backfill — and one new gating question — whether the state store is multi-node-safe. Run a bounded spike only if both the backfill requirement and a shared-state answer are satisfied; otherwise keep treating the repository as a design reference, port the state/keying model under our own tests, and stay off the dependency. Any adoption must pin ≥ 2.3.1 and ship with a deploy-semantics test matrix covering new, renamed, and removed jobs across multiple instances.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style