Cloud Trace in Google Cloud
A friendly, start-to-finish guide to following a single request through every service it touches, finding exactly where the time went, and fixing slowness with confidence.
You click “Buy now” and the page spins for six seconds. Behind that click, your request may have visited a dozen programs: a front door, a login service, a shopping cart, a price checker, a database and a payment company. Somewhere in that chain, a few seconds slipped away, yet every team swears their own part was fast.
It feels like a parcel that arrives late with no tracking number. Everyone who handled it says they passed it on quickly, and nobody can prove who held it too long. What you need is a tracking page that shows each stop, with the time spent at every one.
Cloud Trace is that tracking page for software running on Google Cloud. In this guide you will learn what it is, how its pieces fit together, how to set it up safely, how to read a trace like a detective, how to control its cost, and how teams use it in real life. No earlier knowledge is needed. Every new word is explained the first time it appears.
1What Is Cloud Trace?
Cloud Trace is Google Cloud’s tool for following a single request on its journey through your system and showing exactly where the time went.
When you order something online, the shop gives you a tracking number. With that number you can see that the parcel left the warehouse, reached the sorting center, rode on a truck, and arrived at your door, with a time stamp at every stop. If the parcel is late, the tracking page shows which stop was slow. Cloud Trace gives your software the same kind of tracking page.
Each request that enters your application, such as a click on “Buy now,” can be given a tracking number. As the request travels from your website to a login service, then to a shopping cart, then to a database and a payment provider, every step records when it started and when it finished. Cloud Trace collects those records and draws them as one timeline. You can see at a glance which step was slow.
Cloud Trace is a distributed tracing system. “Distributed” means your application is spread over many programs, containers or machines. “Tracing” means following one request across all of them. It belongs to Google Cloud Observability, the family of tools that also includes Cloud Logging and Cloud Monitoring.
Imagine a relay race where each runner carries a baton and a small stopwatch. Every runner writes down the moment they received the baton and the moment they handed it on. After the race, you lay all the notes side by side and see exactly which runner lost time. Cloud Trace is the person who collects all the stopwatch notes and lays them out for you.
What Cloud Trace is good at
- Showing where a slow request spent its time, not only that it was slow.
- Revealing hidden chains of calls between services that nobody remembered existed.
- Helping teams agree on facts during a slowdown, because everyone looks at the same timeline.
- Pointing to the right team, since each step belongs to a service with an owner.
A short history in plain words
Tracing grew up with big websites. When a company has hundreds of small services, one slow page can involve dozens of them, and no single person knows the whole picture. Large companies built internal tracing tools to cope. Twitter shared one called Zipkin in 2012, and Uber later shared Jaeger. In 2019, two open projects merged into OpenTelemetry, which is now the common standard way to create trace data. Google Cloud supports sending OpenTelemetry data into Cloud Trace.
Cloud Trace is not Cloud Logging, which stores written messages, and it is not Cloud Monitoring, which stores numbers over time. All three work together, and later chapters show how. Trace answers one question the others answer poorly: “Why was this particular request slow?”
Product names, screens and limits change over time. This guide teaches ideas that stay stable, and it points out places where you should confirm current details in the official Google Cloud documentation.
2The Problem: Slow Requests in a Spread-Out World
Finding slowness was easy when an application lived in one program. It becomes a detective story once the application is split into many parts.
In the old days, many applications were a single big program, called a monolith. If a page was slow, a developer could run a profiler inside that one program and see which function was guilty. Everything happened in one place, so one tool could see everything.
Modern systems often use microservices, which are many small programs that each do one job and talk to each other over the network. This brings freedom, because teams can change their own service without waiting for others. It also brings a new problem. A single click may touch ten services, and each service only knows about its own small piece of the story.
A monolith is a small family restaurant where one cook makes the whole meal, so you can watch the cook and see why dinner is late. Microservices are a huge food court with twenty stalls. Your meal needs a burger from one stall, fries from another and a drink from a third. If the meal is late, you must ask each stall what happened, and each stall says “we were fast.”
Why logs and metrics are not enough alone
Logs are written messages from each service. They tell you what that service saw, but they are scattered over many places and hard to line up in time. Metrics are numbers such as average response time. They tell you that something is slow, but an average hides the details of any single request.
Suppose your checkout page has an average response time that looks fine, yet some customers wait ten seconds. Metrics show the average, not the unlucky ones. Logs from ten services show ten partial stories. A trace is the one thing that ties the stories into a single timeline for one request.
| Tool | What it is | Best question it answers | Weak spot |
|---|---|---|---|
| Logs | Written messages about events | What exactly happened in this service? | Hard to connect across services |
| Metrics | Numbers measured over time | Is the system healthy right now? Is it getting slower? | Hides individual requests |
| Traces | Timed steps of one request across services | Where did this slow request spend its time? | Only a sample is usually kept |
The cost of not knowing
Without tracing, teams argue. The frontend team says the database is slow, the database team says the network is slow, and the network team says the frontend asks for too much. Hours pass. With tracing, the timeline is shared evidence, and the discussion becomes “step seven took four seconds, who owns step seven?”
Invisible chains
Services call other services, which call more services. Nobody sees the full chain.
Averages that lie
A healthy average can hide a group of very unhappy users.
Blame games
Without shared evidence, every team believes the problem is elsewhere.
Slow detective work
Matching time stamps across many log files is boring and error-prone.
3Core Concepts From Zero
A handful of words carry almost all of tracing. Learn them once and every screen, document and tool will make sense.
Trace
A trace is the complete record of one request as it travels through your system. It has a unique trace ID, a long string of letters and numbers that works like a tracking number. In Cloud Trace and in the common standards, a trace ID is a 32-character hexadecimal value, which means it uses the digits zero to nine and the letters a to f.
Span
A span is one timed piece of work inside a trace. It has a name such as “GET /checkout” or “query orders table,” a start time, an end time, and a span ID of its own. A trace is a collection of spans, much like a book is a collection of chapters.
Parent, child and root
Spans form a family tree. The first span, which represents the whole request arriving, is the root span. When that work calls another piece of work, a child span is created, and the first one becomes its parent. Each child remembers its parent’s span ID, which is how the tree is rebuilt later.
Attributes, events and status
Attributes (older tools call them labels) are small notes attached to a span, such as the HTTP method, the page route or the database name. Events are time-stamped moments inside a span, like “cache miss” or “retry started.” Status says whether the span succeeded or failed, so errors can be found quickly.
Latency and percentiles
Latency is the time something takes. Because averages hide problems, engineers use percentiles. The 50th percentile, or p50, is the typical request: half are faster and half are slower. The 95th percentile, p95, means that ninety-five out of a hundred requests are faster than this value. The 99th percentile, p99, shows the slow tail that your unluckiest one percent of users experience.
Context propagation
Context propagation means passing the trace ID and the parent span ID from one service to the next, usually inside a request header. Without it, each service would start a new unrelated trace, and the timeline would fall apart into pieces.
Instrumentation and sampling
Instrumentation is the act of adding tracing to your code, either automatically through a helper library or manually by creating spans yourself. Sampling means keeping only a portion of all traces to save cost and storage, for example one request out of every hundred.
| Term | Simple meaning | Everyday picture |
|---|---|---|
| Trace | The full story of one request | A parcel’s whole tracking page |
| Span | One timed step in the story | One line of the tracking page, such as “arrived at depot” |
| Root span | The first, outermost step | The parcel leaving the warehouse |
| Child span | A step started by another step | A smaller delivery by a local courier |
| Attribute | A small note on a span | A sticky label saying “fragile” |
| Propagation | Passing the tracking number along | Writing the number on every new box |
| Sampling | Keeping only some traces | Checking one parcel in every hundred |
| p99 latency | The slowness of the unluckiest one percent | The very latest parcels of the week |
Think of a family tree for one meal order in a restaurant chain. The order ticket is the trace. The ticket’s first line, “table seven ordered dinner,” is the root span. Under it are child lines such as “grill cooked steak,” “kitchen made salad” and “bar poured drinks,” and under “grill cooked steak” there might be “fetched steak from fridge.” Each line has a start and finish time, so the family tree also shows who kept the table waiting.
4Anatomy of a Trace: Reading the Timeline
The best way to understand tracing is to follow one imaginary request through a small online shop.
A customer presses “Place order.” The request reaches a load balancer, which hands it to a frontend service. The frontend asks a cart service for the items, and the cart service reads from a database. Then the frontend asks a payment service to charge the card, and the payment service calls an outside payment provider. Finally the frontend answers the customer.
flowchart LR
U["User browser"] --> LB["Load balancer"]
LB --> FE["Frontend service"]
FE --> CT["Cart service"]
CT --> DB[("Database")]
FE --> PY["Payment service"]
PY --> EXT["External payment provider"]
Now look at the same journey in time order. Each arrow below will become part of a span in the trace.
sequenceDiagram participant U as User participant F as Frontend participant C as Cart service participant D as Database participant P as Payment service U->>F: Place order F->>C: Get cart items C->>D: Read items D-->>C: Items C-->>F: Cart F->>P: Charge card P-->>F: Approved F-->>U: Order confirmed
The waterfall view
Cloud Trace shows a trace as a waterfall. Each span is a horizontal bar. The bar starts where the span started and ends where it ended, so longer bars mean more time. Child spans are drawn below their parent and slightly indented. The top bar, the root span, covers the entire request, and the smaller bars show how that time was divided.
Reading a waterfall is a skill that comes quickly. Look first for the longest bars. Then look for gaps, which are places where the parent was waiting and no child was working. Then look for bars stacked one after another that could run side by side. These three clues explain most slow requests.
| Span name | Parent | Starts at | Takes |
|---|---|---|---|
| POST /order (root) | none | 0 ms | 1,150 ms |
| get cart items | POST /order | 10 ms | 140 ms |
| query items table | get cart items | 30 ms | 110 ms |
| charge card | POST /order | 160 ms | 950 ms |
| call payment provider | charge card | 200 ms | 880 ms |
In this made-up example, the request took 1,150 milliseconds. The cart service used about 140 of them, which is fine. The payment step used 950, and nearly all of that was the call to the outside provider. The trace makes the answer obvious: the slow part is not your database, it is the external provider.
A waterfall view is like the schedule bar chart on a building site. Each task is a bar placed along a calendar. One glance tells you which task is longest, which tasks wait for others, and which could be done in parallel to finish sooner.
Always ask three questions of any trace: Which span is longest? Where is the empty gap? Which spans run one after another that could run together? Write the answers down, and you already have a useful finding.
5Architecture and Components
A tracing system has a few simple parts: something that creates spans, something that sends them, and something that stores and shows them.
flowchart TD APP["Your application code"] --> SDK["OpenTelemetry SDK creates spans"] SDK --> EXP["Exporter for Google Cloud"] SDK --> COL["OpenTelemetry Collector optional"] COL --> EXP EXP --> API["Google Cloud trace ingestion"] GCP["Some Google Cloud services"] --> API API --> STORE["Trace storage with limited retention"] STORE --> TE["Trace Explorer in the console"] STORE --> LOGS["Links with Cloud Logging"] STORE --> MON["Links with Cloud Monitoring"]
Part 1: the code that creates spans
Inside your application, a tracing library watches important moments. When a request arrives, it starts a root span. When your code calls a database or another service, it starts a child span. When the work ends, it closes the span and records the finish time. Today, the most common library family for this is OpenTelemetry, often shortened to OTel.
Part 2: the exporter
Finished spans are not sent one by one, because that would slow your app. They wait in a small memory buffer, and an exporter sends them in groups to Cloud Trace in the background. Google provides an exporter for OpenTelemetry. There is also a newer route that accepts OpenTelemetry’s own data format directly, so check current documentation to see which route fits your language and platform.
Part 3: the optional collector
The OpenTelemetry Collector is a small separate program that receives spans from many applications, can process them, and forwards them. Teams use it to centralize settings, to add or remove attributes, to keep fewer traces by smart sampling, and to avoid putting export logic inside every service. It is optional, but it grows more helpful as a company grows.
Part 4: ingestion, storage and the screens
Cloud Trace receives spans through an API, checks permissions, groups spans by trace ID, and stores them for a limited time, which is about thirty days at the time of writing. You then search and view traces in Trace Explorer in the Google Cloud console. Links connect traces to logs and metrics, so you can move between the three without losing your place.
| Component | Main job | Who owns it |
|---|---|---|
| Tracing library (SDK) | Create spans, record times and attributes | Application team |
| Exporter | Send finished spans to Cloud Trace | Application or platform team |
| Collector | Receive, process and forward spans for many services | Platform team |
| Cloud Trace ingestion | Accept, check and store spans | Google Cloud |
| Trace Explorer | Search and display traces | Everyone who investigates |
| IAM | Allow or refuse writing and reading traces | Security and platform teams |
Picture a newspaper. Reporters in the field write short notes (spans). A courier gathers notes from many reporters and delivers them in bundles (exporter and collector). The newsroom files them into an archive by story number (ingestion and storage). Readers then open a story and see all the notes together (Trace Explorer).
6Context Propagation: Keeping the Thread Connected
If the tracking number is lost between two services, the trace breaks in half. Propagation is the habit that prevents this.
When service A calls service B, A adds a small piece of information to the request, usually in an HTTP header. This piece says “you are part of trace number so-and-so, and my span is the parent.” Service B reads it, makes its own spans inside the same trace, and passes the same information on when it calls service C.
sequenceDiagram participant A as Service A participant B as Service B participant C as Service C Note over A: Creates trace ID and root span A->>B: Request with trace context header Note over B: Reads header and creates child span B->>C: Request with same trace ID and new parent span C-->>B: Response B-->>A: Response
The headers in use
The modern standard is called W3C Trace Context, and its main header is named traceparent. It carries a version, the trace ID, the parent span ID and a flag that says whether the trace is being kept. Google Cloud also has an older header named X-Cloud-Trace-Context, and Google Cloud load balancers and some other products can add it to incoming requests. Modern libraries can read and write both, so mixed systems can still produce connected traces.
Where propagation breaks
- A service that forgets to pass the header on. A custom HTTP client or a proxy that drops unknown headers makes the trace split into two separate traces.
- Different standards in different services. If one service writes only an old format and the next reads only the new one, the link is lost.
- Background work. A job picked from a queue starts with no request around it, so it needs the context to be saved with the message.
- Third-party services. Outside providers usually do not continue your trace, so you see one span for the whole call and nothing inside it.
Messages and queues
Many systems hand work from one service to another through a message queue, such as Pub/Sub. The sender is not waiting for the receiver, so no live request carries the header. The usual solution is to put the trace context inside the message’s attributes. The receiver reads it and either continues the same trace or starts a new trace that is linked to the original, which is a way of saying “this work was caused by that request.”
Think of a paper form with a case number stamped on the top. Every office that handles the form writes the case number on any new paper they create. If one office forgets, the new paper has no number, and the clerk at the end cannot connect it to the original case. Propagation is the habit of copying the case number every single time.
Do not trust that propagation “just works” after you add tracing to the first two services. Test with one request that crosses every service on its way, then open the trace and confirm that all expected services appear in one waterfall.
7Instrumentation: How Spans Get Created
There are several ways to add tracing to an application. Choosing a path early saves a lot of confusion later.
Automatic instrumentation
Automatic instrumentation uses ready-made helpers that watch popular libraries, such as web frameworks, HTTP clients and database drivers, and create spans without changes to your business code. In some languages, a helper can be attached when the program starts. This is the quickest way to get a first useful trace and is a good starting point for beginners.
Manual instrumentation
Manual instrumentation means you create spans yourself around work that matters, such as “calculate shipping” or “apply discount rules.” You choose the span names and add attributes that make sense for your business. It takes more effort, but it shows your own logic and not only the technical plumbing.
The standards and older libraries
OpenTelemetry is the recommended standard for new work. An older project called OpenCensus was a predecessor and has been retired, so new code should avoid it. Google Cloud also offered its own earlier client libraries for Cloud Trace. Treat those as older routes and prefer OpenTelemetry unless a platform guide says otherwise.
Auto helpers
Attach a helper at start-up, and common libraries are traced automatically. Great for a first demo.
Manual spans
Wrap your own important steps so traces speak the language of your business.
Collector
Send spans to a shared collector that applies company-wide rules for sampling and cleaning data.
Retired libraries
Do not build new systems on retired tracing libraries. Plan a move to OpenTelemetry if you still use them.
| Path | Effort | Detail level | Good for |
|---|---|---|---|
| Auto helpers only | Low | Technical calls such as HTTP and database queries | First traces, quick wins |
| Auto plus a few manual spans | Medium | Technical and key business steps | Most production services |
| Fully manual | High | Exactly what you choose | Special runtimes or strict control |
| Through a collector | Medium to high setup | Same as the above, with central rules | Many teams and many services |
What makes a good span
- A stable, low-variety name. Use the route pattern such as “GET /orders/{id}” and not the actual order number. Otherwise you create millions of different names that cannot be grouped.
- Useful attributes. Add the region, the customer plan type, or the feature flag in use, since these help filtering later.
- The right size. A span should cover a meaningful piece of work, not every tiny loop turn.
- Honest status. Mark a span as failed when it fails, so you can search for errors.
Automatic instrumentation is a security camera that films every doorway in a building. It shows who moved through each door without you doing anything. Manual instrumentation is a notebook where a guide writes “VIP tour started” and “gift shop reached.” The camera gives coverage, and the notebook gives meaning. The best systems use both.
8Designing Good Span Names and Attributes
Spans are only as useful as their names and notes. A few simple rules turn a noisy trace into a clear story.
When you open a waterfall, the first thing you read is the span names. If the names are clear, you understand the story at a glance. If they are vague or random, you must open every span to learn anything. Good naming is the cheapest improvement you can make to a tracing system.
Naming rules
- Describe the operation, not the data. “GET /orders/{id}” is a good name. “GET /orders/84721” is a bad one, because it changes with every request.
- Keep the number of different names small. A system should have hundreds of span names, not millions. Names are used for grouping and searching.
- Use a verb and a noun for business steps. “calculate shipping” and “apply discount” read like plain sentences.
- Be consistent across services. If one team writes “db query” and another writes “database call,” shared filters will miss half the spans.
Attribute rules
Attributes are the notes that make filtering possible. Choose them by asking “what question will someone ask during an incident?” Typical questions are: Which region? Which version of the service? Which type of customer? Which feature switch was on? Which database was used? Add attributes that answer these questions.
The OpenTelemetry project publishes common naming conventions for attributes such as the HTTP method, response status and database system. Following these shared conventions helps tools understand your data and helps new teammates read it. Because the conventions evolve, check the current version when you set a team standard.
| Idea | Good example | Poor example | Why |
|---|---|---|---|
| Span name | GET /orders/{id} | GET /orders/84721 | Stable names group well |
| Business step | apply discount | function2 | People can read it |
| Attribute for filtering | customer plan: premium | customer email: full address | Useful without exposing personal data |
| Version | service version: 2.4.1 | nothing recorded | Lets you compare releases |
| Count | items in cart: 12 | one span per item | Detail without span explosion |
Spans have limits on how many attributes they hold and how long values can be. Very large values may be cut off or rejected. Keep attributes short and few. Never place whole documents or large message bodies inside a span.
A library works because every book has a clear title and a few standard labels: author, subject and shelf number. If each book were named with a random number and had sticky notes in different styles, nobody could find anything. Span names are titles, and attributes are the catalog labels.
9Getting Started: Your First Trace
The path to a first visible trace is short. Follow the order, and each step prepares the next.
Choose a practice project
Use a development project with a budget alert. Tracing is gentle on cost at low volume, but a practice project keeps learning safe and separate from real customers.
Enable the Cloud Trace API
Google Cloud services are switched off until you enable them in the project. Without this step, exports are refused, and the error can look confusing.
Give your app permission to write traces
The identity your app runs as, usually a service account, needs a role that allows writing trace data. The standard role is Cloud Trace Agent. Grant it to that one identity and nothing broader.
Add OpenTelemetry to the app
Follow the current guide for your language to add the tracing library, attach automatic helpers, and point the exporter at Google Cloud. Give your service a clear name so it is easy to find later.
Deploy and send some requests
Deploy the app to a platform such as Cloud Run, GKE or Compute Engine, then open a few pages or call a few endpoints. With a low sample rate you may need to send many requests. For learning, temporarily keep all traces.
Open Trace Explorer
In the console, go to Trace and open Trace Explorer. Choose a recent time range, and you should see your requests as dots or rows. Click one to open the waterfall.
Add one manual span and one attribute
Wrap one business step in a span and add a helpful attribute. Send another request, and find that step in the waterfall. This is the moment tracing starts to feel useful.
If nothing shows up, do not guess. Check, in order, that the API is enabled, that the identity has permission, that the app has no export errors in its own logs, and that your time range includes the moment you sent requests. A later chapter gives a full decision path.
Setting up tracing is like installing a mailbox. You must have a street address (the project), permission from the post office to deliver there (the API and role), a mailbox attached to your door (the library and exporter), and then you wait for the first letter to arrive. If no letter comes, you check each of those in order.
10Identity and Permissions for Tracing
Two groups of identities touch Cloud Trace: programs that write spans and people who read them. Each needs its own narrow permission.
Writers: the programs
Your application runs under an identity, commonly a service account. To send spans, that identity needs permission to write traces. The ready-made role for this is Cloud Trace Agent. On Cloud Run and GKE, the identity attached to the service or workload is the one that matters, so check which service account the platform is really using, not the one you assume.
Readers: the people
Engineers who investigate need to read traces. The ready-made role Cloud Trace User allows viewing, and Cloud Trace Admin allows more control. Most investigators need only the user role. Granting it to a group, and not to individuals, keeps reviews and removals simple.
| Who | Needs to | Typical role |
|---|---|---|
| Application service account | Send spans | Cloud Trace Agent |
| Engineers and on-call staff | Search and read traces | Cloud Trace User |
| Platform administrators | Manage settings across the project | Cloud Trace Admin, used sparingly |
Common permission problems
- Permission denied on export. The app’s service account lacks the writer role. Grant the agent role to that account.
- API not enabled. The error mentions that the Cloud Trace API has not been used. Enable it in the project.
- Engineer sees an empty page. The engineer is looking at the wrong project, or lacks the reader role.
- Cross-project confusion. Services in one project may send traces to another project. Check which project the exporter points to, because traces appear only in the project that received them.
A library lets some people drop off books at the return slot and others borrow books from the shelves. The return slot opens for anybody with a delivery badge but shows nothing inside. Reading privileges are separate. Cloud Trace works the same: the agent role drops spans in, and the user role looks inside.
Resist the urge to give an app a broad project-wide role so that “tracing starts working.” Grant only the writer role, and avoid creating downloadable key files. Use the identity attached to the platform instead.
11Trace Explorer: Finding the Needle
Millions of requests may flow through a system each day. Trace Explorer helps you pick out the few that matter.
Trace Explorer is the main screen in the Google Cloud console for working with traces. Its layout may change over time, but the ideas stay the same: choose a time range, filter down to the requests you care about, look at how they are spread out in time, then open one to read its waterfall.
Step 1: set the time range
Choose the period of the problem, such as “the last hour” or “yesterday between two and four in the afternoon.” Narrow ranges load faster and make patterns clearer. If an incident has just ended, widen the range a little on both sides to include normal behavior for comparison.
Step 2: filter
You can filter by service, by span name, by status, by minimum latency, and by attributes you added. A useful first filter is “slow requests to one route.” Another is “failed spans in the payment service.” Good attributes such as region or customer plan make these filters much more powerful, which is why meaningful attributes matter so much.
Step 3: look at the shape
The screen shows a chart where each trace is a point placed by time and latency. Clusters tell stories. A thin band high above the rest suggests a special slow case. A cloud that suddenly moves up at one moment suggests a change, such as a deployment or an outage in a dependency. A second band running parallel to the first may suggest two different code paths with different speeds.
Step 4: open a trace
Click a point to open its waterfall. Look for the longest bar, the empty gaps, and the stacked steps. Open span details to read attributes and events. Follow links to related logs, so you see the exact messages that were written during this very request.
Step 5: compare
One trace is a clue, but two make a comparison. Open a slow trace beside a fast trace of the same route. The span that grew is your suspect. This habit turns “it feels slow” into “the inventory call took 40 ms normally and 1,900 ms in the slow case.”
Narrow the time
Match the window to the problem.
Filter to one route or service
Remove everything unrelated.
Study the cloud of points
Look for bands, jumps and outliers.
Open one slow and one fast trace
Compare the waterfalls side by side.
Jump to logs
Read what the service said while the slow span ran.
Trace Explorer is like a flight-tracking website. You first pick the day and the airline, then see a map of all planes. Most follow normal routes, but one is circling far from the others. You click that plane and read its details. The skill is not in watching every plane, but in noticing the odd one and then looking closely.
Because only a sample of traces may be kept, a missing example does not prove a problem never happened. If you cannot find a slow trace you expect, temporarily raise the sampling rate and try again.
12Reading Patterns: What Slow Traces Look Like
Slow requests are slow in a handful of recognisable ways. Learn the shapes, and diagnosis becomes quick.
The long single bar
One span takes most of the time. The cause is inside that step, such as a heavy query or a slow outside provider. Start there.
The staircase
Many spans run one after another, each short, but together long. They may be able to run in parallel.
The comb
Dozens of tiny identical spans in a row, such as a database query repeated in a loop. This is the famous N plus one pattern.
The gap
A parent span is long while its children are short, leaving empty space. Time was spent waiting or working in code that has no span.
The retry ladder
The same call appears two or three times with failures before success. Each retry adds delay and load.
The late start
The first span begins long after the request arrived. On serverless platforms this can be a cold start while a new instance boots.
Two ideas worth explaining
N plus one queries. Imagine a page that shows a list of fifty orders. The code asks the database for the list once, and then asks again for each order’s customer, one at a time. That is one plus fifty queries. In a trace it looks like a comb of fifty small bars. The fix is often a single combined query. This pattern is invisible in averages and very clear in a waterfall.
The critical path. When some work happens in parallel, only the longest branch decides the total time. That branch is called the critical path. Speeding up a step that is not on the critical path changes nothing for the user. Traces show which steps are on the path, so you do not waste effort tuning the wrong thing.
| Pattern in the waterfall | Likely cause | Typical fix |
|---|---|---|
| One very long span | Slow query, heavy computation, slow dependency | Optimise that step, add an index, add a cache, or set a time limit |
| Many short serial spans | Calls made one at a time | Run independent calls in parallel |
| Comb of repeated spans | Repeated queries inside a loop | Batch the queries into one |
| Large gap inside a parent | Untraced code, waiting for locks or threads | Add spans around the gap, review waiting behavior |
| Repeated failing calls | Retries against an unhealthy dependency | Use backoff, circuit breakers and sensible limits |
| Delay before the first span | Cold start or queueing before the app code | Keep minimum instances warm, reduce start-up work |
Picture a shopper with a list of ten items. A slow shopper walks to the shelf, picks one item, walks back to the cart, then walks to the shelf again for the next. The path on a security camera would show ten short trips, the comb. A faster shopper picks all ten items in one trip. The trace is the security-camera recording that shows how many trips were taken.
13Databases, Caches and Outside Calls
Most of the time in a typical request is spent waiting for someone else. Tracing these waits is where the biggest wins hide.
Databases
A database is a program that stores and finds data. Your application sends it a query, which is a question such as “give me all orders for this customer.” Automatic helpers can create a span for each query and record the type of database and a shortened form of the query. A slow query appears as a long bar. Many repeated queries appear as a comb.
Be careful about recording the full text of queries. Query text may contain customer data if values are written inside it. Prefer recording a template of the query with placeholders and not the actual values, and follow your privacy rules.
Caches
A cache is a fast storage place for answers you may need again soon, such as a stored copy of a product page. A cache lookup normally takes a tiny fraction of the time of a database query. Spans for cache lookups, with an attribute that says “hit” or “miss,” let you measure how often the cache saves time. A sudden growth in misses often explains a sudden slowdown, because every miss now falls through to the slower database.
Outside calls
Your service may call a payment company, a mapping service or an email provider. You cannot see inside them, but you can see how long you waited. Create a span for each such call, and record the status and the number of retries. When an outside provider has a bad day, your traces will prove it with clear evidence you can share with them.
Watch for combs
Repeated tiny query spans show an N plus one pattern. Combine them into a single query.
Record hit or miss
A simple attribute shows whether the cache is helping and when it stops helping.
Time and retries
Capture how long you waited and how many tries it took, so you can prove who was slow.
No raw values
Record templates and counts, not customer data, in query and call spans.
flowchart TD
REQ["Incoming request"] --> CK{"Is the answer in the cache?"}
CK -->|Hit| FAST["Return the cached answer quickly"]
CK -->|Miss| DBQ["Query the database"]
DBQ --> SAVE["Store the answer in the cache"]
SAVE --> RESP["Return the answer"]
FAST --> RESP
Imagine a teacher who gets the same question many times. Writing the answer on a small card in the pocket is the cache. If the student asks something new, the teacher walks to the library, which is the database. The trip to the library takes much longer. A trace is a stopwatch that shows how many questions were answered from the pocket and how many needed the trip.
14Sampling: How Many Traces to Keep
Keeping every trace of a busy system is expensive and often unnecessary. Sampling is the art of keeping enough to learn and no more.
A busy service may handle thousands of requests every second. Each request can create many spans, and every span has a cost to create, send and store. Most requests look nearly identical. So systems keep only a portion, and that portion is chosen by a rule called a sampling policy.
flowchart TD
R["Request arrives"] --> Q{"Does the incoming context already say sampled?"}
Q -->|Yes| K["Keep and record spans"]
Q -->|No decision| S{"Does a random draw fall below the sampling rate?"}
S -->|Yes| K
S -->|No| D["Do not record spans"]
K --> E["Export spans to Cloud Trace"]
Head-based sampling
In head-based sampling, the decision is made at the very start of the request, before anyone knows how it will turn out. A random draw decides, for example, to keep one request in a hundred. The decision is then passed along in the trace context, so every service in the chain agrees. This is simple and cheap, but it may miss the rare slow or failed requests you most want to see.
Tail-based sampling
In tail-based sampling, the decision is made after the request finishes, when its outcome is known. A collector can hold the spans for a short time and then keep every trace that was slow or failed, plus a small portion of normal ones. This keeps the interesting traces, but it needs more memory and a more careful setup, because all spans of a trace must reach the same collector.
Head-based sampling
- Simple to set up
- Very cheap to run
- Consistent across services
- May miss rare errors and slow outliers
Tail-based sampling
- Keeps slow and failed traces on purpose
- Gives better value per stored trace
- Needs a collector and more memory
- More complex to run and to tune
Choosing a rate
A common approach is to begin with a higher rate in development and test, such as keeping everything, and a small rate in production. Increase the production rate if you find yourself unable to locate examples. Lower it if costs or overhead grow. Many teams also choose a rule such as “always keep traces with errors” when their tools allow it.
A quality inspector at a factory cannot open every single box. Head-based sampling is checking every hundredth box as it passes. Tail-based sampling is waiting until boxes are sealed, and then opening every box that a customer later complained about, plus a few random ones. The second way finds more problems, but it needs more room to hold the boxes while deciding.
Sampling affects counts. If you keep one request in a hundred, the number of traces you see is not the real number of requests. Use metrics, not trace counts, to measure traffic.
15Data Flow and Lifecycle of a Trace
Follow a single span from the moment it is born to the day it expires, and you will understand every setting along the way.
flowchart LR A["Request starts: root span created"] --> B["Child spans for calls and queries"] B --> C["Spans end and wait in a buffer"] C --> D["Batch export runs in the background"] D --> E["Cloud Trace ingests the spans"] E --> F["Trace is stored and searchable"] F --> G["Engineer investigates in Trace Explorer"] F --> H["Data expires after the retention period"]
Birth
A request arrives. The library checks for incoming context. If there is none, it creates a new trace ID and a root span and makes the sampling decision.
Growth
As your code calls a database or another service, child spans are created. Outgoing calls carry the context so downstream services continue the trace.
Finishing
Each span ends and records its end time, status and attributes. A finished span is placed into a memory buffer.
Export
A background worker takes spans from the buffer in batches and sends them to Cloud Trace. This keeps your request fast, since the user never waits for the export.
Ingestion
Cloud Trace checks permissions and quotas, accepts the spans, and groups them by trace ID. Spans from different services join the same trace.
Use
After a short delay, the trace can be searched and opened. Engineers read it, and links connect it to logs and metrics.
Expiry
After the retention period, which is about thirty days at the time of writing, the data is removed. If you need long-term records, save summaries or findings elsewhere, such as in an incident report.
Why the delay matters
Spans are exported in the background and from different services at slightly different moments. A trace may therefore look incomplete if you open it extremely soon after the request, with some services still missing. If a trace looks short, wait a minute and reload before concluding that propagation is broken.
Think of the life of a letter. It is written (born), picked up with other letters at the mailbox (buffered), sent on a truck in a bag (batch export), sorted at the main depot (ingestion), delivered to a reader (use), and finally thrown away after the retention period. Nobody expects the reader to hold a letter the second the writer finishes it.
16Inside the Tracing Library
A short look at what happens inside your application explains why tracing is light, and why it sometimes loses data.
The tracer and the current context
The library keeps track of “which span am I currently inside” for each running piece of work. This is the current context. When your code starts a new span, the library looks at the current context and makes the new span a child of it. When the span ends, the context steps back to the parent. In programs that handle many requests at once, each request has its own context so that spans never get mixed up.
The span processor and the buffer
When a span ends, it is handed to a span processor. The usual choice is a batching processor. It stores spans in a queue of limited size and sends them in groups after a short time or when the group is full. This is efficient, because sending many spans in one network call is much cheaper than sending each separately.
What can go wrong
- Full buffer. If a service creates spans faster than it can export them, the queue fills, and new spans are dropped. This protects your app, but you lose data.
- Shutdown before export. If the program exits right after a request, spans still waiting in the buffer may never be sent. Short-lived jobs must flush the buffer before they exit.
- CPU-throttled instances. On some serverless platforms, background work may be slowed when no request is active, which can delay exports. Check platform guidance on this.
- Clock differences. Different machines have slightly different clocks. A child span may appear to start a little before its parent. Do not over-read tiny differences between services.
The overhead
Creating a span takes very little time, usually a tiny fraction of a millisecond, and most of the work is done in the background. Even so, overhead is not zero. Adding thousands of spans to one request, or storing large attributes on each, can slow the service and increase costs. Measure the effect in a test environment, and keep spans meaningful.
A waiter jots short notes on a pad as the meal progresses, a very small effort. At the end of each hour, the waiter hands the pad to the kitchen manager. If the pad is tiny and the waiter is very busy, notes might be skipped. If the waiter leaves suddenly without handing in the pad, the notes are lost. The pad is the buffer, and the hand-in is the export.
17Async and Event-Driven Work
Not every request waits for an answer. Some work is handed off and finished later, and tracing must follow it across the gap.
In an event-driven system, one service publishes a message, such as “order placed,” and other services react to it whenever they are ready. The sender does not wait. This makes systems flexible and resilient, but it also breaks the simple picture of a request moving in a straight line.
Two ways to connect the pieces
Continue the same trace. The receiver reads the trace context stored in the message and creates spans inside the original trace. The waterfall then shows the delay between the message being published and being processed. This is simple to read for short, one-to-one chains.
Start a new trace with a link. The receiver starts a fresh trace and adds a link that points back to the original span. This suits long delays, fan-out to many receivers, or batches that combine many messages, because one giant trace with hours of waiting would be unreadable.
What to look for
- Queue delay. The time between publish and start of processing is often the biggest part of the end-to-end time. It grows when receivers are overloaded.
- Retries and redelivery. A message that fails may be delivered again. Several processing spans for one message show repeated failure.
- Fan-out. One event can trigger many receivers. Links help you see them all as part of the same cause.
- Batch jobs. A scheduled job has no incoming request. Create a root span for each run and record the number of items processed as an attribute.
| Situation | Best approach | Reason |
|---|---|---|
| Short delay, one receiver | Continue the same trace | One simple timeline |
| Long delay or many receivers | New traces with links | Readable, with the cause still visible |
| Scheduled batch job | One root span per run | No request exists to continue |
| Function reacting to an event | Read context from the event, flush before exit | Instances may stop right after finishing |
Sending a letter is different from making a phone call. In a call, both people are on the line, and you can time the whole conversation. With a letter, the time includes sitting in the mailbox, traveling, and waiting on the other person’s desk. A good tracking system for letters must record when it was posted and when it was opened, not only the work done in between.
For asynchronous systems, a metric for “age of the oldest unprocessed message” is a valuable partner to traces. The metric warns you that work is piling up, and the traces show what the slow processing steps look like.
18Connecting Traces With Logs
A trace tells you which step was slow. A log tells you what that step was saying while it was slow. Together they close the case.
The key idea is simple: write the trace ID and span ID inside every log line. Cloud Logging has special fields for these values. When a log entry carries the trace field in the expected format, which includes the project name and the trace ID, Google Cloud can link the log line to its trace. In the console, you can then jump from a span to the logs written during it, and from a log line to its trace.
Many logging libraries can add these fields for you when tracing is active. On some Google Cloud platforms, such as Cloud Run, there are also ready ways to connect logs written to standard output with the incoming trace header. Check the current platform documentation for the exact conditions, because the details depend on how logs are written.
Span to logs
You see a slow span, click to view the messages written during exactly that time and request.
Log to trace
You read an error message, click to see the whole journey of the request that caused it.
One ID to rule all
Search all logs of all services using one trace ID to see the complete conversation of a request.
Structured logs
Logs written as labeled fields, not loose text, are easier to filter and to connect.
A trace is the flight path of one airplane drawn on a map. The logs are the cockpit recordings. If you only have the map, you know the plane circled for twenty minutes but not why. If you only have the recordings, you hear words but cannot tell where the plane was. The shared flight number connects the two.
Add the trace ID to the error response or to a support code shown to users. When a customer reports “something broke,” support can paste that value into Cloud Trace and Cloud Logging and find the exact request within seconds.
Linking logs and traces does not mean logging everything. Never write passwords, tokens, card numbers or personal details into log lines or span attributes. Both systems keep data for days or longer and may be read by many engineers.
19Traces Next to Metrics, Errors and Profiles
Cloud Trace is strongest when used as part of a team of tools. Each answers a different question, and they hand work to each other.
Metrics tell you when to look
Cloud Monitoring watches numbers such as request counts, error rates and latency percentiles. An alert on p99 latency tells you that users are suffering right now. The alert gives you a time and a service, and those become your filters in Trace Explorer. Some metric charts can also show example traces for a data point, a feature often called exemplars. Availability depends on the type of metric and on the platform, so check current documentation.
Error tools tell you what failed
Error Reporting groups similar crashes and exceptions, showing how many times each occurred. When an error group looks important, you can search for a trace that contains a failed span from the same service and time to see what the request was doing when it broke.
Profilers tell you why code is slow
A trace shows that one span was slow, but not which lines of code inside it burned the time. Cloud Profiler samples your running program continuously and shows which functions use the most processor time or memory. Use the trace to find the slow step, then use the profiler to look inside it.
| Question | Best first tool | Then move to |
|---|---|---|
| Is something wrong right now? | Cloud Monitoring dashboards and alerts | Trace Explorer for examples |
| Which step of this request was slow? | Cloud Trace | Logs for that span |
| What did the service say at that moment? | Cloud Logging | Trace for the surrounding journey |
| How often does this error occur? | Error Reporting | Trace for an example request |
| Which function inside the slow step burns time? | Cloud Profiler | Code change, then verify in Trace |
A hospital has a monitor that beeps when a heartbeat is unusual (metrics), a chart of what happened to one patient during their stay (trace), a nurse’s written notes (logs), a list of repeated complaints (error reports), and an X-ray that looks inside one organ (profiler). A good doctor uses all of them in order, not just one.
20Latency Budgets and Service Level Objectives
Tracing is not only for emergencies. It is also a planning tool that helps teams decide how fast each part of a request is allowed to be.
A service level objective, or SLO, is a promise about quality that a team makes to itself, such as “ninety-nine percent of checkout requests finish in under one second.” The measurable number behind such a promise is called a service level indicator. Latency percentiles are common indicators, and they come from metrics. Traces explain what stands behind those numbers.
The latency budget
A latency budget splits the total allowed time among the steps. If checkout may take one second, the team might allow 100 milliseconds for the frontend, 200 for the cart, 500 for payment and 200 for everything else. A trace shows how real requests spend the budget. When one step regularly uses more than its share, the team knows where to invest effort.
| Step | Budget | Measured in a typical trace | Verdict |
|---|---|---|---|
| Frontend work | 100 ms | 80 ms | Within budget |
| Cart service | 200 ms | 140 ms | Within budget |
| Payment step | 500 ms | 950 ms | Over budget, investigate |
| Everything else | 200 ms | 60 ms | Within budget |
Why percentiles and traces work together
A metric might say that p99 latency is 2.4 seconds. That is a symptom. The next move is to open traces from the slowest one percent and ask which span is consistently the longest. If the answer is always the payment call, you have a clear target. If the answer varies, the cause may be shared, such as slow start-ups after scaling up.
Error budgets and change
If an SLO allows one percent of requests to be slow, that allowance is an error budget. When the budget is nearly used up, teams slow down risky releases and work on reliability. Traces from the slow and failed requests that used the budget become the to-do list for that work.
A family trip has a fixed time to reach the destination. The plan allows one hour for breakfast, three hours for driving, and one hour for stops. After the trip, the family compares the plan to reality and learns that breakfast took two hours. Next time they leave earlier or plan a quicker breakfast. A latency budget is the trip plan, and a trace is the diary of what really happened.
21Tracing on Different Google Cloud Platforms
The idea is the same everywhere, but each platform has its own ways of helping and its own details to watch.
Some Google Cloud products can create basic trace data on their own, and some pass trace headers to your code. Others leave everything to you. Because these behaviors change as products evolve, treat the table below as a guide to ideas and confirm specifics in current documentation.
| Platform | What to expect | What you usually do |
|---|---|---|
| Cloud Run | Incoming requests may carry trace headers, and logs can be linked to them | Add OpenTelemetry in your code to see spans inside the service and for outgoing calls |
| Google Kubernetes Engine | No application spans by default, but a service mesh can add spans for traffic between services | Instrument apps, and optionally run a collector as a shared service |
| App Engine | Some standard runtimes can report basic request traces automatically | Add libraries for spans inside your code and for outgoing calls |
| Compute Engine | Nothing automatic for your own programs | Instrument apps and make sure the virtual machine’s service account may write traces |
| Cloud Run functions | Short-lived code with a request or event | Add tracing and remember to flush spans before the function finishes |
| Load balancers | External load balancers can add a trace header to requests they forward | Make sure your app reads that header so the trace starts at the edge |
Special notes
- Serverless instances come and go. Spans must be exported soon after they finish, because an instance can be frozen or removed right after the response.
- Service meshes see the network, not your code. They add spans for calls between services but cannot see inside a service. Pair them with application spans.
- Virtual machines need the right scope and identity. A machine with no permission to write traces will export without errors being obvious to the user.
Some buildings come with a few security cameras at the entrance already installed, while others are empty rooms. In both cases, if you want cameras inside the offices, you need to place them yourself. The platform provides the entrance cameras. Your instrumentation provides the ones inside.
22Many Projects, Many Teams, Many Clouds
Real companies rarely have one tidy project. Traces must cross boundaries between projects, teams and even different clouds.
Many Google Cloud projects
Large organizations split systems across several projects, one per team or environment. Traces are stored in the project that receives them. If service A in project one calls service B in project two, and each exports to its own project, the full trace may be split between two places. Teams solve this in one of two ways. One way is to send all traces to a central observability project, and the other is to use features that let you view data from several projects together. Check current documentation for the options available to your setup.
Many teams
When many teams share one tracing setup, naming and access rules matter even more. Use clear service names, a common set of required attributes, and a reader role that includes engineers who may be called to help another team. Remember that wide read access increases privacy risk, so mask sensitive data centrally.
Other clouds and on-premises systems
If part of your system runs on another cloud or in your own data center, you can still use OpenTelemetry there and send spans to Cloud Trace, or use a collector to forward them. The service account or credentials used must be handled carefully, since the program is outside Google Cloud and cannot use an attached platform identity. Some teams prefer to send all spans to a central collector, and then forward them to one or more backends. This also keeps the door open if you later change tools.
Central project
All services export to one observability project, giving one place to search and one place to control access.
Project per team
Each team keeps its own traces, which is simpler for ownership but may split cross-team traces.
Collector gateway
A shared collector receives from everywhere, cleans and samples, and forwards to the chosen backend.
Hybrid
Teams view their own traces, and a platform team has a central view for incidents that cross teams.
A national postal service has local post offices, regional depots and links to foreign postal systems. For a parcel to be trackable from one country to another, all the offices must agree on the format of the tracking number and share their scans. Traces across projects and clouds depend on the same sort of agreement.
23Security and Privacy
Traces are a detailed diary of how your system works. That diary must be protected like any other sensitive record.
Trace data can reveal internal service names, server addresses, database tables, error messages and even customer information if careless attributes are added. In the wrong hands, this is a map for attackers. For this reason, a few layers of defense are needed.
Layer 1: control who can read and write
Grant the writer role only to the identities that run your applications, and the reader role only to the groups who investigate problems. Avoid broad roles. Review the lists on a regular schedule, and remove people when they change teams.
Layer 2: keep sensitive data out of spans
Decide in advance what must never appear in a span name or attribute: passwords, tokens, full card numbers, health details, government identifiers and anything your privacy rules protect. Use harmless identifiers, such as an internal customer number or a hashed value, if you need to filter by customer. Review code in pull requests with this in mind.
Layer 3: clean data centrally
A collector can remove or mask attributes before spans leave your network. This works as a safety net when a developer forgets a rule. It should never be your only defense, but it is a strong second one.
Layer 4: respect boundaries and regulations
Organizations with strict rules about where data may live and who may reach it can place Google Cloud services inside protected perimeters and apply organization policies. Confirm in current documentation which controls apply to Cloud Trace in your setup. Also be aware that stored traces expire, but data in exports or screenshots may not.
Layer 5: protect the pipeline
Keep the collector and exporters updated, run them with minimal permissions, and avoid sending traces over untrusted networks. Prefer attached platform identities over key files.
| Risk | Example | Defense |
|---|---|---|
| Sensitive data in attributes | A full email address or card number saved in a span | Naming rules, code review, central masking |
| Over-wide read access | Every employee can read production traces | Reader role for investigators only, group-based access |
| Leaked credentials for export | A key file copied into a repository | Use attached identities, no key files, secret scanning |
| Trace used for reconnaissance | Internal addresses and table names visible to a stranger | Strict access, short retention, avoid sharing screenshots publicly |
| Trace context abuse | An outside caller sends forged trace headers to force heavy sampling | Decide whether to trust incoming context at the edge, and cap sampling |
A flight recorder is useful because it captures many private details, which is why only trained investigators may open it. If anyone could read it, or if pilots recorded their bank passwords on it, the same detail would become a hazard. Traces deserve the same careful handling.
24Monitoring the Tracing Pipeline Itself
A tracing system that quietly stops working is worse than none, because people believe it. Watch the watcher.
Tracing can fail without anyone noticing. A permission change might block exports. A new release might drop the propagation code. A full buffer might silently discard spans. Because traces are mostly used during incidents, the worst time to find out that they are missing is during an incident.
Signs of a healthy pipeline
- Fresh traces appear for each important service every hour, even at a low sample rate.
- A test request that crosses all services forms one trace with all expected services in it.
- Export errors in your application logs are close to zero.
- The count of ingested spans is steady, apart from expected daily and weekly patterns.
- Collectors report low or zero dropped spans.
Good habits
- Run a small synthetic request, a scheduled fake user action, that always produces a trace. If that trace disappears, an alarm rings.
- Alert on sudden drops in ingested spans, and on repeated export failures in logs.
- After every major change to networking, permissions or deployment tools, send one test request and look at the trace.
- Include tracing checks in your release checklist for new services.
A decision path for “no traces appear”
flowchart TD
S["No traces appear"] --> A{"Is the Cloud Trace API enabled?"}
A -->|No| A1["Enable the API in the project"]
A -->|Yes| B{"Can the service account write traces?"}
B -->|No| B1["Grant the Cloud Trace Agent role"]
B -->|Yes| C{"Is the app exporting without errors?"}
C -->|No| C1["Fix exporter setup and read the app logs"]
C -->|Yes| D{"Is sampling too low or the time range wrong?"}
D -->|Yes| D1["Raise sampling and widen the time range"]
D -->|No| E["Check network paths, quotas and the project that receives traces"]
A smoke alarm is only useful if its battery works. Sensible homeowners press the test button once a month. A synthetic request is the test button for your tracing system: it proves, on a calm day, that the alarm will sound on a stormy one.
25Cost and Performance Overhead
Tracing is inexpensive when planned, and surprisingly costly when ignored. A little arithmetic in advance prevents bad surprises.
What you pay for
Cloud Trace is generally billed by the number of spans ingested each month, with a free allowance and a price per additional amount of spans. Prices and allowances change, so read the current pricing page before you plan. Viewing and querying traces through the console is typically not the main cost driver. Span volume is.
Span volume is easy to estimate. Multiply the requests per second by the number of spans in each trace, then by the fraction you sample, then by the seconds in a month. A service with 500 requests per second and ten spans per request produces 5,000 spans every second if you keep everything, which is a very large monthly number. Keeping one percent produces fifty spans per second, a much smaller number.
How to keep volume sensible
- Lower the sampling rate for very busy, low-risk services, and keep higher rates for critical paths.
- Avoid creating spans inside tight loops. One span for the loop is usually enough.
- Drop noisy spans such as health checks and static file requests at the collector.
- Keep attributes small and few, since oversized values add storage and network cost.
- Use tail sampling to keep errors and slow requests while discarding most normal ones.
Performance overhead
The performance cost inside your app has three parts: the small time to create each span, the memory for the buffer, and the network and processor time for exporting. For most services this is small, but it grows with span count. Test with realistic traffic. If tracing noticeably slows a service, you are probably creating too many spans or sampling too much.
Think of taking photographs on a holiday. A few good photos from each place make a lovely album that is easy to browse. Photographing every single step you take fills your phone, drains the battery, and leaves you with ten thousand near-identical pictures. Sampling is choosing which pictures are worth taking.
A single loop that creates a span for every item of a large list can multiply span volume by a thousand overnight. Add a budget alert and a dashboard for ingested spans, and review them after every release.
26Advantages, Disadvantages and Trade-offs
Every tool is a bargain. Look at both sides, and choose with open eyes.
Advantages
- Fully managed, so there are no tracing servers to install, patch or scale
- Close to the rest of Google Cloud, with links to logs, metrics and errors
- Works with the OpenTelemetry standard, so your instrumentation is not locked to one vendor
- Simple permission model with ready-made roles
- Some Google Cloud products add trace data or headers for you
- Easy way to prove where time is spent, ending blame games
- Low effort to start, with a free monthly allowance at small scale
Disadvantages
- Retention is limited, so old traces expire
- Only a sample is usually kept, so rare events can be missed
- Value depends on good instrumentation and clean propagation
- Costs grow with span volume if nobody watches them
- Works best for Google Cloud workloads, and gives less to systems elsewhere
- Advanced analysis features may be fewer than in some specialised commercial tools
- Third-party services do not show their insides
Cloud Trace compared with other choices
| Choice | Strength | Weakness | Good fit |
|---|---|---|---|
| Cloud Trace | Managed, integrated with Google Cloud, simple to start | Limited retention, fewer advanced analytics | Teams running mainly on Google Cloud |
| Self-run open-source tools such as Jaeger or Zipkin | Full control, no per-span fee, runs anywhere | You operate storage, scaling and upgrades | Teams with platform skills or strict hosting rules |
| Commercial observability platforms | Rich features, one screen for everything, strong analytics | Higher cost, data leaves your cloud account | Large teams wanting advanced tools |
| Logs only | Already available | Hard to connect across services, no timeline | Very small systems |
Trade-offs to think about
Detail versus cost. More spans reveal more but cost more. Begin with automatic spans plus a few business spans, and add detail only where questions repeat.
Simplicity versus control. A managed service is easy but gives fewer knobs. A self-run tool gives knobs, and also the work of keeping it healthy.
Coverage versus effort. Tracing every service gives complete timelines, but half-traced systems give half-useful traces. Plan the rollout so that each request path is covered end to end before moving on.
Using the OpenTelemetry standard keeps the door open. If you later move to a different tracing backend, most of your instrumentation stays the same, and mainly the exporter setting changes.
27Design Patterns and Anti-patterns
Patterns are shortcuts earned by other teams’ experience. Anti-patterns are the traps they fell into.
Six helpful patterns
Trace at every boundary
Create spans where work crosses a boundary: incoming requests, outgoing calls, database queries, cache lookups and queue operations.
One standard, one collector
Use OpenTelemetry everywhere and a shared collector, so rules for sampling and cleaning live in one place.
Trace ID in every log
Automatically include trace and span IDs in logs, and show the trace ID to users in error messages.
Keep the interesting ones
Use tail sampling to always keep errors and slow requests while sampling normal ones lightly.
Standard attribute names
Agree on names such as service version, region and customer plan across teams, so filters work everywhere.
Trace-driven reviews
After each incident, attach the slow trace to the report and note which span was responsible.
Three costly anti-patterns
What it looks like
Span names include unique values such as order numbers, email addresses or full web addresses with query strings.
Why it hurts
Every request creates a new unique name, so spans cannot be grouped or compared. Searches become messy, and sensitive data may leak into names, which are often more widely visible than other fields.
Do this instead
Use stable names based on the route pattern or operation, and put variable details in carefully chosen attributes, never including secrets or personal data.
What it looks like
A span is created for every item inside large loops, or for every tiny internal function, producing hundreds of spans per request.
Why it hurts
Costs rise, waterfalls become unreadable, and the application slows down. The valuable signal drowns in noise.
Do this instead
Create one span for the whole loop, and record counts or totals as attributes. Add detail temporarily only when investigating a specific problem.
What it looks like
Tracing is added to the frontend and a couple of services, and everything else is left dark. Nobody checks that the traces connect.
Why it hurts
Waterfalls end abruptly at the first untraced service, and the missing part is exactly where problems hide. Teams lose trust in the tool and stop looking.
Do this instead
Trace one important user journey end to end first, confirm that the whole path forms a single trace, and then expand to the next journey.
28Best Practices and Common Mistakes
Small habits make traces trustworthy. Most mistakes are cheap to fix once you know them.
Best practices
- Name your services clearly. A trace with ten spans named “app” is almost useless. Use a unique, readable name per service, and include the version.
- Start with one critical journey. Pick checkout, sign-in or search, and trace it completely.
- Use standard names for common attributes. Shared conventions allow shared dashboards and filters.
- Mark errors properly. Set span status to failed and record the error message as an event.
- Set time limits on outgoing calls. A call with no limit can turn a slow dependency into a hung request. Traces will show it, but limits prevent it.
- Flush before exit. In batch jobs and functions, make sure spans are sent before the program ends.
- Test propagation after each infrastructure change. Proxies, gateways and libraries are the usual culprits.
- Review sampling and costs monthly. Systems change, and old settings may no longer fit.
Common mistakes and quick fixes
| Mistake | What happens | Better habit |
|---|---|---|
| Forgetting to enable the API | Exports are rejected, no traces appear | Enable it as part of project setup |
| Wrong service account role | Permission denied on export | Grant the Cloud Trace Agent role to the running identity |
| Traces split in half | Two short traces instead of one long one | Check that every hop passes the trace header on |
| Sampling too low to debug | Cannot find an example of the slow request | Raise sampling during investigation, keep errors with tail sampling |
| High-variety span names | Unsearchable, costly, risk of leaks | Stable names, variable details as attributes |
| Sensitive data in attributes | Privacy exposure | Naming rules, review and central masking |
| Short jobs exit early | Spans never leave the buffer | Flush and shut down the tracer cleanly |
| Reading tiny time gaps across machines | False conclusions from clock differences | Focus on large differences, not milliseconds between hosts |
29Failure Scenarios and Recovery
Both your application and the tracing pipeline can fail. Knowing the common failures keeps you calm when they appear.
| Symptom | Likely cause | First move |
|---|---|---|
| No traces at all | API off, missing permission, exporter misconfigured | Follow the decision path in the earlier chapter |
| Traces appear only for some services | Missing instrumentation or lost headers | Test one request through the whole path and see where the trace ends |
| Trace stops at a gateway or proxy | The proxy removes or does not forward the trace header | Configure the proxy to pass trace headers through |
| Traces appear in the wrong project | Exporter points to another project | Check the project setting of the exporter |
| Very few traces under heavy load | Full buffer drops spans, or sampling is too low | Raise queue sizes, add a collector, review sample rate |
| Spans missing from short jobs | Program exits before export | Flush the exporter before exit |
| Child spans appear before parents | Clock differences between machines | Synchronise clocks and avoid reading tiny offsets |
| Costs jump suddenly | A release added many spans or raised sampling | Check recent changes, reduce span volume, add alerts |
A calm response path
Confirm what you expected
Write down which trace you expected to see, with which services. A clear expectation shows where the real trace differs.
Check the application’s own logs
Export errors are usually written there, naming the permission, network or setting at fault.
Send a controlled test request
One request with sampling forced on is easier to follow than random traffic.
Walk the path hop by hop
Find the last service present in the trace. The break is between it and the next service.
Fix one thing and test again
Change a single setting, repeat the test, and write the result down for your team.
When a parcel tracking page stops updating, you do not throw the parcel away. You find the last scan, and call the depot that handled it. Finding the last service that appears in a broken trace is the same kind of detective work.
30Real-World Usage Patterns
Teams use Cloud Trace in a few repeating ways. Find the one that looks like your team.
Chasing a slow checkout
An online store sees complaints about slow payment on busy evenings. The team filters traces to the checkout route, looks at the slowest one percent, and finds that most of the extra time sits in one outside call, with two retries. They add a time limit, a smarter retry rule and a fallback message, and the slow tail disappears from the next evening’s traces.
Finding an accidental N plus one
A new “order history” page loads slowly. The waterfall shows a comb of sixty near-identical database spans. A developer replaces the loop with one combined query, and the page becomes much faster. The same pattern is then searched for in other pages using the filter for repeated span names.
Verifying a release
After each release, a team compares traces from the old and new versions, using the service version attribute. If a span grew noticeably, the release is paused before it reaches all users. Traces are a quick, human-readable check beside automated tests.
Untangling a dependency map
A company that inherited a hundred services uses traces to discover which services really call which others. The surprise: an old reporting service is called by five newer ones. The team uses this real map to plan changes safely.
Supporting customers faster
The support desk asks customers for the support code shown in an error message, which contains the trace ID. Engineers paste it into the console and see exactly what happened to that request, with linked logs, in minutes and not hours.
The wider industry picture
Distributed tracing became common because large internet companies needed it. Twitter shared Zipkin, and Uber shared Jaeger, and both ideas flowed into the OpenTelemetry standard now supported by almost every major observability tool. Large companies such as Spotify, Snap and The Home Depot are well-known Google Cloud customers running systems made of many services. We name them to show the scale at which tracing matters, not to claim how they use Cloud Trace specifically, because public information may not say.
The deeper lesson is about culture. Teams that can see their system make calmer decisions, argue less, and fix problems faster. A trace is a shared picture, and shared pictures end many arguments.
31A Worked Walkthrough in Words
Let us follow a made-up engineer named Meera through one stressful afternoon, using everything above.
Meera is on call for a bookshop’s website. At two in the afternoon, a monitoring alert says that the 99th percentile latency of the checkout route has doubled. The average has barely moved, which is why nobody complained loudly yet. She knows the time window and the service, so she has her first two filters.
She opens Trace Explorer, sets the time range to the last two hours, and filters to the checkout route. The cloud of points shows most requests are fast, but a band of requests has risen sharply since one-thirty. That moment matches a release that went out at the same time. The shape suggests a change, not random bad luck.
Meera opens one slow trace and one fast trace from the same route. In the fast trace, the inventory check takes forty milliseconds. In the slow trace it takes nearly two seconds, and the waterfall shows it called the stock service three times in a row. The service version attribute shows that the slow traces all come from the new release.
She clicks through to the logs linked to the slow span. A warning appears saying that the new code asks for stock one item at a time. The developer who made the change has accidentally created the N plus one pattern. Meera rolls back the release, and within minutes new traces show the old, fast shape again.
The next morning, the team writes a short report that includes the slow trace, the fast trace and a note about the one span that grew. They add a rule to their review checklist: new loops that call other services must show a single span in a test trace. They also add an alert that compares latency by service version, so the next regression is spotted within minutes of release.
Metrics told Meera when to look. Traces told her where. Logs told her why. The release attribute told her who should fix it. Each tool did its own job, and together they turned a mystery into a ten-minute fix.
32Team Workflow and Governance
Tracing succeeds when a team shares a few simple rules. Without them, every service becomes a different dialect.
Agree on a standard
Decide that all services use OpenTelemetry, which header format they propagate, and how services are named. Publish a short starter template with tracing already configured, so new services begin correct.
Agree on attributes and names
Create a short list of required attributes, such as service version and environment, and a list of forbidden content, such as personal data. Review it once a quarter, and keep it short enough that people remember it.
Assign ownership
Someone must own the collector, the sampling rules and the cost dashboard. Often this is the platform team. Application teams own their own spans and attributes, and they fix gaps in their services.
Make traces part of daily habits
Include a trace link in incident reports and in pull requests that change performance. Teach new engineers to read a waterfall in their first week. Hold a short monthly session where someone shows an interesting trace to the group.
| Team decision | Why it matters | A simple default |
|---|---|---|
| Instrumentation standard | Consistency across services | OpenTelemetry for all new services |
| Service naming | Readable traces and dashboards | Team, product and component in a fixed pattern |
| Sampling policy | Controls cost and coverage | Low rate in production, keep errors and slow requests |
| Access rules | Protects sensitive details | Reader role for investigators, writer role for apps |
| Data rules | Prevents privacy leaks | No personal data in names or attributes |
| Health checks of tracing | Catch silent failure | Synthetic request and drop-in-volume alert |
A city’s roads work because everyone follows the same signs and signals. If every driver invented their own signs, accidents would be common. Naming rules, shared headers and standard attributes are the road signs of a tracing system.
33A Learning Path You Can Follow
You do not need to learn everything at once. Move from simple and safe to deep and powerful.
Week one: the vocabulary
Learn trace, span, parent, child, attribute and propagation. Draw one imaginary request on paper as a tree of spans.
Week two: your first trace
Deploy a tiny two-service app to a practice project. Enable the API, grant the writer role, add automatic instrumentation, and find your first waterfall.
Week three: manual spans and attributes
Add spans around business steps and useful attributes. Practice filtering by them in Trace Explorer.
Week four: logs and metrics together
Add trace IDs to logs, create a latency alert, and practice the path from alert to trace to log.
Week five: sampling and cost
Experiment with different sampling rates, estimate span volume, and set a budget alert. Try a collector with simple rules.
Week six: security and teamwork
Write down rules about sensitive data, review roles, add a synthetic trace check, and share what you learned with your team.
Keep a small notebook of every odd waterfall you meet, with a one-line explanation. After a month, you will recognise shapes at a glance, and that quick recognition is the real skill behind good tracing.
34Frequently Asked Questions
Short, honest answers to the questions beginners ask most often.
35Summary and Key Takeaways
If you remember only a few ideas from this long guide, make them these.
Key Takeaways
- A trace is a tracking number for a request. It joins many timed steps, called spans, into one timeline, so you can see exactly where a slow or failed request spent its time.
- Propagation keeps the thread connected. Pass the trace context through every hop, including queues, proxies and background jobs, and test with a request that crosses the whole path.
- Use OpenTelemetry and mix automatic with manual spans. Automatic helpers give quick coverage, and a few well-named business spans give meaning. Keep names stable and attributes useful.
- Read waterfalls by shape. Look for the longest bar, empty gaps, serial chains that could run in parallel, combs of repeated queries, retry ladders and late starts.
- Sample wisely and watch the cost. Keep errors and slow requests on purpose, estimate span volume, avoid spans inside tight loops, and set budget alerts.
- Protect and monitor the pipeline. Grant narrow roles, keep sensitive data out of spans, link traces with logs and metrics, and run a synthetic request so a silent failure never surprises you.