TracekitTracekit

Laravel APM with OpenTelemetry: Production Guide for 2026

Set up Laravel APM with OpenTelemetry, traces, queue visibility, and dynamic logs so you can debug production issues without guessing.

Terry Osayawe1 min read
Laravel APM with OpenTelemetry: Production Guide for 2026

Laravel APM with OpenTelemetry should help you answer four production questions quickly: which request or job failed, where the time went, what changed in the release, and what runtime state explains the bad outcome. If your current workflow stops at "the route was slow" or "the logs did not show the missing variable," your Laravel APM setup is incomplete.

This guide shows how to instrument Laravel with Tracekit's current Laravel package, what it traces automatically today, where OpenTelemetry context propagation still matters, and how dynamic logs help when traces show the hot path but not the reason the code made the wrong decision.

The focus is production Laravel applications that handle HTTP traffic, database work, queue jobs, and outbound API calls. If your stack also includes workers, scheduled jobs, or multiple services, keep reading. Those are the places where a basic APM dashboard often stops being enough.

What good Laravel APM should show

The official Laravel queue docs and OpenTelemetry trace concepts describe the pieces independently. A useful Laravel APM setup connects them into one production debugging workflow.

For a practical setup, you want:

AreaWhat to seeWhy it matters
Incoming requestsroute, method, status, duration, trace IDConfirms which user-facing request actually hurt
Database workquery timing, slow queries, repeated query patternsMakes N+1 and lock-heavy endpoints visible
Queue jobsjob class, queue name, status, durationExplains what kept running after the response
Outbound callsHTTP target, status, duration, peer serviceShows whether the bottleneck is internal or external
Error contextexception, stack trace, release context where availableTurns "500 error" into a fixable incident
Runtime statebounded dynamic logs on suspicious code pathsExplains why the code chose the wrong branch

Tracekit's current Laravel support is grounded in the package and docs that ship today:

  • The service provider registers HTTP middleware for request tracing.
  • Database query listeners are attached when database tracing is enabled.
  • Queue job listeners are attached when queue tracing is enabled.
  • Outgoing Laravel HTTP client requests can be instrumented automatically.
  • Dynamic logs are exposed through the tracekit_snapshot() helper and the code monitoring client.

That matters because the live SERP for Laravel APM is crowded with framework-specific monitoring products, generic APM vendors, and OpenTelemetry examples. Searchers usually want a clear setup path plus debugging advice, not just a features page.

1. Start with an OpenTelemetry-native Laravel package

Tracekit's Laravel package is built on OpenTelemetry and ships as tracekit/laravel-apm.

composer require tracekit/laravel-apm
php artisan tracekit:install

Then configure the service in .env:

TRACEKIT_API_KEY=ctxio_your_api_key
TRACEKIT_SERVICE_NAME=checkout-web
TRACEKIT_ENABLED=true

# Optional but useful for production debugging
TRACEKIT_CODE_MONITORING_ENABLED=true
TRACEKIT_CODE_MONITORING_POLL_INTERVAL=30
TRACEKIT_SLOW_QUERY_MS=100

For the complete package options, use the Laravel integration guide. For a lower-level installation walkthrough, continue with the OpenTelemetry PHP and Laravel setup guide. If you are standardizing exporters across services, the OTel config generator is a useful companion.

Two practical notes:

  1. Keep TRACEKIT_SERVICE_NAME stable per deployable Laravel service. If every worker or environment writes a different service name, your traces get harder to query.
  2. Enable dynamic logs only where you actually need runtime-state capture. Your normal application logs should still live in Laravel's logger.

2. Know what Tracekit traces automatically today

The current Laravel package is not making a vague "works with PHP somehow" claim. The local package registers concrete tracing hooks through the service provider:

  • HTTP middleware for incoming requests
  • database query listeners
  • queue job listeners
  • outbound HTTP client instrumentation
  • exception capture on active spans

In practice, that means a default setup is strongest for:

  • request tracing across your Laravel routes
  • Eloquent and query builder timing
  • queue job execution visibility
  • outbound API call timing through Laravel's HTTP client
  • exception capture tied to the current trace

That is already enough to solve a lot of production issues. You can see whether the slow path was in the route handler, the database, the queue job, or the downstream API.

It is also important to stay honest about the current boundary:

  • If a queue worker runs independently from the original request, you still need to think about how context should be linked across that boundary.
  • If your app calls services through libraries outside the instrumented Laravel HTTP client path, verify that those clients are instrumented too.
  • If you only keep permanent logs and never add bounded runtime capture, traces may tell you where to look without telling you why the business decision was wrong.

That distinction is the difference between a useful Laravel APM guide and a misleading one.

3. Treat queue and service boundaries as context-propagation checkpoints

The W3C Trace Context specification defines the standard headers used to preserve trace identity across services. That matters in Laravel whenever a request leaves the web process and becomes background work, another HTTP call, or another service entirely.

Your Laravel APM checklist should confirm:

  • incoming request traces start with the correct route and request metadata
  • outbound HTTP calls preserve trace context where instrumented
  • queue workers are visible as their own execution units
  • service names stay consistent across web and worker processes
  • important release metadata is attached where your deployment flow provides it

If you skip this step, you still get spans, but you do not always get one coherent story. That usually shows up as:

  • a request span that looks normal while the downstream API is slow
  • a queue job that appears disconnected from the user action that triggered it
  • traces that stop at the controller even though the incident happened in a worker

Tracekit helps once the context exists. It cannot reconstruct missing propagation after the fact.

4. Use Laravel APM to catch query problems before they become incidents

Laravel applications often degrade through query shape, not dramatic crashes. N+1 queries, repeated cache misses, missing indexes, and slow external dependencies can make a route feel random to users long before it becomes obviously broken.

That is why Laravel APM should make these questions easy:

  • Which route got slower after the last deploy?
  • Which SQL statement dominates request time?
  • Is the issue in the web request or in the queued follow-up job?
  • Did a dependency timeout, or did the application make too many small queries?

The current Laravel package exposes a slow-query threshold through TRACEKIT_SLOW_QUERY_MS, so you can tune what gets highlighted for your application instead of treating every query the same.

You should also keep a framework-specific checklist in mind:

  • trace the routes users care about, not just /health
  • review repeated query patterns on list pages and dashboards
  • instrument outbound services that make Laravel wait
  • look at queue latency separately from request latency
  • keep high-cardinality or sensitive data out of attributes unless you truly need it

For a broader query workflow, pair this guide with Tracekit's N+1 query guide and distributed tracing feature docs.

5. Add dynamic logs when traces show where to look but not why

Tracing answers timing and path questions well. It does not always answer state questions.

That is where Tracekit dynamic logs fit. They are bounded capture points for the exact code path you already suspect. They are not a generic log ingestion system, and they are not a reason to stop using Laravel's normal logger for everyday application events.

Use dynamic logs when a trace already told you which request or job is suspicious, but you still need to inspect:

  • the payload shape returned by a third-party API
  • a tenant- or plan-specific branch
  • the values used to build a query
  • the state of a checkout or queue handoff
  • the variable that should have been logged but was not

Tracekit's current Laravel helper is still named tracekit_snapshot() in code, but the public workflow should be thought of as dynamic logs:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class CheckoutController extends Controller
{
    public function process(Request $request)
    {
        $cart = $request->input('cart', []);
        $userId = $request->user()?->id;

        tracekit_snapshot('checkout-validation', [
            'user_id' => $userId,
            'cart_items' => count($cart['items'] ?? []),
            'cart_total' => $cart['total'] ?? 0,
        ]);

        // Continue normal checkout flow...
    }
}

That lets you inspect runtime state without adding another permanent log line and waiting for a redeploy. For the broader workflow, see the dynamic logs documentation and the dynamic logs feature page.

6. Make queue jobs first-class citizens in your Laravel APM workflow

A lot of Laravel incidents are not pure request problems. They show up after the response:

  • a queued email job times out
  • a payment reconciliation job retries forever
  • a webhook processor is fast in development but backs up under real traffic
  • a worker throws exceptions that never surface clearly in the original request path

That is why queue visibility should not be an afterthought in Laravel APM.

The current package registers queue listeners, so your baseline should include:

  • job class name
  • queue name
  • execution status
  • duration

From there, your operational checklist should ask:

  • Which jobs fail most often after deploys?
  • Which queue is backing up?
  • Which job calls an external dependency that is timing out?
  • Which worker needs dynamic logs because the trace shows the hot path but not the business state?

If your application depends heavily on jobs, make sure your alerting and ownership rules treat web traffic and worker traffic as separate investigation surfaces.

7. Build the dashboard around triage questions, not vanity charts

A useful Laravel APM dashboard should help the on-call developer answer:

  • What broke?
  • When did it start?
  • Which route or job is affected?
  • Is the database, queue, or downstream API the bottleneck?
  • Did this begin after a release?
  • Do I need runtime state from a specific code path?

That usually leads to a tighter operating model:

QuestionBest Tracekit surface
Which route or service regressed?Distributed tracing
Did the failure create a grouped exception?Error tracking
Do we need runtime variables from the suspicious path?Dynamic logs
Should someone be paged for this pattern?Alerting

The goal is not "one more dashboard." The goal is faster incident explanation.

8. A practical Laravel APM checklist for production releases

Before a meaningful Laravel release, ask:

  1. Do the important routes still produce traces with stable service and route names?
  2. Are slow queries and repeated query patterns still visible?
  3. Are queue workers and follow-up jobs still being traced?
  4. Are outbound API calls instrumented on the code paths that matter most?
  5. Do error groups and release context still make sense after the deploy?
  6. If the incident turns out to be state-related, do we have a safe path to add dynamic logs?

If you cannot answer those questions quickly, the problem is not only "missing monitoring." It is that your debugging workflow has gaps between traces, jobs, releases, and runtime state.

When Tracekit fits best for Laravel APM

Tracekit is a strong fit when you want:

  • OpenTelemetry-native Laravel tracing
  • one workflow for request traces, queue jobs, errors, and runtime-state capture
  • production debugging context without turning your whole stack into permanent log storage
  • a simpler setup path than stitching together multiple separate tools for traces, alerts, and runtime capture

It is especially useful when your team already knows where incidents happen, but keeps losing time on why the code made the wrong decision in production.

For setup, start with the Laravel observability page, Laravel integration docs, and the OpenTelemetry PHP setup guide. When query count is the warning signal, use the Laravel N+1 query guide. If you are standardizing exporters across multiple services, use the OTel config generator. If your next incident will probably involve a queue job or a hidden branch condition, plan your dynamic logs workflow before the outage, not during it.

Share this post

Related Posts