upscale/swoole-blackfire
Integrates Blackfire profiling with Swoole workers, enabling per-request profiling in long-running Laravel Octane applications. Helps Blackfire traces work correctly across persistent PHP workers instead of only the initial request.
Architecture fit. The package is a narrow, single-purpose shim that bridges two technologies with fundamentally incompatible execution models. Swoole (and OpenSwoole) run PHP in long-lived worker processes with a coroutine-per-request model; Blackfire's PHP extension was designed for process-per-request SAPIs (FPM/Apache/CLI) where the profiler instruments one request per process lifetime. upscale/swoole-blackfire reconciles this by hooking Swoole's request lifecycle and toggling Blackfire's probe API (blackfire_probe_enable/disable/set) around each request, rather than relying on auto-instrumentation. Architecturally that is the correct approach — but it is a very thin layer over two extensions whose internal contracts it does not control.
Integration feasibility. Low mechanical effort, non-trivial validation effort. It is Composer-installable with a small API surface, but it is effectively a reference implementation: 22 stars and 0 dependents means no evidence of production use at any scale, and the meaningful work is proving profile correctness rather than wiring it up.
Technical risk (ranked).
| Risk | Severity | Notes |
|---|---|---|
| Coroutine concurrency vs. probe global state | High | Blackfire probe is process-global, not coroutine-scoped. If a worker interleaves requests (common under Swoole coroutines / Octane concurrency), enabling the probe for one request will capture others — blended, misattributed profiles. Must confirm whether the package forces serialization or only supports concurrency=1. |
| Probe not disabled on all exit paths | High | Exceptions, timeouts, fatal errors, or Swoole\ExitException paths that bypass cleanup leave the worker profiling every subsequent request — overhead blowup and unintended data export. |
| Extension/version coupling | Medium-High | Depends on ext-swoole (4.x vs 5.x vs OpenSwoole fork) and a Blackfire PHP extension new enough to expose the probe API. No graceful degradation on mismatch — typically a boot-time fatal. |
| Security / data governance | Medium-High | Profiles traverse the full request path and may capture arguments and env. Triggering must be authenticated and impossible in production unless explicitly armed. |
| Maintenance bus factor | Medium | Single-maintainer, low-activity repo. Apache-2.0 permits vendoring, which materially reduces this risk. |
Key questions to answer before committing.
ext-swoole / OpenSwoole and the Blackfire extension, and is Swoole 5 supported?X-Blackfire-Query header, env var, or programmatic? Where is the authorization check?onRequest, or also task workers, WebSocket/HTTP2 handlers, and Octane's RequestContext?Stack fit. Only relevant if the target stack already runs Swoole or OpenSwoole as the HTTP server: Laravel Octane (swoole/openswoole), Hyperf, or a bespoke Swoole HTTP server. For a conventional FPM stack this package has zero value. For an Octane stack, verify it hooks beneath Octane's own onRequest wiring rather than competing with it — the cleanest integration is usually to wrap Octane's request callback in the package's decorator, not to reconfigure the server.
Migration path. Treat it as development and pre-production tooling first, and possibly forever:
require-dev on a branch; keep it out of the production composer.lock until profiled-request attribution is proven.worker_num pinned low and concurrency set to 1 to eliminate the coroutine-interleaving risk during evaluation.Compatibility checklist. PHP minor version; Swoole vs OpenSwoole fork (naming and API differ); Blackfire extension version exposing the probe API; Blackfire Agent reachability and whether it is SaaS or self-hosted (data residency); Octane version and its request-lifecycle hooks.
Sequencing.
Maintenance. Low code churn but zero maintenance guarantee — plan for the realistic outcome that you fork it. It is small enough that vendoring and owning it is a credible alternative to depending on it; a senior PHP infrastructure engineer can reimplement the equivalent (probe enable/disable, transaction naming, trigger parsing) in a few hundred lines. Frame the build-vs-buy decision accordingly: this package is best used as a reference implementation and a two-week evaluation shortcut, not as a long-lived dependency.
Support. Community-only. Blackfire (Platform.sh) supports the agent and the PHP extension, not this glue; Swoole/OpenSwoole maintainers do not support Blackfire. Any incident lands on your platform team. Document that explicitly before adoption.
Scaling. Profiling must never be always-on. Budget for on-demand or sampled profiling, ideally pinned to a small canary pool. Watch for: memory growth in long-lived workers holding probe buffers, synchronous agent writes stalling the event loop (which stalls all concurrent requests on that worker), and profile volume/cost if using Blackfire's SaaS tiers.
Failure modes to design against.
max_requests).composer install is still a delivery risk; keep it in require-dev and out of CI's production build path.Ramp-up. Roughly 1–2 days for an engineer already fluent in both Swoole's worker lifecycle and Blackfire's probe semantics; 3–5 days otherwise, most of it spent on concurrency validation rather than integration. Add half a day of documentation so the team knows the tool exists, how to trigger it safely, and why profiles taken under concurrency may be unreliable.
Recommendation. Proceed only as a time-boxed evaluation against an existing Swoole/Octane footprint, with production exposure gated and the fork-and-own outcome priced in from the start. Do not adopt on an FPM stack, and do not adopt without first answering the coroutine-attribution question — that single answer determines whether this tool produces trustworthy data or plausible-looking noise.
How can I help you explore Laravel packages today?