Practices
Observability for Serverless Architectures
Why function-as-a-service platforms like AWS Lambda force different instrumentation, sampling, and tracing tradeoffs than server-based observability.
Last updated
Serverless computing — most commonly function-as-a-service (FaaS) platforms like AWS Lambda, Azure Functions, and Google Cloud Functions — removes the long-running process that traditional observability agents depend on. A conventional APM agent runs as a background thread or sidecar inside a process that stays alive for hours or days, continuously buffering and flushing telemetry. A serverless function might run for a few hundred milliseconds, execute once, and then have its entire execution environment frozen or destroyed. That single difference forces a different approach to instrumentation, export, sampling, and cost accounting across the whole observability pipeline.
The practical challenges cluster around a few recurring issues: getting telemetry out of a short-lived execution before the function environment is frozen, accounting for cold starts as a distinct and important latency phenomenon, tracing requests across function boundaries and into other managed services, and controlling the cost of observability when it’s billed and charged per invocation rather than per host-hour.
Why it matters
- There’s no persistent process to attach a traditional agent to. A function invocation may last milliseconds, and the runtime can freeze or terminate the execution environment as soon as the handler returns, so telemetry has to be flushed synchronously or handed off before that happens — a buffering, batch-on-a-timer agent designed for long-running servers doesn’t work the same way here.
- Cold starts are a first-class latency signal, not noise. When a platform has to initialize a new execution environment for a function, that initialization time adds directly to user-facing latency; observability for serverless has to distinguish cold-start latency from warm-invocation latency, since they have different causes and different fixes.
- Sampling and cost decisions are different because billing is per-invocation. Every invocation is already metered and billed individually, so the marginal cost of adding instrumentation overhead or telemetry export to each invocation is more visible and immediate than the amortized cost of an agent on a long-running host — teams tend to be more deliberate about what gets traced on every call versus sampled.
- Distributed tracing has to cross function and managed-service boundaries. A single user request commonly touches multiple functions plus managed services (API Gateway, queues, managed databases) that the team doesn’t operate directly, so trace context has to propagate through platform-managed boundaries the team can’t instrument directly, not just through their own code.
How to approach it
- Use extensions and layers instead of a traditional in-process agent. AWS Lambda’s Extensions API lets an agent run alongside the function as a separate process within the same execution environment, handling telemetry export without blocking the handler; the AWS Distro for OpenTelemetry (ADOT) and the OpenTelemetry Lambda layers ship as prebuilt layers that add auto-instrumentation and a lightweight collector to a function with minimal code changes.
- Only enable the instrumentation you actually use. Auto-instrumentation libraries typically enable only common ones (AWS SDK, HTTP calls) by default because loading and initializing additional instrumentation adds measurable overhead to cold start time; broad, unfiltered auto-instrumentation is one of the most common causes of noticeably slower cold starts.
- Propagate trace context through platform-managed services deliberately. Confirm that context propagates correctly through API Gateway, EventBridge, SQS, or Step Functions between function invocations — these hops don’t automatically carry a W3C Trace Context header the way a direct HTTP call between two services you control would, and each service integration typically needs explicit configuration to forward it.
- Treat sampling as a cost lever from day one, not an afterthought. Because both invocation and telemetry export are billed per call, decide upfront what fraction of invocations get full tracing versus a lighter-weight metric-only path, rather than defaulting to trace-everything and discovering the bill later.
- Correlate cold-start metrics with deployment and configuration changes. Cold start frequency and duration are heavily influenced by runtime, package size, memory allocation, and provisioned concurrency settings — track them as a distinct metric so a regression can be tied back to a specific change rather than blended into general latency numbers.
Serverless doesn’t eliminate the need for the four pillars — it just moves where they’re captured. See traces for how context propagation works in general, and metrics for how per-invocation latency and error data gets aggregated once it’s out of the function.
Related tools
AWS's native distributed tracing service, transitioning to OpenTelemetry-based instrumentation and now the trace storage layer behind Application Signals.
Language-specific instrumentation libraries (Java, Go, Python, JS/TS, .NET, and more) for emitting traces, metrics, and logs.
A unified commercial observability platform covering infrastructure metrics, APM/distributed tracing, log management, and continuous profiling.
A managed observability platform built around high-cardinality, wide structured events, marketed as the model for what its founders call 'Observability 2.0'.