silpo-tech/health-check-bundle
A health check bundle for Laravel apps that adds ready-made health endpoints and pluggable checks for database, cache, queue, disk and custom services, so uptime monitors and load balancers can confirm your application and its dependencies are up.
Architecture fit. This is a Symfony Framework bundle, not a Laravel package, and that distinction is the central finding. Bundles are a Symfony-specific packaging primitive: they rely on a Bundle subclass, kernel registration in config/bundles.php, service definitions in YAML/XML, compiler passes, and HttpKernel event subscribers. Laravel has no equivalent registration path — its extension points are service providers, facades, and route/middleware registration. The package will not autoload into a Laravel application in any supported way, and its value to a Laravel stack is as a reference design, not as a dependency.
Integration feasibility. The portable core of any health-check bundle is small and largely framework-agnostic: a CheckInterface with a name and a pass/fail result, a registry/aggregator, an HTTP controller returning a JSON payload, and probably an exit-code or status-word convention (ok/fail, HTTP 200/503). That core is typically a few hundred lines. A Laravel port is therefore feasible in days, not weeks — but it is a rewrite of the glue, and we would own it permanently. Three options exist: (1) adopt as-is — not viable on Laravel; (2) fork and re-implement the Laravel binding layer against the upstream check contract; (3) use it as a design reference and build against a maintained Laravel-native alternative (e.g. spatie/laravel-health) or a thin in-house endpoint. Option 3 is the default recommendation absent a compelling reason to mirror Silpo's specific semantics.
Technical risk. High, and mostly not about code quality. Signals: 0 stars, 0 dependents, single-vendor origin (a Ukrainian grocery retailer publishing an internal tool), no downstream adoption to surface breakage. Last release 2025-08-20 indicates it is at least currently touched, which is better than a dormant repo, but there is no evidence of a release cadence, deprecation policy, or external contributor base. Specific unknowns that could invalidate a port: which Symfony majors are supported (Symfony 5 vs 6/7 have meaningfully different service-definition and attribute conventions), PHP version floor, whether checks are pluggable via an interface or hardcoded, whether the endpoint distinguishes liveness from readiness, and whether output leaks environment details (DSNs, versions, hostnames) on what is usually an unauthenticated route.
Key questions for the maintainers (or the repo, if unresponsive).
composer.json, and is there a CI matrix?Stack fit. Zero direct fit for Laravel; near-perfect fit for a Symfony service. If any part of the estate is Symfony, this is a low-friction add: register the bundle, expose the route, point the orchestrator probe at it. If the estate is Laravel — as the framing implies — treat the package as a specification, not a dependency, and match its contract (route path, JSON shape, status codes) rather than its implementation.
Migration path. Whichever route we take, the durable artifact is the probe contract, not the library. Sequence: (1) freeze the JSON schema and status-code semantics our load balancer / Kubernetes / uptime monitor already consumes; (2) extract the check taxonomy (DB, cache, queue, storage, downstream HTTP) from this bundle's offerings; (3) implement those checks behind a Laravel service provider and a /health (readiness) plus /health/live (liveness) route pair; (4) only then consider whether upstream parity matters. If we instead fork, keep the upstream check interface signature byte-compatible so future upstream diffs can be cherry-picked.
Compatibility. Even setting aside the bundle registration problem, Composer resolution is a real hazard: a bundle will constrain symfony/framework-bundle, symfony/dependency-injection and symfony/http-kernel to specific majors. Laravel pulls a subset of Symfony components (console, http-foundation, http-kernel, routing, process), so some constraints will appear satisfiable while the bundle-registration machinery is absent — a false-positive install that fails at runtime rather than at composer require. Pin and test in a scratch branch before assuming resolution implies function.
Sequencing. Week 1: read the source, answer the key questions above, decide build-vs-port-vs-adopt. Week 2: if porting, build the check registry and the two endpoints behind a feature flag with the existing probe still authoritative. Week 3: shadow-run both endpoints, diff responses, confirm timeout behaviour under an injected slow dependency. Week 4: cut probes over, keep the old endpoint for one release cycle, then remove. If we adopt Symfony-native instead, collapse this to roughly a week.
Maintenance. This is the dominant cost. A fork means we carry the glue layer indefinitely, and every Symfony-side change upstream becomes a manual merge or a deliberate divergence. With 0 dependents there is no ecosystem pressure keeping the upstream honest; if Silpo's internal needs change, the public repo can go quiet without notice. Budget an explicit owner and a quarterly "is upstream still alive?" review. If we use it only as a design reference, maintenance cost drops to near zero and this concern evaporates.
Support. No vendor support, no community forum, no SLA. MIT means there is no obligation of any kind from the authors. Escalation path for a production bug is "we fix it ourselves" — acceptable for a health endpoint, which is usually simple, but it must be a conscious acceptance rather than a surprise during an incident.
Scaling. Health checks are trivially cheap per call but are called constantly and by multiple systems simultaneously (orchestrator liveness, readiness, load balancer, uptime monitor). The scaling risk is not CPU — it is fan-out. If each probe executes live DB, Redis, and downstream HTTP checks, a 2-second probe interval across 50 pods becomes thousands of dependency round-trips per minute, and the health endpoint starts contributing load to the very systems it is meant to observe. Mitigations to require in any implementation: short per-check timeouts, a cached/short-TTL result, cheap liveness that touches nothing external, and expensive readiness reserved for lower-frequency callers.
Failure modes. Three matter. (1) Dependency amplification: a hung downstream check causes the probe to time out, the orchestrator concludes the pod is unhealthy, and it restarts pods that were serving traffic fine — a partial outage converted into a full one. Per-check timeouts and a total-response deadline are non-negotiable. (2) Information disclosure: health endpoints are conventionally unauthenticated and reachable from outside the mesh; verbose check output can leak versions, hostnames, and connection strings. Restrict to internal networks and return opaque status words on the public path. (3) Silent false-green: a check that swallows exceptions and reports "ok" is worse than no check, because it suppresses the alerting that would have caught the real failure. Require explicit fail states and a test that proves a broken dependency turns the endpoint red.
Ramp-up. For a Symfony team: hours — register the bundle, read the check interface, add checks. For a Laravel team: the ramp-up is not learning this package, it is learning enough Symfony bundle internals to judge whether a port is faithful, followed by writing the Laravel binding. Estimate one to two days for a spike to reach a build-vs-port decision, roughly a week for a hardened, timeout-safe port with tests. The larger ramp-up cost is organisational: the team must absorb ownership of a component with no upstream safety net, and that ownership should be assigned before the first commit, not after the first incident.
How can I help you explore Laravel packages today?