Splunk APM: Distributed Tracing, Service Maps, and Always-On Profiling

Splunk APM: Distributed Tracing, Service Maps, and Always-On Profiling

Distributed systems fail in distributed ways. A request that touches 12 microservices before completing can fail or slow down at any of 12 points — and without distributed tracing, finding which one is a process of elimination that can take hours. Splunk APM is built to eliminate that investigation time, providing complete trace visibility, auto-generated service maps, and profiling capabilities that connect performance problems directly to code.

This guide covers Splunk APM in depth: how distributed tracing works, what makes NoSample™ tracing different, how to read service maps, what Always-On Profiling reveals, and how Business Workflows give you business-context visibility.

What Is Distributed Tracing?

A distributed trace is a record of a single request as it travels through your system. Each operation — HTTP call, database query, cache lookup, message queue publish — is recorded as a span. Spans from the same request share a trace ID and form a tree structure showing the call hierarchy and timing.

Without distributed tracing, you have logs that tell you "request A took 2.3 seconds" but no visibility into which of the 15 operations within that request consumed the time. With tracing, you can see: operation A took 2ms, operation B took 2.27 seconds (it called a database), operation C waited for B and then took 8ms.

Trace Anatomy

A trace consists of:

  • Root span — the entry point (e.g., the incoming HTTP request to your API gateway)
  • Child spans — operations triggered by the root (service calls, database queries)
  • Tags/Attributes — key-value metadata on each span (HTTP status code, DB query text, user ID)
  • Events — timestamped annotations within a span (e.g., "cache miss", "retry attempt 2")
  • Status — OK or ERROR, with optional error message

The W3C Trace Context standard (traceparent header) propagates trace context across service boundaries via HTTP headers. Splunk APM supports this standard, ensuring traces stitch correctly across services regardless of language or framework.

NoSample™ Tracing: Full Fidelity at Scale

Most APM solutions sample traces: they capture 1%, 5%, or 10% of requests and discard the rest. This works for statistical metrics like average latency. It fails for debugging, because:

  • Rare bugs appear in the 99% of traces you discarded
  • Specific user sessions you need to debug may not be captured
  • P99/P99.9 latency calculations become unreliable at low sample rates
  • Cascading failures that start as rare events are invisible until they're widespread

Splunk APM's NoSample™ approach retains 100% of trace data. Every span from every request is captured, indexed, and queryable.

How NoSample™ Stays Affordable

Retaining all traces naively would be prohibitively expensive. Splunk's approach:

Metricized traces: As spans arrive, Splunk derives RED metrics (Rate, Error, Duration) automatically. Dashboards query these pre-computed metrics — not raw spans — so typical monitoring workloads cost almost nothing in query terms.

Tiered retention: Full span data is retained for a short window (typically 8 days, configurable). Summary metrics derived from traces are retained much longer (13 months by default). Most root cause investigations happen within hours of an incident — 8 days covers virtually all real-world use cases.

Selective full retention: High-cardinality tracing data that doesn't need deep dive query capability is compressed aggressively. Only spans that match alert conditions or are actively queried incur full retrieval cost.

Service Maps

Splunk APM automatically generates service maps from your trace data. No configuration required — as traces flow in, the platform derives:

  • Which services call which other services
  • Request rate, error rate, and latency for each service
  • Request rate, error rate, and latency for each edge (service-to-service connection)

Reading the Service Map

The service map renders as a directed graph. Each node is a service. Each edge is a call path between services, annotated with RED metrics.

Node coloring: Services are color-coded by health status. Green = healthy, yellow = degraded (error rate or latency above baseline), red = high error rate or breaching SLO thresholds.

Edge thickness: Thicker edges indicate higher request volume. During an incident, you can immediately see which call paths are hot.

Dependency direction: Arrows show call direction. Downstream services that a failing service depends on are visible immediately — critical for triage when a shared service (auth, database, cache) causes cascading failures.

Drilling Into a Service

Clicking a service node in the map opens the Service Dashboard:

  • Request rate: requests per second, trended over time
  • Error rate: percentage of requests resulting in errors, trended
  • Latency: p50, p90, p99 distribution trended over time
  • Top endpoints: breakdown of traffic and errors by individual endpoint
  • Dependencies: upstream callers and downstream dependencies

From here you can jump into individual traces, filtered by time range, error status, or specific endpoints.

Trace Explorer

The Trace Explorer is Splunk APM's interface for querying individual traces. Unlike metrics which are aggregated, the Trace Explorer lets you retrieve specific individual traces.

Filtering Traces

Traces can be filtered by:

  • Time range
  • Service name
  • Endpoint / operation name
  • Duration (find slow requests: duration > 2s)
  • Error status (find only errored traces)
  • Any span tag (e.g., user.id = "usr_8821", order.id = "ord_4422")
  • HTTP status code

The high-cardinality tag filtering is where NoSample™ really pays off. With sampled APM, you might search for traces from a specific user and find nothing because that user's traces were discarded. With NoSample™, every trace is there.

Trace Detail View

Opening a trace renders a trace waterfall: a visual timeline of all spans in the trace, nested to show the call hierarchy.

Each span shows:

  • Service name and operation name
  • Start time and duration
  • Tags (expandable key-value list)
  • Error details (if status is ERROR)
  • Link to logs from this span's service during the span's time window

The trace waterfall immediately answers "what was slow?": the widest bars are the most time-consuming operations. Clicking any span opens its full tag set — including database query text, HTTP URL, response status code, and any custom tags your instrumentation adds.

Always-On Profiling

Standard distributed tracing tells you which service is slow. Always-On Profiling tells you which function in that service is consuming the time.

How It Works

Always-On Profiling continuously samples CPU stack traces from your running application. Unlike traditional profilers that you attach on-demand, it runs continuously at low overhead (typically < 1% CPU impact) and stores stack trace samples in Splunk APM alongside trace data.

When you have a slow trace, you can click into a span and see the flame graph of actual code execution that occurred during that span. No need to reproduce the issue, attach a profiler, and hope the problem recurs.

Reading a Flame Graph

A flame graph shows function call stacks. The X-axis represents time (wider = more CPU time consumed). The Y-axis is the call stack depth (bottom = entry point, top = leaf function).

Key patterns:

  • Wide plateau at the top: A leaf function consuming substantial CPU — usually the actual performance bottleneck
  • Wide bars at the bottom: A function that calls many things — look at what it's calling
  • Deep, narrow spike: A deep call chain that's called rarely but takes a long time when it runs

Practical Use Case: Debugging a Slow Endpoint

  1. Splunk APM alert fires: p99 latency for /api/checkout > 3s
  2. Trace Explorer: filter to endpoint /api/checkout, duration > 3s, last 30 minutes
  3. Open the slowest trace
  4. Waterfall shows: the inventory-service span took 2.8s
  5. Click into the inventory-service span, open Always-On Profiling
  6. Flame graph shows: 78% of CPU time in InventoryService.checkAvailability(), specifically in a nested loop that calls db.findById() in a tight loop (N+1 query problem)

Without profiling, step 6 would require a code review of the inventory-service, reproducing the issue, and potentially adding manual instrumentation. With Always-On Profiling, the answer is there immediately.

Business Workflows

Business Workflows is a Splunk APM feature that groups traces by business process rather than technical service. This is critical for organizations where multiple technical services collaborate on a single user-facing operation.

Configuration

You define a Business Workflow by specifying which span attribute to use as the grouping key. For example, a checkout workflow might be defined as:

Any trace where root span tag "workflow.name" = "checkout"

Your instrumentation adds this tag at the entry point:

with tracer.start_as_current_span("process_payment") as span:
    span.set_attribute("workflow.name", "checkout")
    span.set_attribute("order.id", order_id)
    span.set_attribute("order.value", order_value)
    # ... process payment

What You Get

Once workflows are defined, the Business Workflows dashboard shows:

  • Workflow rate: how many checkouts per minute
  • Workflow error rate: what percentage of checkouts fail
  • Workflow latency: p50/p99 for the complete checkout process end-to-end
  • Business impact: with order value as a tag, you can estimate revenue at risk from high error rates

This bridges the gap between technical metrics ("service X has 2% error rate") and business metrics ("our checkout is failing for 2% of customers, representing $X/hour in lost revenue").

Tag Spotlight: Finding Root Causes with Dimensions

Tag Spotlight is a feature that automatically surfaces correlations between span tags and performance anomalies. For a service with elevated error rates, Tag Spotlight analyzes all tags on errored spans and compares their distribution against healthy spans.

Example: Your order-service has a 5% error rate. Tag Spotlight shows:

  • region = us-east-1: 4.8% error rate (close to average — not correlated)
  • region = eu-west-1: 23% error rate (highly correlated — something regional is broken)
  • payment_method = paypal: 18% error rate (PayPal integration may be down)
  • customer_tier = enterprise: 0.1% error rate (enterprise customers unaffected)

This analysis, done manually, would require writing multiple aggregation queries across dimensions. Tag Spotlight does it automatically on every incident.

Instrumentation Best Practices

What to Instrument

Beyond what auto-instrumentation libraries capture, add custom spans and attributes for:

  • Business context: order.id, customer.tier, product.category, payment.method
  • Feature flags: feature_flag.name, feature_flag.value (invaluable for debugging canary deployments)
  • External dependencies: calls to third-party APIs that auto-instrumentation may not cover
  • Background jobs: message consumers, scheduled tasks, batch processing

Attribute Naming

Follow OpenTelemetry semantic conventions where possible:

  • http.method, http.status_code, http.url
  • db.system, db.statement, db.name
  • messaging.system, messaging.destination

Custom attributes: use a namespace prefix — myapp.order.id, not just order.id — to avoid collisions with OTel conventions.

Error Recording

Mark spans as error correctly:

from opentelemetry import trace
from opentelemetry.trace import StatusCode

with tracer.start_as_current_span("process_payment") as span:
    try:
        result = payment_client.charge(order)
    except PaymentDeclinedException as e:
        span.set_status(StatusCode.ERROR, str(e))
        span.record_exception(e)
        raise

This ensures errors appear in Splunk APM's error rate calculations and in Tag Spotlight analysis. Without explicit error recording, some exceptions may not be captured depending on the auto-instrumentation library.

Complementing APM with Functional Testing

Splunk APM gives you deep visibility into how your system behaves under real production traffic. For verifying that specific user flows work correctly before they reach production, HelpMeTest handles the functional layer — plain-English E2E tests that run on every deployment. The two tools together answer both "does the system work correctly?" (HelpMeTest) and "how does the system perform?" (Splunk APM).

Conclusion

Splunk APM is a serious distributed tracing platform. The NoSample™ model alone makes it qualitatively different from systems that require you to choose between cost and trace completeness. Combined with auto-generated service maps, Always-On Profiling that connects traces to code, and Business Workflows that frame technical metrics in business terms, it covers the full debugging workflow from symptom to root cause without leaving the platform.

For engineering teams operating distributed systems with performance and reliability SLOs, Splunk APM provides the observability depth that makes those SLOs maintainable rather than aspirational.

Read more

Start now free