What changes when you switch an AWS Lambda function's tracing mode from PassThrough to Active, what segments does the resulting trace contain, and why might that function still appear as a trace of its own instead of joining its caller's?
answer
- a config flag, not an instrumentation library
- two segments per invocation
- one subsegment only appears when cold
- the role has to be allowed to write
- no header in means no shared trace
basics
~20 sActive tracing makes the Lambda service record the invocation itself, producing a service segment plus a function segment with Initialization, Invocation and Overhead subsegments. The function joins its caller's trace only if the caller propagated the trace header and the execution role can write to X-Ray.
solid answer
~50 sWith tracing mode `PassThrough`, Lambda forwards an incoming trace header but records nothing. Set it to `Active` and the Lambda service samples and records the invocation itself, so a trace contains two segments per invocation: one for the **Lambda service** (the time the platform spent handling and queueing the invoke) and one for the **function**, whose subsegments are `Initialization`, `Invocation` and `Overhead`. The gap between them is where you see cold-start and platform overhead separated from your handler's own time. Two things must be true for it to join a wider trace: the caller must actually propagate `X-Amzn-Trace-Id` — Lambda exposes the incoming value in the `_X_AMZN_TRACE_ID` environment variable — and the execution role needs X-Ray write permissions, conventionally via the `AWSXRayDaemonWriteAccess` managed policy. Subsegments for your own downstream calls require the SDK or an ADOT layer in the function; active tracing alone does not instrument your code.
code
bash · 9 lines# Turn on active tracing for a function
aws lambda update-function-configuration \
--function-name checkout-worker \
--tracing-config Mode=Active
# The execution role must be allowed to send segments
aws iam attach-role-policy \
--role-name checkout-worker-role \
--policy-arn arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccessgo deeper
Know that tracing is a function setting with two modes, that Active makes Lambda record the invocation, and that the role must be allowed to write to X-Ray.
Describe the resulting trace precisely: a Lambda service segment plus a function segment with Initialization, Invocation and Overhead, and what each one covers.
Diagnose a disconnected or empty trace end to end — missing propagation, an async hop, a role without xray:PutTraceSegments, context lost inside the handler — and separate cold-start cost from handler time by reading the subsegments.
Decide where active tracing is worth its per-trace cost across a large function estate, and set the propagation and permission conventions so that traces span the boundaries between synchronous and event-driven components.
## The two modes A Lambda function's `TracingConfig.Mode` is either `PassThrough` (the default) or `Active`. - **PassThrough** — Lambda does not record anything of its own. It still receives and forwards the trace header, so a function that is instrumented by you, or a service the function calls, can still participate in the upstream trace. Sampling decisions from upstream pass through untouched. - **Active** — the Lambda service records the invocation. If the incoming request already carries a sampling decision, Lambda honours it; if there is no decision, Lambda makes one using X-Ray sampling. Switching to `Active` is a configuration change on the function, not a code change. That is exactly why candidates over-claim what it gives them. ## What a traced invocation looks like An active-traced invocation produces **two segments**: 1. **The Lambda service segment**, recorded by the platform. It covers the invocation from the service's point of view — the time spent receiving the request and getting it onto an execution environment. Errors here are platform-level: throttling, permission failures on the invoke. 2. **The function segment**, recorded by the execution environment, containing up to three subsegments: - `Initialization` — the execution environment starting up and running your initialization code outside the handler. It appears **only on a cold start**, which makes it the clearest visual signal of one you will get. - `Invocation` — your handler running. Anything the X-Ray SDK or ADOT instruments in your code hangs beneath this. - `Overhead` — the time between the handler returning and the environment being ready for the next invoke. Reading the two together is the point: a slow invocation with a fat `Initialization` subsegment is a different problem from one with a fat `Invocation`, and a gap between the service segment and the function segment points at the platform rather than at you. ## What active tracing does *not* give you Active tracing records the shape of the invocation. It does **not** instrument what your handler does. Subsegments for the DynamoDB call, the outbound HTTP request, the SQL query only appear if you add instrumentation inside the function — the X-Ray SDK with its client patching, or an ADOT Lambda layer configured to export to X-Ray. A common disappointment is enabling active tracing, seeing three subsegments named after lifecycle phases, and concluding X-Ray is useless. ## Why the function shows up as its own trace When a function's traces are disconnected from the caller's, work through this list: **The caller never propagated the header.** This is the usual cause. An API Gateway REST stage with tracing enabled passes the trace id along; an unrelated caller invoking through the SDK from an uninstrumented process does not. If nothing arrives, Lambda mints a fresh `Root` and you get an orphan trace that is internally correct and externally isolated. **An asynchronous hop in between.** If the invocation came from a queue, a stream or an event bus, there is no HTTP header, and context has to be carried in the message and re-established deliberately. Most estates lose the trace here and do not realise it until they look. **The execution role lacks X-Ray permissions.** Without `xray:PutTraceSegments` and `xray:PutTelemetryRecords` — the actions the `AWSXRayDaemonWriteAccess` managed policy grants — the function segment is never accepted. You then see the Lambda service segment and nothing underneath, which reads confusingly like a function that did no work. **Your handler lost the context internally.** Work handed to a background task, a thread, or a callback can run without the current segment attached, so any downstream call made there is uninstrumented and unparented. **Sampling disagreement.** If the incoming decision says not sampled, the invocation is not recorded at all — which looks like a missing function rather than a deliberate omission. ## The VPC red herring One thing worth knowing because it is asked: a function in a VPC does *not* need internet access for tracing to work in the way people fear — but every AWS API call the function makes, including telemetry, has to have a route. Teams that put a function into private subnets without a NAT route or the appropriate VPC endpoints frequently discover several things broke at once, and tracing is one of them. Diagnose it as a general egress problem rather than an X-Ray problem. ## Operational note Active tracing costs money per trace recorded and per trace retrieved, and a very high-volume function traced at a high rate is a real line item. Sampling exists for this reason: leave active tracing on, and let sampling rules control volume, rather than flipping tracing off and losing the ability to investigate.
- You enabled active tracing but the trace shows only lifecycle subsegments and none of your downstream calls. Why?Because active tracing records the shape of the invocation, not what your code does. `Initialization`, `Invocation` and `Overhead` come from the platform; subsegments for a DynamoDB call or an outbound HTTP request only appear when the function itself is instrumented — the X-Ray SDK patching its clients, or an ADOT layer exporting to X-Ray. The flag and the instrumentation are two separate decisions.
- How can you tell a cold start apart from a slow handler in an X-Ray trace of a Lambda invocation?By which subsegment is fat. The `Initialization` subsegment exists only when a new execution environment was created, so its presence is the cold-start signal and its duration is the cold-start cost. A long `Invocation` with no `Initialization` is a warm invoke doing slow work. `Overhead` covers post-handler platform work and is normally small; a large one is unusual and worth investigating separately.
- What does PassThrough mode still do, and when is it the right setting?It forwards the incoming `X-Amzn-Trace-Id` without recording anything on Lambda's behalf. It is right when the function is a high-volume, low-value hop you do not want to pay to trace but which sits in the middle of traces you do care about — the header keeps flowing, so services downstream still join the caller's trace. It is also the default, which is why an untouched function contributes nothing to your service map.
saying these in an interview costs you the question
- Thinking active tracing instruments your handler's downstream calls
- Forgetting the execution role needs X-Ray write permissions
- Believing PassThrough drops the trace header entirely
- Expecting an Initialization subsegment on every invocation
- Assuming Lambda joins the caller's trace without any propagation