---
title: PHP Observability with OpenTelemetry | Pydantic Logfire
description: >-
  Send PHP traces to Pydantic Logfire with the standard OpenTelemetry PHP SDK.
  Autoloading builds and flushes the tracer, then query traces, metrics, and
  logs with SQL.
canonical: 'https://pydantic.dev/logfire/php'
---

> Markdown version of [Trace, monitor and debug your PHP app](https://pydantic.dev/logfire/php) — the canonical HTML page.
>
> Site index: [/llms.txt](https://pydantic.dev/llms.txt)

---

# Trace, monitor and debug your PHP app

Logfire for PHP

PHP Observability from the team behind Pydantic: trace request-per-process apps, keep Composer vendor-neutral, and query everything in plain SQL. Standard OpenTelemetry, no lock-in.

[Try Logfire for free](https://logfire.pydantic.dev/login?intent=signup) [See the PHP docs](https://pydantic.dev/docs/logfire/instrument/php/)

Set up Logfire with your coding agent:

uvx logfire-cli wizard

Install and configure

```bash
composer require open-telemetry/sdk open-telemetry/exporter-otlp php-http/guzzle7-adapter
```

Configure exporter

```bash
export OTEL_PHP_AUTOLOAD_ENABLED=true
export OTEL_SERVICE_NAME=hello-php
export OTEL_EXPORTER_OTLP_ENDPOINT='https://logfire-us.pydantic.dev'
export OTEL_EXPORTER_OTLP_HEADERS='Authorization=your-write-token'
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
```

Create a span

```php
<?php
require __DIR__ . '/vendor/autoload.php';

\OpenTelemetry\API\Globals::tracerProvider()
    ->getTracer('hello-php')
    ->spanBuilder('Hello World')
    ->startSpan()
    ->end();
```

Full details are in the [PHP setup guide](https://pydantic.dev/docs/logfire/instrument/php/).

Trusted by teams building production software and AI

**Customers:** Motorola, Sophos, Airbyte, Pictet, Vox Media, Weaviate, Amboss, Tiger Data

What you get

## One request, one trace

![A Logfire trace of a PHP request handled by Slim, showing the route, the closure and the service's own spans](https://pydantic.dev/assets/logfire/language-traces/php-trace.png)

**What lands in Logfire:**

* the Slim route span, timed and carrying its status code
* the `{closure}` that handles it, from the Slim auto-instrumentation
* your own `calculate-quote` span, nested where it ran
* each log line attached to the span that emitted it, not to the request

The framework spans need the `opentelemetry` extension: `pecl install opentelemetry`, add `extension=opentelemetry.so` to your `php.ini`, then install the auto-instrumentation package for your framework (`open-telemetry/opentelemetry-auto-slim` here). Your own spans work without it.

Try it on your stack

## See your own PHP trace

Start free with 10 million spans, logs, and metrics each month. No credit card required.

[Start free](https://logfire.pydantic.dev/login?intent=signup) [Read the PHP setup guide](https://pydantic.dev/docs/logfire/instrument/php/)

How it works

## Standard OpenTelemetry, hosted backend

### Autoloading does the wiring, and the flushing

With OTEL\_PHP\_AUTOLOAD\_ENABLED set to true, the SDK builds a tracer provider from your environment when the app loads and flushes it when the script ends. That last part matters more in PHP than anywhere else: the request-per-process model means a missed flush is lost telemetry, and autoloading removes that failure mode instead of leaving it to you.

### Standard OTLP, so genuinely no lock-in

Configuration is OTEL\_ environment variables against the standard OpenTelemetry PHP SDK. Your composer.json contains OpenTelemetry packages and nothing of ours, so moving to a different backend is a config change rather than a migration.

### Request telemetry in one project

Bring PHP request traces and any OTLP metrics or logs from the surrounding stack into one Logfire project. Shared service attributes keep the signals connected instead of splitting one incident across separate backends.

### SQL instead of a query language you have to learn

Use PostgreSQL-compatible SQL to compare PHP routes, status codes, database spans, and any attributes your instrumentation records. Turn the same query into a dashboard or alert when the question becomes part of operating the service.

Query

## Query your PHP telemetry with SQL

If you can ask it, SQL can find out

* Query your traces, metrics and logs with real SQL
* No proprietary query language to learn
* AI models are great at writing SQL
* From a one-off investigation to an alert, dashboard, or SLO

```sql
select
  attributes->>'http.route' as route,
  count(*) as requests,
  avg(duration) as avg_seconds
from records
where duration > 1
group by route
order by avg_seconds desc;
```

Proof

## In production

> You can tell that Pydantic Logfire was built by people who use it.

Dennis Griffin, VP of Engineering, Sophos [Read the case study](https://pydantic.dev/case-studies/sophos)

Decision guide

## Is Logfire right for you?

### Choose Logfire if

* You want request traces from a PHP app without a proprietary agent
* You want only OpenTelemetry packages in your composer.json
* You want to query traces, metrics, and logs with PostgreSQL-compatible SQL
* You do not want to run Jaeger, Prometheus, and storage yourself
* You want the option to repoint at another backend without a rewrite

### Choose a vendor APM if

* You want a vendor-maintained PHP SDK with vendor-specific APIs
* You are already deeply integrated with a specific APM vendor's ecosystem
* You need a vendor-only integration or compliance capability Logfire does not offer

FAQ

## Common questions

### Is there a Logfire SDK for PHP?

No. PHP uses the standard OpenTelemetry PHP SDK, and Logfire is the OTLP backend it exports to, so nothing proprietary enters your composer.json. First-party Logfire SDKs exist for Python, TypeScript, and Rust.

### composer require fails with no PSR-18 HTTP client found

The OpenTelemetry OTLP exporter needs a PSR-18 HTTP client and does not bundle one. Install php-http/guzzle7-adapter, or any other PSR-18 implementation you prefer, alongside the SDK and exporter packages.

### The script runs but nothing appears in Logfire

Autoloading is almost always the cause. With OTEL\_PHP\_AUTOLOAD\_ENABLED set to true, the SDK builds a tracer provider from your environment variables when the app loads and flushes it when the script ends. Without it, no tracer provider is created and spans go nowhere.

### Nothing arrives from a self-hosted instance with a private certificate

PHP's HTTP client does not trust a private CA and ignores the OpenTelemetry certificate environment variable. Set openssl.cafile to your CA bundle in php.ini, or pass php -d openssl.cafile=/path/to/ca.pem when running.

### Am I locked in to Logfire?

No. Configuration is standard OTEL\_ environment variables against the standard OpenTelemetry PHP SDK, and your code references OpenTelemetry APIs only. Repoint the endpoint at another OpenTelemetry-compatible backend, or at your own collector, whenever you want.

## Start seeing your PHP app

Get started with 10 million free spans, logs, and metrics per month. No credit card required.

* [Start free](https://logfire.pydantic.dev/login?intent=signup)
* [Book a demo](https://pydantic.dev/contact)
* [View pricing plans](https://pydantic.dev/pricing)
