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

Opentelemetry Propagation Server Timing Laravel Package

open-telemetry/opentelemetry-propagation-server-timing

Propagates OpenTelemetry trace context through the Server-Timing HTTP header, helping PHP applications correlate backend traces with browser and frontend requests for simpler debugging and performance analysis.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • The package is a response-side propagator, not a Laravel package. It emits the W3C Server-Timing response header so browser DevTools / RUM agents can correlate a client-side resource timing entry with the server-side trace that produced it. That makes it a correlation/UX layer on top of an existing OTel PHP deployment, not a tracing capability in its own right.
  • Fit is conditional: it delivers zero value unless open-telemetry/sdk + a tracer provider + an exporter are already wired into the app. In a Laravel context that usually means open-telemetry/opentelemetry-auto-laravel (or a hand-rolled middleware stack) is already in place.
  • Laravel's Illuminate\Http\Response/Symfony Response is not PSR-7, but OTel PHP propagators typically use array carriers (inject(array &$carrier, SpanContext $context)), so the integration surface is a thin middleware that reads the active span context, injects into an array, and copies values onto $response->headers. Low architectural intrusion.
  • The real architectural question is where the span context comes from: the middleware must execute after the root span is started and before the response is sent. Middleware priority in Kernel/bootstrap/app.php is the main design constraint.

Integration feasibility

  • Small, tractable build: one Composer dependency, one service-provider binding to register the propagator (env-var propagator config typically supports only built-ins like tracecontext/baggage, so expect to compose the propagator in code), one middleware, one config flag.
  • Estimated effort for a competent Laravel/PHP engineer: 1–2 days to a working header in dev; 3–5 days including CORS Timing-Allow-Origin / Access-Control-Expose-Headers, Octane/streaming handling, and a frontend RUM consumer that actually reads PerformanceResourceTiming.serverTiming.
  • Reversibility is excellent: remove the middleware and the header disappears. That makes it a safe spike.

Technical risk

  • Maturity/supply-chain risk is the dominant factor. 1 star, 0 dependents, READONLY mirror of a contrib repo, low overall score (14.8). This is effectively single-maintainer, pre-1.0 community code. Plan to treat the package as source you own rather than a dependency you consume.
  • Correctness risk (medium): Server-Timing semantics are per-resource and per-span; naive implementations double-emit or emit unsampled/blank entries. Header size is unbounded if combined with Baggage — enforce a cap.
  • Delivery risk (medium): CDNs, reverse proxies, and app-level caches frequently strip or cache Server-Timing; streaming responses flush headers before the propagator runs. The header can be silently absent with no error signal.
  • Security/privacy (low–medium): trace IDs are not secrets, but exposing them to unauthenticated clients can aid correlation against internal telemetry. Decide deliberately whether to emit in production, and only for sampled spans.

Key questions

  1. Does it implement inject() only, or also extract()? (Affects whether it can be safely dropped into the global propagator list without breaking inbound context.)
  2. Compatible with open-telemetry/sdk ^1.x and PHP 8.1/8.2/8.3 — is there a composer.json constraint matrix, or nothing published?
  3. Does it emit dur (duration), desc (traceparent), or both, and does it support multiple entries per response?
  4. Does it behave correctly with Octane (long-lived workers) and StreamedResponse?
  5. What is the upstream repo's release cadence and issue-response time — i.e., what does "last release 2026-07-15" actually mean in practice?
  6. Is the header expected to expose traceparent verbatim (useful for frontend→backend log join) or an opaque ID (safer)?

Integration Approach

Stack fit

  • Assumes Laravel 10/11, PHP 8.1+, and an already-instrumented OTel PHP SDK with tracecontext propagation. If tracing is not yet live, this package should be deferred — it is the last 5% of a tracing program, not the first.
  • Composes cleanly with the standard propagator chain: TraceContext (inbound/outbound) + this Server-Timing propagator (response header only). Keep them as separate bindings so the response behaviour can be toggled independently.
  • Frontend consumer is the actual dependency: Next/Vue/React RUM must read performance.getEntriesByType('resource') → serverTiming and forward to your observability backend. Budget for that work explicitly; it is often larger than the backend change.

Migration path

  • Phase 0 — Spike (2 days): install, register propagator, add middleware, verify header in curl -I on a local route. Gate: header present with a valid traceparent-derived value on sampled requests only.
  • Phase 1 — Non-prod only (1 week): enable via config('observability.server_timing.enabled') defaulting to false; enable in staging. Validate CORS exposure and CDN passthrough.
  • Phase 2 — Canary (2 weeks): 5–10% of production traffic, one service, one frontend surface. Measure header presence rate and frontend join success rate.
  • Phase 3 — Default on in a minor release, with the flag retained as a kill switch.
  • Fallback path is trivial: remove middleware, ship patch release. No data migration, no schema change, no API contract change.

Compatibility

  • Pin exact version (composer require ...:x.y.z) — do not use ^ on a 0.x contrib package with 1 star.
  • Verify coexistence with opentelemetry-auto-laravel: two middlewares both touching span lifecycle can conflict; confirm ordering and that the auto-instrumentation's response hook does not already set Server-Timing.
  • Confirm behaviour when CORS middleware is present: Server-Timing is not a CORS-safelisted response header; cross-origin frontends need Access-Control-Expose-Headers: Server-Timing and Timing-Allow-Origin. This is a one-line config change in config/cors.php but is a common silent-failure source.

Sequencing

  1. Confirm OTel SDK is live and sampled traces are queryable end-to-end.
  2. Lock the version matrix question (question 2 above) — this is the only true blocker.
  3. Build the service-provider binding + middleware behind a flag.
  4. Validate header correctness in staging (presence, format, size, sampled-only).
  5. Ship the frontend consumer and dashboard before broad enablement; otherwise you have unread telemetry.
  6. Canary → default-on with kill switch.

Operational Impact

Maintenance

  • Ownership cost is the headline. READONLY mirror + 1 star + 0 dependents means you should assume the upstream may go quiet. Realistic posture: vendor the ~100–200 LOC into app/Observability/ or a private fork, keep the Composer dependency for the spike only, and assign a named owner.
  • Ongoing effort is small but non-zero: a version bump per OTel SDK minor, plus a periodic check that the header still appears in production (a synthetic canary check is worth more than a dashboard here).
  • Recommend a composer outdated alert on open-telemetry/* and a quarterly review of the upstream contrib repo's activity.

Support

  • No commercial support; community-only. No Laravel-specific docs, no Stack Overflow corpus, no examples in the repo ecosystem. Effective support is your team reading the source.
  • Escalation path must be internal. Document the propagator's behaviour in your runbook so on-call isn't reverse-engineering it during an incident.

Scaling

  • Compute cost is negligible (microseconds per request, no I/O).
  • Network cost is real but small: a traceparent-derived desc is ~55–80 bytes per response; with Baggage it can grow. Cap header size and exclude Baggage from this header.
  • Watch header compression behaviour under HTTP/2 and any WAF/proxy header-size limits, particularly on high-fan-out endpoints.
  • Under Octane/RoadRunner, confirm no per-worker state accumulation in the middleware — this is the most plausible scaling failure mode.

Failure modes

  • Silent absence — no active span, unsampled trace, or middleware ordering error means no header and no error. Mitigate with a presence-rate metric.
  • Stripped in transit — CDN/WAF removes Server-Timing; appears to work in staging, not in prod. Test through the full edge path.
  • CORS invisibility — header present server-side, invisible to JS. Most common "it doesn't work" ticket.
  • Streaming/SSE responses — headers already flushed; propagator either throws or is a no-op. Must be explicitly handled.
  • Duplicate/oversized entries — nested spans or Baggage injection producing malformed or truncated headers.
  • Telemetry leakage — trace IDs exposed on unauthenticated endpoints, enabling correlation against internal systems. Decide per-route.

Ramp-up

  • Backend engineer: half a day to understand the propagator, 1–2 days to ship it responsibly. The concept (W3C Server-Timing for trace correlation) is easy; the CORS/edge/streaming edge cases are where time goes.
  • Frontend engineer: 2–4 days for the RUM consumer and dashboard — plan for this explicitly or the project delivers an unread header.
  • On-call/SRE: 1 hour of runbook familiarisation. Low cognitive load; the header is diagnostic, not load-bearing — its absence degrades observability, not availability.

Overall TPM recommendation: Low-risk, low-cost, low-ceiling capability that is only worth scheduling after tracing is already production-grade. Treat it as a build-in-house candidate (small enough to own outright) rather than a dependency to standardise on, and pair it with a frontend consumer commitment so the header produces a decision-relevant metric rather than bytes on the wire.

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.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel