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

Doctrine Retry Bundle Laravel Package

keboola/doctrine-retry-bundle

A Symfony bundle that adds configurable retry logic to Doctrine DBAL connections, helping applications recover from transient database failures and improve resilience with minimal configuration.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Reliability hardening vs. new features. The package exists to convert a class of transient database-connection failures (failover blips, container cold starts, network resets during deploys) into automatic retries instead of 5xx responses and crashed workers. It is a candidate line item for a hardening/stability sprint, not for a feature roadmap.
  • Build vs. buy vs. solve-in-infra. The entire surface is roughly four classes: a DBAL driver middleware, a driver subclass overriding connect(), a keboola/retry proxy, and a compiler pass. The real build-vs-buy question is therefore "vendor/fork 200 lines" vs. "write it ourselves" vs. "push it to the proxy/connection pooler/load balancer." Decide this before committing engineering time.
  • Scoping what reliability we actually promise. Retry is applied only to connect(), deliberately — queries are never replayed, because replaying a statement after a mid-transaction failure is unsafe. This is a feature decision with product consequences: you can credibly promise resilience to connection-establishment failures and you must explicitly not promise resilience to deadlocks, mid-transaction drops, or read-replica flakiness.
  • Opt-in blast radius via configuration. Retry is enabled per connection through driverOptions.x_connect_retries, with a compile-time pass that skips connections where the option is absent or 0. That supports a graduated rollout: one non-critical connection first, then broaden — and supports heterogeneous fleets where some connections should never retry.
  • Roadmap coupling with platform upgrades — now a two-step dependency, not one. 1.2.0 raises the floor to PHP ^8.4, doctrine/dbal ^4.2, doctrine/doctrine-bundle ^3.0, and Symfony ^7.4|^8.0. Adoption is bundled into a framework/runtime upgrade and a DoctrineBundle major upgrade; the release exists precisely to unblock Symfony 8 consumers that doctrine-bundle 2.x was pinning via symfony/var-exporter. Sequence it as part of that upgrade train, not as an isolated dependency add.
  • Upgrade-window decision for existing consumers. If we are already on an earlier version, 1.2.0 is a breaking release: it drops Symfony 6.4 / doctrine-bundle 2.x support outright. That means our Symfony 6.4 services are frozen on 1.1.x and will accumulate drift; decide now whether they get an upgrade path or a deprecation date.
  • Concrete use cases worth prototyping on: queue/worker boot storms against a saturated DB, blue-green or DNS cutover windows, managed-database failover, Kubernetes cold starts, and per-connection routing where a replica endpoint is occasionally unavailable.

When to Consider This Package

Consider it when all of the following hold:

  • The application is Symfony with DoctrineBundle (the compiler pass rewrites the DBAL Configuration::setMiddlewares() call, which only exists in that stack).
  • You are on, or are about to move to, PHP 8.4 / DBAL 4.2+ / doctrine/doctrine-bundle 3.x / Symfony 7.4–8.x. 1.2.0 hardened this: doctrine-bundle 2.x is no longer installable with it.
  • You have evidence that failures originate at connection establishment, not query execution.
  • You are willing to own the code — the GitHub repo is a read-only mirror force-pushed from the keboola/platform-libraries monorepo; PRs to the mirror are closed. Any fix means forking or working in someone else's monorepo.
  • You can run fault injection in CI (the project uses MySQL behind Toxiproxy to exercise the retry path). Without that, you cannot verify the behavior you are buying — and 1.2.0 makes this more important, not less (see below).

Look elsewhere when:

  • Your stack is Laravel. This is not a Laravel package — Laravel's Illuminate\Database layer has no DoctrineBundle and no compiler pass, and nothing in 1.2.0 changes that. The equivalent capability has to come from Laravel's own reconnect configuration or a hand-written PDO/connector wrapper. Do not let the "PHP package" framing pull this into a Laravel backlog.
  • You need query-level retry. This package intentionally does not do it; a solution that does is a different risk profile entirely.
  • You need vendor support, a security review trail, or broad social proof. Still zero stars and zero public dependents, single-organization maintenance, mirror-only repo. The one new signal in 1.2.0 is that the release was driven by a named internal consumer ("the editor service") — that is evidence the package is live and maintained upstream, not evidence of an external community or a support contract.
  • Infrastructure can absorb the problem more cheaply — proxy-level retries, PgBouncer/connection pooling, proper startup/readiness probes, or DNS/endpoint stabilization.
  • You are pinned below PHP 8.4, on DBAL 3 / Symfony 6.4, or on doctrine-bundle 2.x; 1.2.0 explicitly will not accept you, and the constraints are inherited from the upstream monorepo and will not be relaxed for us.

One risk that 1.2.0 raises rather than resolves: the compiler pass removes and re-adds an existing setMiddlewares() call from DoctrineBundle, and if DoctrineBundle changes how it registers middlewares, this bundle's behavior is silently dropped rather than erroring. We are now being asked to take a major DoctrineBundle bump (2.x → 3.x) at the same time as this package's release. That is exactly the change class most likely to break the pass silently. Adopt only with a regression test in our own suite that asserts retry actually fires (a Toxiproxy-style fault injection mirroring the project's ConnectionWithRetryTest), and re-run it as a gate on every DoctrineBundle upgrade.

How to Pitch It (Stakeholders)

To executives: This is a small, MIT-licensed reliability component that lets a database connection failure during a deploy, failover, or cold start be retried automatically instead of surfacing as an error to users. It is roughly four classes of code, so audit and maintenance cost are low, and it is opt-in per database connection — we can enable it for one connection and measure before widening. The 1.2.0 release is a compatibility release: it lifts the floor to Symfony 7.4+/8.x and DoctrineBundle 3.x, drops Symfony 6.4/DoctrineBundle 2.x, and was cut to unblock a named internal service upstream, which tells us the project is actively maintained rather than abandoned. Two honest caveats remain: it has effectively zero public adoption (no stars, no downstream dependents) and it is maintained as a read-only mirror of another organization's monorepo, so we would be adopting, not partnering. Recommendation is a timeboxed spike, not a commitment — and any Symfony 6.4 services should get an explicit upgrade-or-deprecate decision, since they are now frozen on 1.1.x.

To engineering: Four classes; the interesting part is the compiler pass, not the retry. It prepends a per-connection driver middleware so the retry wrapper is outermost and sees failures from every other middleware, and it only wraps connect() — queries are never replayed, by design. Requires PHP 8.4 / DBAL 4.2 / doctrine-bundle ^3.0 / Symfony 7.4+. Zero-config once driverOptions.x_connect_retries is set. What changed in 1.2.0: dependency bumps only — doctrine-bundle ^3.0, Symfony components ^8.0|^7.4, no API or behavior changes to the four classes. It is breaking for consumers because the minimums moved (Symfony 6.4 / doctrine-bundle 2.x are out), and it exists to unblock Symfony 8 consumers that doctrine-bundle 2.x was holding back via symfony/var-exporter 8.x. Fragility to flag harder than before: the pass rewrites DoctrineBundle's setMiddlewares() registration, and we are now crossing a DoctrineBundle major version at the same time — the failure mode is silent disablement, not an exception. Gate the upgrade on our own Toxiproxy fault-injection test mirroring ConnectionWithRetryTest. Also note this is a Symfony bundle; nothing here transfers to our Laravel services, and 1.2.0 does not change that.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource