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

Groundhog Laravel Package

boysfromthefactory/groundhog

Groundhog is a lightweight Laravel/PHP package from boysfromthefactory that simplifies recurring, repeatable work in your app. Drop it in, configure a few options, and keep repetitive logic clean, predictable, and easy to test. No extra dependencies.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • v0.2.0 is a fundamental architectural shift: recurrence occurrences move from write-time materialization (groundhog_occurrences table) to read-time expansion inside the database using JSON set-returning functions (json_each, JSON_TABLE, json_array_elements).
  • This removes the need for background materialization jobs, occurrence pruning, and sync logic — a simpler write path and fewer moving parts.
  • The model fits read-light or moderate-cardinality use cases (e.g., scheduling UIs, calendar views with bounded windows). It is a poorer fit for high-QPS list endpoints or high series cardinality, because expansion cost is paid on every query.
  • The package now pushes recurrence semantics into SQL, so correctness and performance become database-version-dependent. That is a meaningful coupling change for a TPM to own.

Integration feasibility

  • Upgrade path is explicit and small: publish groundhog-migrations, run php artisan migrate. The migration is idempotent and a no-op on fresh installs, which lowers first-install risk.
  • Breaking changes are real: the occurrence table and materialized_until column are dropped, and groundhog.max_materialization_ahead is removed. Any application code, reporting query, export, BI connection, or admin screen reading those directly will break.
  • The max_occurrences_per_series semantic change is subtle: it now bounds occurrences per series per query (in-window only), while the save-time check is unchanged. Existing configured values may need retuning.
  • Duration-only edits no longer rebuild anything; occurrence ends are computed on next query. This is likely desirable, but tests or consumers that expected materialized end times to update immediately should be reviewed.

Technical risk

  • Performance is the dominant risk. Published benchmarks: 1,000 daily series over a one-year window, 25-row page plus total, takes 4.8–7.4 s on SQLite, 7.0–7.9 s on MySQL 8.4, and 6.8–7.1 s on PostgreSQL 18. Cost grows with series × in-window occurrences on every query, including the total count.
  • Driver support is now an explicit runtime constraint: expanded queries throw RecurrenceNotSupported on drivers other than SQLite, MySQL, and PostgreSQL. Teams on MariaDB, SQL Server, or other Laravel-supported drivers lose the feature or need a fallback.
  • The removed read ceiling is replaced by a runtime ceiling: arbitrarily far windows are now possible but can produce unbounded query latency and large JSON parameters.
  • Large series counts risk database parameter/packet limits (e.g., MySQL max_allowed_packet) and statement timeouts.
  • Migration is destructive (drops table and column). Rollback requires restoring from backup or reverting the package and re-materializing, so a backup gate is mandatory.

Key questions

  • What is our production series cardinality, typical query window, and peak QPS for recurrence-backed views?
  • Which database driver and version are we on, and are all target environments within the tested set (MySQL 8.4, PostgreSQL 18, SQLite)?
  • Does any code, report, export, or BI tool read groundhog_occurrences or materialized_until directly?
  • What is the intended behavior when max_occurrences_per_series is hit — truncation, silent omission, or exception? This needs confirmation before relying on the bound.
  • Do we need caching, narrower default windows, or pagination limits to keep p95 latency acceptable?
  • What is the rollback/restore procedure and backup window for the migration?
  • Are there existing indexes supporting the series-selection predicates used before expansion?

Integration Approach

Stack fit

  • Laravel/Eloquent package; requires a database with JSON table functions. Confirm minimum versions: MySQL with JSON_TABLE (8.0.4+), PostgreSQL with json_array_elements, SQLite with JSON1 enabled.
  • Because this is a 0.x package, breaking changes are expected between minors; pin the version and treat upgrades as planned work rather than routine composer update fallout.

Migration path

  1. Audit the codebase and downstream consumers for references to groundhog_occurrences, materialized_until, and groundhog.max_materialization_ahead.
  2. Take a verified backup of any environment where the migration will run; the drop is destructive.
  3. Update the package constraint, then run php artisan vendor:publish --tag="groundhog-migrations" and php artisan migrate in staging against a production-like snapshot.
  4. Remove or update any jobs, commands, config keys, and documentation tied to materialization.
  5. Rehearse rollback: either restore the dropped objects from backup or revert the package and re-run the 0.1 migrations/materialization.

Compatibility

  • Fresh installs are low-risk: the migration is a no-op, and no occurrence table is created.
  • Upgrades from 0.1 are the risk surface: require the publish + migrate sequence, and block deployment if the migration has not run.
  • Driver compatibility must be validated per environment. If any environment runs an unsupported driver, gate the feature or plan a fallback before upgrading.
  • Confirm the package's supported Laravel/PHP matrix against our runtime; the release notes do not state it.

Sequencing

  1. Code and consumer audit.
  2. Staging upgrade and migration rehearsal with backup/restore validation.
  3. Benchmark with production-scale series counts and realistic windows, measuring p50/p95 for page plus total.
  4. Tune max_occurrences_per_series, default window sizes, and page limits; add caching or read-replica routing if latency is unacceptable.
  5. Production deploy with migration as a distinct, monitored step.
  6. Post-deploy validation of recurrence correctness (DST boundaries, duration-only edits, long windows) and latency dashboards.

Operational Impact

Maintenance

  • Net reduction in scheduled maintenance: no materialization cron, no occurrence pruning, no drift between stored and computed occurrences.
  • One-time cleanup burden: stale config keys, obsolete jobs, and documentation referencing the removed table and setting must be removed to avoid confusion.
  • Database-version upgrades become recurrence-correctness events, since expansion depends on JSON function behavior.

Support

  • New user-visible failure mode: RecurrenceNotSupported on unsupported drivers. Support and on-call runbooks need to recognize this exception and route it as a configuration/deployment issue, not a data issue.
  • Latency incidents will correlate with window size and series count rather than with job failures. Support needs guidance on which views/windows are expensive.
  • Fewer "stale occurrence" tickets; potentially more "slow calendar" tickets.

Scaling

  • Cost model changes from amortized write-time work to per-query CPU on the database, scaling with series × in-window occurrences. Page plus total roughly doubles the expansion work.
  • Mitigations: restrict default windows, cap page sizes, cache frequent views, route heavy reads to replicas, and add indexes for series-selection predicates.
  • Watch database resource limits: JSON parameter size, packet size, statement timeout, and connection pool pressure under concurrent wide-window queries.
  • High-cardinality tenants may need per-tenant window limits or a denormalized path for dashboard-style aggregates.

Failure modes

  • Slow query or timeout on wide windows or large series counts; may surface as 500s or empty calendars if not handled.
  • RecurrenceNotSupported on any non-SQLite/MySQL/PostgreSQL driver.
  • Parameter/packet limit errors when many series are expanded into one JSON payload.
  • Migration failure or partial state if run without the published migration; recovery requires backup restore because the drop is destructive.
  • Misconfigured max_occurrences_per_series silently changing result completeness (behavior on bound exceeded must be confirmed).
  • Duration-only edits now propagate at query time; consumers caching occurrence rows externally may serve stale ends.

Ramp-up

  • Engineering: understand read-time expansion, the cost model, and driver constraints; update tests that assumed materialized rows.
  • QA: add cases for long windows, large series counts, duration-only edits, and unsupported-driver behavior.
  • Ops/SRE: add latency monitoring for recurrence-backed endpoints, define alert thresholds, and document the migration rollback procedure.
  • Product/support: reset expectations that "far windows work" is a capability, not a performance guarantee; default UI windows should remain bounded.
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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums