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 Db Snapshots Laravel Package

spatie/laravel-db-snapshots

Spatie's Laravel package adding Artisan commands to instantly dump and load MySQL, PostgreSQL, or SQLite databases. Create named snapshots, load the latest, list, and clean up old dumps in seconds.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

The package is a thin Laravel-native wrapper: it registers a service provider, exposes six Artisan commands (snapshot:create, :load, :list, :delete, :cleanup, plus --latest/--table/--exclude/--compress/--stream/--drop-tables flags), and delegates the actual work to spatie/db-dumper, which in turn shells out to mysqldump, pg_dump, or sqlite3. That delegation is the single most important architectural fact. This is not a backup engine — it is a developer-experience facade over vendor CLI tools, with Laravel's filesystem abstraction layered on for storage and Laravel's config/database.php used as the credential source.

The fit is therefore narrow and specific: it is an excellent fit for developer and CI workflows (seeding local/staging environments from a known dump, resetting a test database between suites, snapshot-before-migration safety nets, handing a reproducible dataset to QA) and a poor primary fit for production disaster recovery, where you need point-in-time recovery, integrity verification, encryption, cross-region replication, and a restore SLA. Treating it as a DR solution is the most likely way a team misadopts this package. It is architecturally a sibling of django-dbbackup or a bin/dump shell script — not of RDS automated backups or pgBackRest.

Integration feasibility

Low friction on the happy path: composer require spatie/laravel-db-snapshots, add a snapshots disk to config/filesystems.php, optionally publish the config. Everything is driven by Artisan, so it slots into existing deployment scripts, Composer scripts, Pest/PHPUnit setUp, and Laravel's scheduler with no glue code. The event surface (CreatingSnapshot, CreatedSnapshot, LoadingSnapshot, LoadedSnapshot, DeletingSnapshot, DeletedSnapshot) is the main extension seam and is sufficient for audit logging and Slack/observability hooks without forking.

The real integration cost is environmental, not code: the target host must have the matching DB client binaries installed and on PATH, plus a writable temporary_directory_path. This is trivial on a developer laptop or a standard VM-based CI runner and non-trivial in distroless containers, Laravel Vapor/Lambda, or locked-down PaaS buildpacks. Any integration plan must resolve "where do the binaries come from" before writing a line of config.

Technical risk

  • Client/server binary version skew. mysqldump and pg_dump must generally be at or above the server major version. Container base images drift; managed database engines auto-upgrade. This is the highest-probability silent failure.
  • Destructive default. snapshot:load drops all tables unless --drop-tables=0 is passed. A mistyped connection name can wipe the wrong database. This is the highest-severity risk and needs guardrails (environment checks, APP_ENV gating, confirmation prompts in wrapper commands).
  • Non-transactional restore. Loads are not atomic; a failed or interrupted load leaves a partially restored database. There is no checksum/verification step on the dump artifact.
  • Memory and timeout. Default non-streamed loads read the whole dump into memory; --stream mitigates this but the changelog shows recent fixes (2.9.0) for chunk-boundary and continued-line parsing bugs, which signals the streaming path is newer and less battle-tested.
  • Data-at-rest exposure. Dumps are plain SQL (or gzip, which is not encryption) sitting on a disk. If that disk is database_path('snapshots') — the documented default — the files live inside the deploy directory, are commonly ephemeral in containers, and are one missing .gitignore entry away from being committed. PII in a .sql file on local disk is a compliance finding waiting to happen.
  • Credential handling. Credentials come from config/database.php, so whatever privilege the app's DB user has, the dump has. There is no separate backup role, no read-replica targeting, and no IAM/Cloud SQL connector story documented beyond the connect_via_database support added in 2.5.0.
  • Metadata anomaly. The stated last release (2026-10-19) is future-dated and "Dependents: 0" understates real usage; verify against Packagist before relying on either signal for a maturity argument.

Key questions

  1. Is the intended use case developer/CI environment seeding or production data protection? The answer changes the recommendation entirely.
  2. What is the required RPO/RTO, and does it exceed what a scheduled full dump can deliver?
  3. Does the runtime environment allow installing mysqldump/pg_dump/sqlite3, or is it serverless/distroless?
  4. Where will snapshots physically live, and does that location satisfy data-residency and encryption-at-rest policy for the data they contain?
  5. What is the largest database we must handle, and does --stream hold up at that size?
  6. Do we already own a DBA-grade backup platform? If so, this package's correct role is complementary (dev seeding), not competitive.
  7. Who is authorized to run snapshot:load against a shared or production-like database, and how is that enforced?

Integration Approach

Stack fit

Strong fit for standard Laravel monoliths on VM/container infrastructure running MySQL, MariaDB, PostgreSQL, or SQLite — all four are supported, with MariaDB support added in 2.6.1. Weak fit for serverless Laravel (Vapor) and for polyglot estates where non-PHP services also need the data, since everything here is only reachable through Artisan. If the org is Laravel-standardized on current versions, fit is effectively native.

Migration path

Adopt incrementally rather than as a replacement. Phase one: install as a developer convenience only, on local and CI environments, with the snapshots disk pointed at storage_path() rather than database_path() and added to .gitignore. This delivers the productivity win with zero production blast radius. Phase two: add a scheduled snapshot:create --compress job in staging with snapshot:cleanup --keep=N chained after it, giving a lightweight "restore staging to yesterday morning" capability. Phase three — only if a genuine gap is confirmed — extend to production, and only via a wrapper command that enforces environment checks, uses a dedicated low-privilege backup connection configured under default_connection, writes to a remote Flysystem disk with server-side encryption, and fires CreatedSnapshot into the existing monitoring pipeline. Do not decommission any incumbent backup tooling on the strength of this package.

Compatibility

Actively maintained across Laravel majors through 13 (per changelog 2.8.0/2.7.1/2.6.0), PHP 8.x on v2, PHP 7.x/Laravel 6.x requires pinning v1.x. Pin the major version in composer.json and track the spatie/db-dumper constraint (v4 allowed as of 2.10.0), because dumper upgrades can change CLI flag behavior. The dump.addExtraOption connection key (e.g. --no-owner for Postgres) is the escape hatch for engine-specific quirks and should be documented as the sanctioned customization point rather than patching the package.

Sequencing

  1. Environment validation spike: confirm binaries, versions, temp-dir writability, and dump size/time on a realistic copy of the largest database. This is the go/no-go gate.
  2. Local + CI rollout with the .gitignore and disk-path fixes.
  3. Observability wiring via events; storage lifecycle policy defined (retention count, disk capacity, encryption).
  4. Staging scheduled snapshots with a rehearsed restore, timed and documented.
  5. Production evaluation memo — go/no-go against the DR requirements gathered in the questions above, with an explicit statement that this is a supplement, not a substitute, for platform backups.

Operational Impact

Maintenance

Ongoing cost is low but not zero. The package itself is small and stable; the maintenance burden is concentrated in the environment (client binary versions tracking server upgrades) and in the storage lifecycle (unbounded dump accumulation is the classic failure — snapshot:cleanup --keep=N exists but is opt-in and must be scheduled, not assumed). Budget a recurring check that CI base images ship a pg_dump/mysqldump at or above the managed database's major version; that one check prevents most incidents.

Support

MIT-licensed, Spatie-maintained, high-reputation vendor with a broad package portfolio and an active changelog (recent releases include Laravel 13 support and two correctness fixes to streamed loading). Documentation is a README and CHANGELOG — good for the happy path, thin on troubleshooting. There is no commercial SLA. Support burden therefore falls internally: name an owner, write a runbook covering "restore staging from snapshot," and document the --stream/--drop-tables flags prominently. Because the package is a thin wrapper, most "package bugs" will actually be binary-version or permissions issues — the runbook should route there first.

Scaling

Scales acceptably with data volume up to the point where full-dump duration and storage exceed the maintenance window and disk budget; --compress and --stream extend that range but do not eliminate it. Does not scale as a many-database fleet management tool — there is no inventory, no parallel orchestration, no central catalog across applications. Per-app scheduling via Laravel's scheduler is fine for a handful of apps, not for dozens. Storage scaling is a matter of the configured Flysystem disk; S3-backed snapshots work but restore latency becomes network-bound.

Failure modes

Ranked by expected pain: (1) silent partial restore after an interrupted load — no atomicity, so verify row counts post-restore; (2) accidental drop of the wrong database via a misdirected --connection combined with the default --drop-tables behavior; (3) binary version mismatch producing a dump that fails to load or, worse, loads incompletely; (4) OOM/timeout on large unstreamed loads; (5) disk exhaustion from unscheduled cleanup; (6) snapshot files left inside the deploy directory and lost on redeploy, or committed to version control; (7) plaintext PII exposure on the snapshots disk. Each maps to a specific control: post-restore verification, environment gating, image-pinned client versions, --stream as default, scheduled cleanup, explicit disk path + .gitignore, and encryption/lifecycle policy on the target disk.

Ramp-up

Very fast for engineers already fluent in Artisan — the commands are self-documenting and the README is five minutes of reading. Expect near-zero ramp-up for the create/list/load loop and roughly a day of institutional learning for the sharp edges (drop semantics, streaming, binary dependencies, storage hygiene). The larger ramp-up cost is organizational, not technical: getting the team to agree on what this tool is for so it is not mistaken for a backup-of-record, and establishing the guardrails that keep a destructive load command out of unauthorized hands. That framing conversation is the TPM's actual deliverable here.

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.
thuraaung2493/laravel-rulecraft
cyberwizard/schedule-catchup
livetennisapi/livetennisapi-laravel
roundly-consulting/notifications-for-laravel
flightsadmin/bootstrap-starter-kit
lasserafn/laravel-intempus
likyly/sdk
tdt/input
coreation/php-shapefile
coreation/gisconverter
primix/widgets
primix/notifications
primix/actions
primix/tables
primix/details
primix/forms
primix/support
marcelgwerder/laravel-api-handler
firebrikdotcom/conveyor-laravel-broadcaster
kanata-php/conveyor-laravel-broadcaster