whiteoctober/swiftmailerdbbundle
A Symfony bundle that stores SwiftMailer's spooled emails in a database table instead of memory or files. Queued messages survive restarts and can be sent by cron or workers across multiple servers, delivering reliably without losing mail when a process crashes.
Architecture fit. The package is a Symfony bundle, not a framework-agnostic library. It contributes a DI extension, a service definition, and a Doctrine-backed implementation of Swift_Spool (queueMessage, flushQueue, isStarted, start, stop) that persists serialized Swift_Message payloads in a table rather than the filesystem or memory. For a Laravel codebase this is a structural mismatch: Laravel has no bundle/compiler-pass concept, and its mail layer (Illuminate\Mail) is built on Symfony Mailer since 9.x, not SwiftMailer. The pattern — durable, transactional, DB-backed mail spooling — is directly applicable to Laravel; the artifact is not.
Integration feasibility. Low as-is, moderate as a reference design. Adopting the package requires: (1) still running SwiftMailer, which reached end of life in November 2021; (2) a Symfony 2.x/3.x-era container and directory structure; (3) a Doctrine connection and schema migration for the spool table; (4) a cron/worker to invoke flushQueue. In a Laravel app, none of these hold. The realistic use is reading the ~200 lines of spool logic to design a native MailSpool model + queued job.
Technical risk.
Swift_Message objects into modern runtimes is fragile; deprecations are likely and hard failures plausible.Key questions.
queue + Mail::queue already covers the first two.Verdict. Score 2.11 with zero dependents is the correct signal: do not adopt. Treat as a design reference only.
Stack fit. Poor for Laravel. This bundle expects Symfony's kernel, services.xml/DI extension conventions, and Doctrine ORM entity mapping — none of which Laravel consumes. Laravel's nearest equivalents already exist and are maintained: Mail::queue() / ShouldQueue for off-process delivery, database queue driver for durability, and symfony/mailer transports underneath. The bundle's distinguishing feature — DB-backed spool as a transport decorator rather than a queue — is a genuinely useful pattern (it decouples "message accepted" from "SMTP succeeded" inside the same DB transaction as the business write), but it is reproducible in Laravel in roughly a model, a migration, a Mailable hook, and a scheduled command.
Migration path. Two viable routes:
mail_spool table (id, mime blob or JSON, recipient, attempts, available_at, created_at, sent_at, last_error). Wrap the mailer so send() persists instead of dispatching. Add a spool:flush command under the scheduler with backoff and a spool:prune retention job. One to two days, fully owned, no EOL dependency.There is no credible path where this package is installed into a Laravel application and used as shipped.
Compatibility. PHP 5.6/7.x era; Symfony 2.3–3.x bundle conventions; SwiftMailer 5.x/6.x. Incompatible with PHP 8.1+, Symfony 6+, and Laravel 9+ mail internals. Composer resolution against a modern Laravel composer.json will conflict on swiftmailer/swiftmailer (^6.0 is abandoned and blocked by Symfony Mailer coexistence in most setups).
Sequencing (Route A).
Maintenance. Owned entirely by us if forked; zero upstream maintenance if not. The bundle's logic is small enough to reimplement, which is almost always the cheaper long-term trade. Budget a dependency-review ticket to formally reject it so it doesn't resurface in future proposals.
Support. Nonexistent. No security advisories will be issued for this package; the underlying swiftmailer/swiftmailer is already flagged abandoned by Composer and will only accumulate CVEs that we cannot patch. Any incident on this path is self-supported from minute zero.
Scaling. The spool table becomes a hot, write-heavy table with unbounded growth if pruning is not automated. Practical concerns: index on (sent_at, available_at) for the flush query; batch flushQueue with a bounded limit per invocation to avoid long transactions; aggressive retention (24–72 hours is typical) to keep the table from dominating backup size and replication lag; avoid storing large attachments inline — store a reference instead. Under high volume, the flush worker becomes a single-consumer bottleneck and needs horizontal partitioning or sharding by available_at. None of this is provided by the package; all of it is our build.
Failure modes.
Ramp-up. For a team already fluent in Laravel mail and queues, the native reimplementation is a low-ceremony task — the conceptual overhead is in retry/idempotency semantics, not code. For a team inheriting the original Symfony bundle, ramp-up is dominated by archaeology: reconstructing pinned PHP/Symfony/SwiftMailer constraints, verifying the spool table migration, and confirming the flush cron exists in production. Assume that work is a week, not a day, because there is no documentation and no maintainer to ask.
Bottom line. The concept is worth borrowing; the package is not worth depending on. Adopt the pattern, reject the artifact.
How can I help you explore Laravel packages today?