{
    "slug": "trace_span",
    "term": "Traces & Spans",
    "category": "observability",
    "difficulty": "intermediate",
    "short": "The building blocks of distributed tracing — a trace represents a complete request journey across services, composed of spans that each record one operation with its start time, duration, and parent–child relationship.",
    "long": "A trace is a collection of spans that together describe how a single request moved through a distributed system. Each span records: operation name, start timestamp, duration, service name, status (success/error), and attributes (key-value metadata). Spans form a tree — the root span is the initial entry point (HTTP request, queue message, scheduled job); child spans represent downstream calls (database queries, external HTTP calls, cache lookups, sub-function calls). The parent–child relationship is maintained via a trace ID (shared by all spans in a trace) and a span ID (unique per span, referenced by children as their parent ID). In PHP, OpenTelemetry is the standard SDK for creating and exporting spans. Traces are exported to collectors like Jaeger, Zipkin, or Datadog, which visualise the span tree and highlight bottlenecks.",
    "aliases": [
        "trace",
        "span",
        "distributed trace",
        "trace context",
        "trace ID",
        "span ID",
        "parent span"
    ],
    "tags": [
        "observability",
        "tracing",
        "opentelemetry",
        "distributed-systems",
        "php"
    ],
    "misconception": "Distributed tracing is only useful in microservices architectures. Tracing is equally valuable in monolithic PHP applications — a trace shows exactly which database queries, cache calls, and template renders are slow for a specific request, with precise timing and the call hierarchy. A monolith with 50ms database queries inside loops benefits from tracing as much as a microservices system with cross-service latency. The cost of adding spans to a PHP application is low with the OpenTelemetry auto-instrumentation package.",
    "why_it_matters": "Logs and metrics tell you that something is slow; traces tell you exactly what is slow and why. A PHP application processing an order might log 'request took 850ms' — a trace shows it was three sequential database queries each taking 280ms, called inside a loop, with a cache miss on every iteration. Without traces, diagnosing this requires adding timing code, re-deploying, and hoping the issue reproduces. With traces, the span tree makes the N+1 pattern immediately visible in the UI. OpenTelemetry auto-instrumentation for PHP instruments PDO, Guzzle, and Redis automatically with zero code changes.",
    "common_mistakes": [
        "Creating spans that are too coarse — a single span for 'process order' hides where time is spent; instrument individual database queries and external calls.",
        "Not propagating trace context across service boundaries — HTTP headers (traceparent) must be forwarded to downstream services for the trace tree to connect.",
        "Sampling 100% of requests in production — at high traffic, full sampling generates enormous data volume; use head-based sampling (1-10%) or tail-based sampling (keep traces with errors).",
        "Not adding attributes to spans — a span named 'db.query' with no attributes is useless; add the query, table name, and affected rows."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "distributed_tracing",
        "opentelemetry",
        "structured_logging",
        "slo_sli_sla"
    ],
    "prerequisites": [],
    "refs": [
        "https://opentelemetry.io/docs/languages/php/"
    ],
    "bad_code": "// No tracing — request slow, no idea why\npublic function processOrder(int $orderId): void {\n    $order = $this->db->query('SELECT * FROM orders WHERE id = ?', [$orderId]);\n    foreach ($order->items as $item) {\n        $product = $this->db->query('SELECT * FROM products WHERE id = ?', [$item->product_id]);\n        // N+1 — invisible in logs, obvious in traces\n    }\n}",
    "good_code": "// Manual spans — each operation visible in trace UI\npublic function processOrder(int $orderId): void {\n    $span = $this->tracer->spanBuilder('process_order')\n        ->setAttribute('order.id', $orderId)\n        ->startSpan();\n    $scope = $span->activate();\n\n    try {\n        // PDO auto-instrumentation creates child spans automatically\n        $order = $this->db->query('SELECT * FROM orders WHERE id = ?', [$orderId]);\n        $span->setAttribute('order.item_count', count($order->items));\n        // ... rest of processing\n        $span->setStatus(StatusCode::STATUS_OK);\n    } catch (Throwable $e) {\n        $span->recordException($e)->setStatus(StatusCode::STATUS_ERROR);\n        throw $e;\n    } finally {\n        $scope->detach();\n        $span->end();\n    }\n}",
    "quick_fix": "Install open-telemetry/opentelemetry-auto-pdo for automatic PDO span creation — zero code changes, all SQL queries become spans with timing",
    "severity": "info",
    "effort": "medium",
    "created": "2026-03-23",
    "updated": "2026-04-05",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/trace_span",
        "html_url": "https://codeclaritylab.com/glossary/trace_span",
        "json_url": "https://codeclaritylab.com/glossary/trace_span.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Traces & Spans](https://codeclaritylab.com/glossary/trace_span) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/trace_span"
            }
        }
    }
}