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

Laravel Prunekeeper Laravel Package

helgesverre/laravel-prunekeeper

PruneKeeper gives Laravel apps a central home for model pruning: define retention rules, schedule prune commands, and track what gets cleaned up so your database stays lean without scattered ad-hoc cleanup scripts or guesswork.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit laravel-prunekeeper targets a gap most Laravel apps handle with bespoke commands: exporting records to a compressed archive before deleting them, so "pruning" is auditable rather than destructive-by-default. v2.0.0's move to static methods aligned with first-party package conventions (e.g. Prunekeeper::makePrunableQuery(), Prunekeeper::flushState()) makes it feel native to the framework, and the --compression CLI flag plus prunekeeper.compression.driver config gives both ops-time and deploy-time control. It fits cleanly alongside the scheduler and queue infrastructure the team already runs.

Integration feasibility Composer install plus config publish is a low-ceremony integration. The real feasibility question is the PHP extension matrix: zip (default) needs ext-zip, gzip needs ext-zlib, bzip2 needs ext-bz2, and targz needs ext-phar and ext-zlib. That must be validated against local dev, CI containers, and production base images before we commit to a driver. Soft-delete support via makePrunableQuery() is a good sign the package anticipates real Eloquent patterns rather than assuming hard-deleted tables.

Technical risk

  • Destructive by nature. The package deletes data. The blast radius of a misconfigured cutoff date or a missing where clause is total. Dry-run behavior, row-count reporting, and export-before-delete ordering must be confirmed, not assumed.
  • Breaking changes vs. pre-2.0. The static-method refactor and the config-callback return change (void instead of $this, which breaks fluent chaining) will break any early adopter on a 0.x/1.x release. No risk for greenfield adoption.
  • Static state. flushState() exists specifically because the package holds static state. That is a leak vector in Octane, queue workers, and test suites if not called at the right boundaries.
  • Immature ecosystem. v2.0.0 is the first stable release, so we are early. Single-maintainer OSS dependency on a data-deletion path is a concentration risk.

Key questions

  1. Is export strictly ordered before delete, and what happens if the process dies between the two steps — duplicate archives on the next run, or orphaned rows?
  2. Are exports streamed/chunked, or built in memory? What is the behavior on a 50M-row table?
  3. Where do archives land (local disk, Flysystem/S3), and can that be configured? What is the temp-file lifecycle on success vs. failure?
  4. Is there a --dry-run, and does it report matched row counts?
  5. Does it guard against concurrent runs, or do we own withoutOverlapping() / onOneServer() in the scheduler?
  6. Are archives encrypted, and do they inherit PII from the source table? What is the retention policy for the archives themselves?
  7. Which Laravel/PHP versions are supported, and what is the maintainer's release cadence commitment post-2.0.0?

Integration Approach

Stack fit Standard Laravel: config file, artisan command, Eloquent query builder, scheduler. No new infrastructure required beyond a writable archive destination and the chosen compression extension. The --compression flag lets us differ per environment (e.g. zip where ext-zip is universal, targz in containers where ext-phar is bundled with PHP).

Migration path

  • Greenfield: install ^2.0, publish config, pin the version, no migration needed.
  • From a pre-2.0 pre-release: expect to rewrite fluent config callbacks (they now return void) and any instance-based calls to the static API. Budget a small refactor plus a full test pass; treat it as a major-version upgrade, not a patch.
  • No data migration is required — the package operates on existing tables.

Compatibility

  • Verify the extension matrix in each environment before choosing a driver; default to zip as the lowest-common-denominator.
  • Confirm soft-deleted models are pruned intentionally (or excluded via makePrunableQuery() scoping) — this is a policy decision, not a technical default.
  • Confirm behavior on tables with foreign keys and on replicated databases (delete load, replica lag).

Sequencing

  1. Spike (1–2 days): install in a dev branch, run against a seeded dataset, confirm dry-run, archive contents, and temp-file cleanup on induced failure.
  2. Index prep: ensure the prune-date column is indexed before any production run; this is the single biggest determinant of whether pruning is a 30-second job or a 3-hour table lock.
  3. Staging soak: schedule the command in staging for at least one full cycle, capture row counts, runtime, archive sizes, and peak memory.
  4. Production shadow mode: run with deletion disabled (or a zero-match cutoff) for one cycle to validate the query plan and timing.
  5. Enable with a conservative cutoff, then widen. Start with one low-risk table, not the highest-volume one.

Operational Impact

Maintenance Low surface area but non-zero: pinned composer constraint, a changelog watch (the package just demonstrated it will make breaking changes at major versions), and PHP extension upkeep in base images. Archives accumulate, so a retention/rotation policy for the archive destination is a standing operational duty we own, not the package.

Support Community OSS, single maintainer, first stable release. Escalation path is GitHub issues. For a component on the data-deletion path, we should have an internal fallback: the ability to disable the schedule and prune manually with a one-off script if the package regresses. Recommend pinning to 2.0.* and reviewing 2.1+ before adopting.

Scaling

  • Runtime scales with rows matched, not table size, provided the cutoff column is indexed.
  • Delete load competes with application traffic; schedule in the lowest-traffic window and consider chunked/batched deletion to avoid long transactions and lock escalation.
  • Archive storage grows linearly with pruned volume; bzip2 gives the best ratio at the highest CPU cost, gzip/targz are the pragmatic middle, zip is fastest and most portable.
  • Multi-node deployments need onOneServer() or an equivalent lock to prevent duplicate concurrent pruning.

Failure modes

Failure Expected behavior Mitigation
Export fails Delete should not proceed (safe) Verify ordering; alert on command failure
Delete fails after export Rows remain; next run re-exports duplicates Idempotency check; dedupe on archive name/hash
Temp disk exhausted Export aborts; temp cleanup added in 2.0.0 Monitor temp volume; size based on staging soak
OOM on large tables Command dies mid-run Confirm streaming; cap batch size; alert on memory
Static state leakage (Octane/queues) Stale config/state across requests Call flushState() at job/request boundaries
Missing PHP extension Driver unavailable at runtime Fail fast at boot; CI check on extension matrix

Ramp-up Engineering ramp-up is genuinely low — a Laravel developer can read the config and command in under an hour. The real cost is data governance, not code: agreeing retention windows per table, who approves a cutoff change, where archives live, how long they're kept, and whether they contain PII. Budget most of the adoption effort there. Recommend a named owner for the prune schedule and a documented rollback (disable schedule + restore from archive) before the first production deletion.

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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource