π AWS X-Ray β Distributed Tracing
X-Ray shows you the complete journey of every request through your application β across all services, all the way to the database. It's how you find which service is slow, which is failing, and exactly why.
π Covers: Traces Β· Segments Β· Annotations Β· Service Maps Β· Sampling Β· Filter Expressions Β· X-Ray DaemonThe Problem β Why Do We Need X-Ray?
In the old days, you had one server running one application. When it was slow, you checked that server. Simple.
Modern applications (microservices, serverless) are distributed β a single user request might touch 5-10 different services:
The user says: "The API is slow, it takes 4 seconds!"
Without X-Ray, you'd check each service manually. Is it API Gateway? Lambda? DynamoDB? The email service? With 5+ services, this is extremely time-consuming.
With X-Ray: You see that the DynamoDB query is taking 3.7 seconds. Found it. Fix it.
Core X-Ray Concepts β The Building Blocks
From this trace, you can immediately see: DynamoDB.GetItem took 3700ms out of the 4200ms total. That's the bottleneck. You'd then look at the DynamoDB query β maybe it's doing a full table scan instead of using an index.
Annotations vs Metadata β Critical Difference
You can attach custom data to X-Ray segments. There are two types: Annotations (filterable) and Metadata (not filterable). This distinction is heavily tested.
π·οΈ Annotations β Indexed, Filterable
- Simple key-value pairs (string, number, boolean)
- CloudWatch X-Ray indexes them β you can use them in filter expressions to search traces
- Limited: max 50 annotations per trace
- Use for: data you need to search/filter on β userID, orderId, environment, tenantId, feature flag
- Example:
"userId": "user-123"
π Metadata β Non-Indexed, Not Filterable
- Can store any JSON-serializable data (objects, arrays, complex structures)
- NOT indexed β you cannot filter traces based on metadata values
- No limit on size (reasonable amounts)
- Use for: additional context you want to see when you look at a trace β request body, response data, debug info
- Example: Full DynamoDB response object
Metadata cannot be filtered. If someone says "I want to search for all traces from tenant X" β add an Annotation, not Metadata.
X-Ray Service Maps β Visual Dependency Analysis
A Service Map is an automatically generated diagram showing all the services in your application and how they connect. Each node (box) shows the service, and the edges (arrows) show calls between them, with health and latency information.
π What a Service Map Shows
From this Service Map, you can instantly see:
- DynamoDB is the slow node (3.7 seconds average) β highlighted in red/orange
- Payment API is an "inferred" service (no X-Ray SDK) β shown in different color
- API Gateway and SES are healthy β shown in green
π― Service Map Benefits
- Automatic discovery: You don't draw the diagram manually β X-Ray discovers service dependencies from actual traffic
- Health indicators: Color-coded to show which services are having issues
- Latency visualization: Shows average and percentile response times per service
- Drill down: Click on a service node to see its traces, then click on a trace to see the full timeline
X-Ray Sampling β Cost vs Detail Trade-off
Tracing every single request in a high-traffic application would be expensive (costs money to store traces) and could add latency. Sampling means only recording some requests as traces, not all of them.
π Default Sampling Rule
X-Ray's default rule: record the first request per second, then 5% of additional requests.
Default sampling: Record 1 (first) + 5% of remaining 999 = ~51 traces per second.
Instead of storing 1000 traces/sec, you store ~51/sec. Much cheaper, still statistically significant.
βοΈ Custom Sampling Rules
You can create custom sampling rules to sample different rates for different types of requests:
| Rule Name | Condition | Rate | Why |
|---|---|---|---|
| HealthCheck | URL = /health | 0% | Health check noise is useless |
| PaymentAPI | URL contains /payment | 100% | Always trace critical transactions |
| ErrorTracing | HTTP status = 5XX | 100% | Always trace errors for debugging |
| Default | Everything else | 5% | Statistical sample for normal traffic |
Filter Expressions β Finding Specific Traces
With thousands of traces, you need to search for specific ones. Filter Expressions are queries you use to find traces that match specific criteria.
X-Ray Daemon β The Data Collector
The X-Ray SDK in your application doesn't send trace data directly to the X-Ray service. Instead, it sends trace data (UDP on port 2000) to a local X-Ray Daemon process, which batches the data and sends it to the X-Ray service.
π Where Does the Daemon Run?
| Platform | Daemon Setup |
|---|---|
| AWS Lambda | X-Ray daemon runs automatically when you enable Active Tracing. You don't install or manage it. |
| Elastic Beanstalk | Enable X-Ray in the EB console β daemon is installed automatically. No manual setup needed. |
| EC2 Instance | You install the daemon manually as a background process. Available as a package for Linux/Windows. |
| ECS Container | Run as a sidecar container alongside your app container. |
| On-Premises | Install daemon manually on the server. Needs IAM user credentials (not IAM role, since not on AWS). |
π IAM Permissions for X-Ray Daemon
The daemon needs permission to write to X-Ray. The IAM policy needs:
X-Ray with AWS Lambda β Active Tracing
Lambda has built-in integration with X-Ray through a feature called Active Tracing. When enabled, Lambda automatically creates segments and runs the X-Ray daemon β you just need to add the X-Ray SDK to your code.
β‘ Enabling Active Tracing
Three ways to enable:
- AWS Console: Lambda function β Configuration β Monitoring β Enable Active Tracing
- AWS CLI:
aws lambda update-function-configuration --function-name my-fn --tracing-config Mode=Active - CloudFormation/SAM:
Tracing: Activein the function resource
π What Lambda Automatically Creates in X-Ray
- A segment for each Lambda invocation with: cold start duration (if applicable), initialization time, invocation time
- Subsegments for each AWS SDK call inside Lambda (DynamoDB, S3, SQS, etc.) β automatically created if you use X-Ray SDK
- Metadata about the function: function name, version, memory, request ID
Passive Tracing: Lambda only traces if the upstream service already started a trace and passed the trace ID in the request (called "trace propagation"). If there's no incoming trace, Lambda doesn't create one.
π Trace Propagation β How Traces Flow Between Services
When one service calls another, it passes the trace ID in a special HTTP header: X-Amzn-Trace-Id. The receiving service picks up this ID and continues the same trace. This is how one trace spans multiple services.
X-Ray with Elastic Beanstalk
Elastic Beanstalk has native X-Ray support. When you enable X-Ray in the Elastic Beanstalk environment, EB automatically installs and configures the X-Ray daemon on all instances.
How to Enable
- AWS Console: Elastic Beanstalk β Environment β Configuration β Software β Enable X-Ray
- Configuration file: Add
.ebextensions/xray-daemon.configto your app package
X-Ray Groups β Organize Your Traces
X-Ray Groups let you create named collections of traces that match a filter expression. Instead of searching every time, you define a group once and all matching traces are automatically organized in it.
responsetime > 2.Now you have a dedicated view of all slow requests, with separate service maps and metrics for just those traces.
Create another group "PaymentErrors" with filter:
annotation.service = "PaymentService" AND error = true.
π X-Ray Insights β Anomaly Detection
X-Ray Insights (not to be confused with Logs Insights) automatically detects when fault rates in your traces spike. It groups related anomalous events into "insights" so you don't have to manually notice the pattern.
- Detects sudden increases in error rates, latency spikes
- Groups related traces that show the same anomaly
- Can send notifications via SNS
X-Ray Exam Quick Reference
| Scenario / Question | X-Ray Feature to Use |
|---|---|
| Find which service in the chain is slow | Service Map β visual latency per node |
| See the detailed timing of one specific request | Trace Timeline β drill into one trace |
| Find all traces for a specific user ID | Annotations + Filter Expression |
| Attach complex JSON data to a trace for debugging | Metadata β not filterable but stores rich data |
| Only trace 10% of requests to save cost | Sampling Rules |
| Always trace payment requests but sample others | Custom Sampling Rules |
| Integrate X-Ray with Lambda (easiest way) | Active Tracing (enable in console) |
| Integrate X-Ray with Elastic Beanstalk | Enable in EB console β daemon auto-installed |
| Service B doesn't have X-Ray SDK but is in the map | Inferred Segment β auto-created by X-Ray |
| How does X-Ray SDK send data to X-Ray service? | Via X-Ray Daemon (UDP port 2000) |
| Find all errors/faults in traces | Filter Expression: error = true or fault = true |