Cloud Profiler in Google Cloud

Cloud Profiler in Google Cloud

A friendly, step-by-step guide to the service that shows exactly which lines of your code eat your CPU and memory in production: what it is, how it works inside, how to set it up, how to read its pictures, and how to use it to make software faster and cheaper.

Imagine a busy restaurant where customers complain that the food takes too long. You could guess the reason. Maybe the oven is slow, maybe the chef chops too carefully, maybe the waiter walks in circles. Or you could place a quiet observer in the kitchen with a stopwatch who writes down, every few seconds, what each person is doing at that exact moment. After a day of notes you would know, with proof, that the chef spends forty percent of the time hunting for a missing spoon. That observer is what Cloud Profiler does for software.

This guide assumes you know nothing about profiling. Every new word is explained when it first appears. By the end you will understand what a profile is, how Google collects it with very little slowdown, how to read the colorful bars called flame graphs, and how engineers use them to remove waste from real systems. We will also keep the story honest, with the trade-offs, the traps, and the habits that keep you safe.

WWhat Is Cloud Profiler?

Start with the big picture, in plain words.

The simple definition

A program is a list of instructions that a computer follows. Those instructions are grouped into named pieces called functions. When your program runs, some functions run for a long time and others finish in a blink. A profile is a report that tells you how much of a resource, such as processor time or memory, each function used. The act of collecting such a report is called profiling.

Cloud Profiler is a Google Cloud service that does continuous profiling. The word continuous matters. Instead of running a special tool once on your laptop, Profiler collects data all the time from your real, live applications and stores it so you can look at it later. It then draws the results as interactive pictures that link each cost back to the exact function in your source code.

Everyday analogy

Think of your household electricity bill. The bill tells you the total, but not which gadget caused it. Profiling is like plugging a small meter into every appliance. After a week you discover the old freezer in the garage uses more power than the rest of the house combined. Cloud Profiler is that meter for each function in your program, left plugged in permanently so you can check it whenever the bill rises.

Where it sits in Google Cloud

Cloud Profiler belongs to the family of tools Google calls its observability suite, which also contains Cloud Monitoring for numbers over time, Cloud Logging for text messages, Cloud Trace for the path of one request, and Error Reporting for crashes. Each answers a different question. Profiler answers one very specific question: inside my running code, which lines are using the most resources?

Why it exists

Software that works fine on a developer’s laptop often behaves differently in production. Real traffic is larger, messier, and more surprising than any test. A slow function that never showed up in testing can suddenly dominate when a million real users arrive. Profiling on a laptop cannot reproduce that. Profiling in production can. Cloud Profiler lets teams do it safely because its overhead is designed to be low enough to leave on all the time.

Always on
collects data continuously from live services
Low cost
designed to add only a small slowdown to your app
Code level
points at functions, not just at machines

A short history

The idea did not start as a cloud product. In 2010 Google engineers published a research paper describing an internal system called Google-Wide Profiling. It sampled programs across Google’s enormous fleets of computers and showed which code burned the most resources. The lesson was powerful: even tiny wins, such as making a common function two percent cheaper, saved huge amounts of computing power when multiplied across thousands of machines. Years later, Google packaged the same idea for its customers as Cloud Profiler, so that any team could do what Google had done internally.

Around the same time, a visual style called the flame graph, invented by the performance engineer Brendan Gregg, became popular across the industry because it shows a profile in one glance. Cloud Profiler uses a flame graph as its main view.

i
Keep in mind

Profiling does not tell you that your program is broken. It tells you where the effort goes. Often the answer is surprising, and surprises are exactly what make profiling valuable.

PPerformance Basics: The Words You Need First

Five small ideas make the rest of this guide easy.

CPU time

The CPU, or processor, is the part of a computer that actually carries out instructions. CPU time is how long the processor was busy working for your function. If a function does lots of math, it consumes lots of CPU time. High CPU time usually means slow responses or high bills.

Memory and the heap

Memory is the short-term workspace where a running program keeps its data. The part of memory used for objects that your program creates and later discards is called the heap. If a program keeps creating objects and never lets go, the heap grows until the machine runs out of space. This problem is called a memory leak.

Allocation

An allocation is a request for a piece of memory. Even if a program never leaks, constantly allocating and discarding many objects forces the system to spend time cleaning up, a job called garbage collection. A function that allocates too much can slow the whole application, even when its own math is quick.

Waiting time

Not all slowness is the processor working hard. Often a program is simply waiting, for a database to answer, for a file to load, or for another thread to release a shared item. Time spent waiting is sometimes called wall time, because it is the time you would measure by looking at a clock on the wall, including all the idle moments.

Latency and throughput

Latency is how long one request takes from start to finish. Throughput is how many requests the system can handle per second. Profiling helps with both: cheaper functions mean quicker answers and room for more requests on the same machines.

Processor

CPU time

How long the processor was busy running your function.

Workspace

Heap memory

The area where your program keeps objects it creates.

Requests

Allocation

Each ask for a new piece of memory, which can add cleanup work.

Idle

Wall time

Total elapsed time, including waiting on other things.

Speed

Latency

How long a single request takes.

Volume

Throughput

How many requests per second the system finishes.

Profiling versus monitoring, logging, and tracing

Beginners often wonder why they need yet another tool. The easiest way to see the difference is to ask each tool a question.

ToolThe question it answersLevel of detail
Cloud MonitoringIs my service healthy right now, and how are the numbers changing?Whole service or machine
Cloud LoggingWhat messages did my program print?Individual events
Cloud TraceWhere did the time go for one request across many services?One request path
Error ReportingWhat is crashing, and how often?Exceptions
Cloud ProfilerWhich functions inside my code use the most CPU, memory, or waiting time?Functions and lines of code
Everyday analogy

Picture a car trip. Monitoring is the dashboard showing speed and fuel. Logging is the notebook where the driver writes remarks. Tracing is the route map for one journey with the time spent at each stop. Profiling is the mechanic’s report that says which engine part wastes the most fuel. You need the dashboard to notice a problem, but you need the mechanic to fix it.

CCore Concepts of Cloud Profiler

The vocabulary of the service, explained one word at a time.

Agent

The profiler agent is a small piece of code that lives inside your application, either added as a library or switched on as an agent. It does the actual collecting. Think of it as the stopwatch-holding observer in the kitchen. It runs beside your own code, wakes up now and then, records what is happening, and sends the notes to Google.

Sampling

Sampling means taking snapshots at intervals instead of recording every moment. If you wanted to know how a crowd spends its day, you would not follow each person constantly. You would take a photograph every few minutes and count what people are doing. Given enough photographs, the picture of the crowd becomes accurate. Sampling is the secret to Cloud Profiler’s low overhead.

Stack trace

When a function calls another function, which calls another, the computer keeps a list of this chain called the call stack. A stack trace is a snapshot of that list at one instant. It reads like: the web handler called the order checker, which called the price calculator, which called the discount lookup. A profile is built from thousands of these snapshots.

Profile type

A profile type says which resource was measured. Examples are CPU time, heap usage, allocated memory, wall time, contention, and threads. Different programming languages support different types, which we cover in a later chapter.

Service and version

In Profiler, a service is the name you give to one logical application, such as “checkout-api”. A version is a label for a specific release, such as “v42” or a build number. Profiler groups data by these two labels. This makes it possible to compare today’s release with yesterday’s and to see whether a change made things better or worse.

Flame graph

A flame graph is a picture made of horizontal bars. Each bar stands for a function. The wider the bar, the larger its share of the measured resource. Bars stacked above or below each other show who called whom. A glance tells you which function is the widest and therefore the most expensive.

Self cost and total cost

Every function has two numbers. Self cost is the resource used by the function’s own lines. Total cost includes the function plus everything it called. If a function has high total cost but low self cost, the real culprit is hiding in one of its helpers. If its self cost is high, the function’s own work is the problem.

?
Remember

Agent collects, sampling keeps it cheap, stack traces explain who called whom, profile types say what was measured, service and version organize the data, and the flame graph makes it readable.

Production example: comparing releases

A team ships version 41 and version 42 of an API one after the other. Because every profile is labeled with its version, they can place the two flame graphs side by side and see that a newly added data conversion step made one function noticeably wider. The same data would be almost impossible to gather by guessing from monitoring charts alone.

AArchitecture: How the Pieces Fit Together

Follow the notes from your running code to the screen of your browser.

The system has three simple parts: the agent inside your application, the Cloud Profiler service on Google’s side, and the interface where you view and compare the results. Between them flows a steady trickle of small profile files.

flowchart LR
  A["Your application running in production"] --> B["Profiler agent library inside the app"]
  B --> C["Short sampling window per profile type"]
  C --> D["Profile data with stack traces"]
  D --> E["Cloud Profiler API"]
  E --> F["IAM permission check"]
  F --> G["Profile storage managed by Google"]
  G --> H["Profiler interface with flame graph"]
  H --> I["Engineer compares versions and finds hotspots"]
    
Figure 1: The journey of profile data from a live application to an engineer’s screen.

Reading the diagram

Your application running in production. This is any program on Compute Engine, Google Kubernetes Engine, Cloud Run, App Engine, or even a machine outside Google Cloud, as long as it can reach Google over the internet.

Profiler agent library inside the app. The agent starts when your program starts. It registers with Google, announcing the project, the service name, and the version. Then it waits for instructions about when to collect.

Short sampling window per profile type. The service tells each agent when to take a profile. The window is short, roughly a few seconds of measurement per profile, and happens only now and then. Outside these windows the agent costs almost nothing.

Profile data with stack traces. The agent packs its snapshots into a compact file, a format commonly known as pprof, which is an open standard for profile data.

Cloud Profiler API. The agent uploads the file by calling Google’s Profiler API over a secure connection.

IAM permission check. Google verifies that the identity behind the upload is allowed to send profiles to this project. The role designed for that purpose is the agent role.

Profile storage managed by Google. The data is stored and indexed so it can be filtered by service, version, time, and type. Profiles are kept for a limited retention period, so very old data eventually disappears.

Profiler interface with flame graph. When you open the Profiler page in the Google Cloud Console, it fetches the stored data and draws it for you.

Everyday analogy

The system works like a team of weather stations. Each station (agent) lives where the weather happens, takes brief readings on schedule, and posts them to a central office (the Profiler service). The office files the readings by place and date, and a forecaster (you) later opens the map to see where the storms are. No one stands outside all day, yet nothing important is missed.

i
Key insight

The agent pushes data out to Google. Google does not reach into your application. This means your application needs outbound access to the Profiler API, but you do not need to open any inbound port for it.

PProfile Types and Supported Languages

Different questions need different measurements.

Cloud Profiler supports several programming languages, and each language runtime exposes different information. The most commonly used languages are Go, Java, Node.js, and Python. Because Google’s lists change as the product evolves, treat the table below as a learning map and confirm the exact current support in the official documentation before you plan a rollout.

The main profile types

Profile typeWhat it showsTypical use
CPU timeWhich functions kept the processor busySlow responses, high compute bills
Wall timeWhere elapsed time went, including waitingSlow requests that do not use much CPU, such as waiting on databases
HeapWhich functions hold memory that is still in useMemory leaks and oversized caches
Allocated heapWhich functions create the most memory over timeGarbage collection pressure
ContentionWhere threads wait to get a shared lockPrograms that slow down as concurrency rises
ThreadsHow many threads exist and what they are doingThread leaks and stuck workers

Not every language offers every type. For example, CPU time is widely available, while contention and thread profiles are tied to specific runtimes. This is a property of the language runtime, not a limit of the Google service, because Profiler can only report what the runtime is able to measure.

Choosing the right type

1

Service feels slow and CPU graphs are high

Start with CPU time. The widest bars point to the functions to optimize first.

2

Service feels slow but CPU graphs are low

Look at wall time. The program is probably waiting on something outside itself.

3

Memory use keeps climbing

Open heap profiles over several hours and see which function holds the growing memory.

4

Frequent pauses for cleanup

Look at allocated heap to find the function that creates too many short-lived objects.

5

Throughput stops improving as you add threads

Check contention. Threads may be queueing for one shared lock.

Everyday analogy

Profile types are like different medical tests. A blood test, an X-ray, and a heart monitor each reveal something the others cannot. A good doctor picks the test that matches the symptom. A good engineer does the same with CPU, wall, heap, and contention profiles.

!
Common confusion

Heap profiles show memory that is still in use when the snapshot was taken. Allocated heap shows memory that was created over time, even if it was freed again. A function can look harmless in the first and terrible in the second, and the difference matters.

IInternal Working: How Sampling Really Happens

Lift the lid and watch the gears turn.

Statistical profiling

Cloud Profiler uses statistical profiling. That means it does not measure each function call exactly. Instead, it checks the program at many random-ish moments and notes which function was running. If a function appears in one hundred of one thousand snapshots, the profile concludes it used about ten percent of the time. With enough snapshots, the estimate is very close to reality, and the effort needed is tiny compared with recording every call.

Everyday analogy

A pollster does not ask every citizen how they will vote. A well-chosen sample of a few thousand people predicts the whole country. Profiling samples the program the same way. The more snapshots collected, the smaller the error.

CPU sampling

For CPU profiles, the runtime asks the operating system to interrupt the program at a steady rhythm, for example many times per second while the profile window is open. Each interruption records the current stack trace. Functions that are running more often are caught more often. A function that never runs is never caught, which is exactly right.

Heap sampling

For memory profiles, runtimes do not record every single allocation. Instead they record a sample of allocations, such as one for every fixed number of bytes created. Large or frequent allocations are therefore more likely to be recorded. The recorded stack trace tells which function asked for the memory. For heap-in-use profiles, the runtime also tracks which of the sampled objects are still alive when the snapshot is taken.

Wall-time sampling

For wall-time profiles, the sampling also records threads that are waiting. This reveals functions that are slow because of time spent blocked, not because of heavy calculation. This is why wall time is the best friend of anyone chasing slow database calls or slow network calls.

How Google schedules the collection

Each agent registers with the Profiler service and then asks, “Is it my turn to profile?” The service spreads the work across all agents of the same service so that, at any moment, only a few instances are actually collecting while the others carry on without any extra effort. Over time, many small profiles from many instances are merged into a single combined view. This spreading is what keeps overhead low for each individual machine, while still producing a rich picture for the whole fleet.

sequenceDiagram
  participant App as "Application instance"
  participant Ag as "Profiler agent"
  participant API as "Cloud Profiler API"
  participant Store as "Profile storage"
  Ag->>API: "Register service name and version"
  loop "Repeated cycle"
    Ag->>API: "Any profile requested for me?"
    API-->>Ag: "Please collect a CPU profile for a short window"
    Ag->>App: "Sample stack traces during window"
    App-->>Ag: "Stack samples"
    Ag->>API: "Upload packed profile"
    API->>Store: "Save, index by service, version, type, time"
  end
    
Figure 2: The request-and-collect loop between an agent and the Profiler service.

Symbols and names

A running program works with raw addresses, which are numbers. To show the human-friendly name of a function, the profile must carry a symbol table, which is a dictionary from address to name. For languages like Java, Python, and Node.js, the runtime itself knows the function names. For compiled languages like Go, the binary contains the information. If you strip the symbols from a binary to make it smaller, your flame graph may show unreadable numbers instead of names, so be careful with such build options.

Aggregation

Finally, Profiler aggregates profiles. It adds together the samples from many instances and many time windows for the chosen service and version. This is why the flame graph you see is usually a summary over a chosen period, not the story of one moment. If you want to understand one burst of trouble, narrow the time range.

i
Why sampling is trustworthy

A small function that takes a tiny share of time might be missed in a short window. A large function that matters will show up again and again. Profiling is built to find the big costs, which are the ones worth fixing.

SSetting It Up: From Zero to First Profile

A calm, ordered path that avoids the usual surprises.

Step one: choose a project and switch on the API

Every Google Cloud resource lives in a project, which is a folder for your cloud things plus billing and permissions. You must turn on the Cloud Profiler API for the project that will receive the profiles. Without it, the agent’s uploads are rejected, and the error message will say the API is not enabled.

Step two: give the application an identity with permission

The agent must prove who it is when uploading. On Google Cloud, applications normally run as a service account, which is an identity for programs rather than people. That account needs the Cloud Profiler Agent role. Following the principle of least privilege, grant only that role, not a broad one such as owner. People who only need to view profiles need a viewing role, which is separate from the agent role.

Step three: add the agent to the application

Each language has its own small package or agent. You add it to the application and call a start function as early as possible, giving it a service name and an optional version. For Java, the usual approach is to attach an agent when the runtime starts. For Go, Node.js, and Python, you include an official library and start it in your code. Because exact package names, flags, and versions change over time, use the official quickstart for your language when you apply this step.

Step four: deploy and generate traffic

A profile only shows what the program does. An idle program produces an empty picture. Send realistic traffic, from a test tool or from real users, so that functions actually run. After a few minutes you should see the first profiles appear.

Step five: open the Profiler page

In the Google Cloud Console, open the Profiler page. Choose the service, the profile type, and the time range. The flame graph appears. If it is empty, jump to the troubleshooting chapter.

flowchart TD
  A["Create or choose a project"] --> B["Enable Cloud Profiler API"]
  B --> C["Create service account for the app"]
  C --> D["Grant Cloud Profiler Agent role"]
  D --> E["Add language agent and start it in the app"]
  E --> F["Deploy to Cloud Run, GKE, Compute Engine, or App Engine"]
  F --> G["Send realistic traffic"]
  G --> H["Open Profiler page and view flame graph"]
    
Figure 3: The setup path from an empty project to the first flame graph.

Where the agent can run

Serverless

Cloud Run

Containers that scale automatically. Give the service account the agent role and start the agent in your code.

Containers

Google Kubernetes Engine

Pods use the identity of their workload. Workload Identity ties a pod to a Google service account without any key file.

Machines

Compute Engine

The virtual machine carries an attached service account that must have the role and a suitable access scope.

Platform

App Engine

The application uses the default or chosen service account for the app.

Anywhere

Outside Google Cloud

Works too, if you supply the project identifier and credentials, preferably through federation rather than long-lived keys.

Local

Developer laptop

Useful for a quick trial using your own login, though real value comes from production traffic.

!
Heads up

Start the agent early in your program. If it starts after a long initialization, you may miss the very work you wanted to study. Also give the agent a stable service name. If the name changes with every deploy, your history becomes scattered across many tiny services.

Production example: rolling out to a fleet

A platform team at a large company can add the agent to a shared base image or common library so that every service gets profiling by default. Teams then only choose a service name. This turns profiling from a rare special project into a normal part of every deployment.

RReading the Flame Graph and the Interface

Learn to read the picture in under five minutes.

What each bar means

Every bar in the flame graph represents one function. The width of the bar shows how much of the selected resource that function and everything it called is responsible for. The stacking of bars shows the call chain: a bar sits next to the function that called it. Colors help tell different pieces apart, but the shapes and widths carry the meaning.

How to find the hot spots

Look for the widest bars. A wide bar means a big share. Then look at the bars it contains. If the wide bar is made of many narrow children, the cost is spread thin and no single child is the culprit. If one child takes almost the whole width, you have found a likely hotspot. If a wide bar has almost nothing inside it, the function’s own lines are expensive.

flowchart TD
  A["handleRequest - 100 percent"] --> B["validateInput - 5 percent"]
  A --> C["buildResponse - 90 percent"]
  A --> D["writeLog - 5 percent"]
  C --> E["queryRecommendations - 70 percent"]
  C --> F["formatJson - 20 percent"]
  E --> G["rankItems - 60 percent"]
  E --> H["fetchFromCache - 10 percent"]
    
Figure 4: A simplified call tree. Following the largest share leads straight to rankItems.

In the example, a beginner might be tempted to speed up the logging, because logging is easy to understand. But logging is only five percent. The tree makes it plain that ranking items carries sixty percent of the cost. Fix that first, and the whole request becomes faster. This is the main gift of profiling: it protects you from optimizing the wrong thing.

The controls you will use

  • Service: choose which application to view.
  • Profile type: choose CPU, heap, wall time, and so on.
  • Version: narrow to one release, or view all.
  • Zone and other filters: narrow to where the code ran when such filters are offered.
  • Time range: view the last hour, a day, or a custom window. Wider windows give smoother results, and narrow windows capture specific incidents.
  • Weight: some profile types let you choose which weighting to display, for example how to interpret the numbers.
  • Focus and highlight: select a function to see only paths that include it, or to see where else it appears.
  • Compare: overlay two time ranges or two versions and see which functions grew or shrank.

Compare mode: the before and after tool

Compare mode is the most useful feature for teams that care about regressions. A regression is a change that makes things worse. After a release, you compare “this week” against “last week” for the same profile type. Functions that grew are flagged in a distinct way, which leads you directly to the change that caused the slowdown.

i
Reading tip

Do not stare at one tall tower. Skim the wide, flat plateaus. A wide plateau is a function that eats a lot of resource by itself. A tall, narrow tower is a very deep chain of calls that is often cheap in total.

Production example: a surprise in an innocent helper

An online store sees page responses slowing down every evening. The flame graph shows that a small helper meant to format prices, called thousands of times per page, takes a large share of CPU because it builds a new formatting object on every call. Reusing one object trims the share dramatically. No dashboard of averages could have named that helper.

DData Flow and Lifecycle of a Profile

From the first sample to the day the data is deleted.

1

Application starts

The agent starts inside the program, finds the project and identity, and registers the service name and version with Google.

2

Agent waits for its turn

The agent asks the service which type of profile to take and when. Most of the time, nothing is asked of it.

3

Short collection window

When its turn comes, the agent samples stack traces for a few seconds. Your normal traffic keeps flowing the whole time.

4

Packing and upload

The samples are compressed into a profile file and uploaded to the Profiler API over a secure connection.

5

Storage and indexing

Google stores the profile and indexes it by project, service, version, profile type, and time.

6

Viewing and aggregation

When you open the interface, many stored profiles for your chosen filters are merged into one flame graph.

7

Retention and expiry

After the retention period ends, old profiles are removed automatically. The period is limited, so save important findings in your own notes or tickets while the data is still available.

stateDiagram-v2
  [*] --> Registered: "Agent starts"
  Registered --> Idle: "Waiting for a request"
  Idle --> Collecting: "Service asks for a profile"
  Collecting --> Uploading: "Window ends"
  Uploading --> Idle: "Upload accepted"
  Uploading --> Idle: "Upload failed - retry later"
  Idle --> [*]: "Application stops"
    
Figure 5: The life of an agent inside a running application.

What happens when an instance disappears

Modern services scale up and down. A container may live only a few minutes. If an instance is shut down in the middle of a collection window, that one small profile may be lost, but profiles from other instances continue to arrive. Because the final picture is built from many instances, losing a few windows hardly changes it.

Data volume

Each profile file is small, usually a few kilobytes to a few hundred kilobytes, depending on the program. Because collection is spread across the fleet, the total upload stays modest even for large systems.

?
Planning note

Retention and pricing details are set by Google and can change. Check the official documentation for the current retention window and for any charges before you plan a long-term strategy. If you want to keep a particular flame graph for months, export or capture it and attach it to the related ticket.

HHands-On Workflows: Solving Real Problems

Four stories that show the tool at work, with no code needed.

Workflow one: the slow API with a hot CPU

Your team notices that an API takes much longer to answer during busy hours, and the CPU graph on the dashboard is high. You open Profiler, pick the CPU profile type, and select the last day. The widest bar leads through a function that sorts a large list again and again for every request. You change the code so the list is sorted once and reused. After the next release, you use compare mode and see the sort function shrink to a thin sliver. Response times drop, and fewer machines are needed during peak hours.

Workflow two: the slowly leaking memory

A service restarts itself every few days because it runs out of memory. Dashboards show memory rising in a steady staircase. In Profiler, you open the heap profile and compare a view from the morning with a view from the evening. One function that stores recent results in a list has grown wider and wider, because nothing ever removes old entries. You add a size limit to that list. The staircase flattens and the restarts stop.

Workflow three: slow requests but low CPU

Users complain about slowness, yet the processor is nearly idle. This is the classic sign of waiting. You switch to a wall-time profile where available. The flame graph shows a wide section inside a function that talks to a database, called many times in a loop for one request. The fix is to ask the database for all the data at once instead of one item at a time. This pattern is known as the N plus one problem, and it is among the most common causes of slow web pages.

Workflow four: too much cleanup work

A service sometimes pauses briefly and then speeds up again, a rhythm that matches garbage collection. The allocated heap profile shows one function creating huge numbers of short-lived temporary objects while building text messages. You change it to reuse a buffer. Allocation drops, pauses shrink, and the long tail of slow requests improves.

flowchart TD
  A["Users report slowness or bill rises"] --> B["Check Monitoring for CPU, memory, latency"]
  B --> C{"What looks abnormal?"}
  C -- "CPU high" --> D["Open CPU profile"]
  C -- "CPU low but latency high" --> E["Open wall-time profile"]
  C -- "Memory rising" --> F["Open heap profile and compare over time"]
  C -- "Frequent pauses" --> G["Open allocated heap profile"]
  D --> H["Find widest function and fix"]
  E --> H
  F --> H
  G --> H
  H --> I["Deploy new version"]
  I --> J["Use compare mode to confirm improvement"]
    
Figure 6: A decision path from a symptom to the right profile type.
Everyday analogy

Fixing performance is like finding why a household budget runs short. You do not cut every expense equally. You list the spending, find the few big items, and change those. A small saving on coffee will never fix a large, forgotten subscription. Profiling is the list of spending, with the biggest items at the top.

i
The golden loop

Measure, change one thing, measure again. If you change five things at once, you will not know which one helped, and one might even have hurt.

AAdvantages, Disadvantages, and Alternatives

An honest look at what Profiler is great at, and where it is not the right tool.

Advantages

  • Production truth: shows real behavior under real traffic.
  • Low overhead: designed to stay on all the time.
  • Code-level answers: points to functions, not just machines.
  • Fleet-wide view: merges many instances into one picture.
  • History and comparison: compare versions and time ranges.
  • Native integration: uses Google Cloud identity, projects, and console.
  • Cost savings: faster code often means fewer machines.

Disadvantages

  • Statistical, not exact: tiny or rare functions may not appear.
  • Language support is limited: only some runtimes are supported.
  • Needs code or agent changes: the application must start the agent.
  • Limited retention: old data is deleted automatically.
  • Not a request tracer: it does not follow one user request across services.
  • Needs interpretation: reading a flame graph takes a little practice.

Profiler versus other approaches

ApproachBest forWeak spot
Cloud ProfilerAlways-on production profiling of supported runtimesLimited languages and retention
Cloud TraceFinding which service or call in a request path is slowDoes not show lines of code inside a service
Cloud MonitoringAlerts and health trendsCannot say which function is guilty
Local profiler on a laptopDeep, exact study during developmentDoes not reflect real production traffic
Third-party APM toolsBroad paid platforms across many languages and cloudsExtra vendor, extra cost, extra agents
Open-source continuous profilersTeams that want self-hosted controlYou run and maintain the system

Trace and Profiler work as a pair. A trace says, “this request spent two seconds in the recommendation service”. Profiler then says, “inside that service, most of the effort goes into the ranking function”. Together they take you from a user complaint to a line of code.

Everyday analogy

Trace is the delivery tracking page that shows which warehouse held your parcel the longest. Profiler is the warehouse manager’s report that explains why that warehouse is slow. One finds the building. The other finds the cause.

PPerformance, Overhead, and Scalability

What does it cost to watch? Very little, by design.

Why the overhead is low

Three design choices keep the slowdown small. First, sampling takes snapshots instead of recording every event. Second, short windows mean the agent is active for only a few seconds at a time, not continuously. Third, fleet-wide scheduling spreads collection so that only a small fraction of instances profile at any moment. Google’s documentation describes the typical overhead as small, in the range of a few percent or less of CPU, and the memory use of the agent as modest. Exact numbers depend on language and workload, so measure it for your own system during a trial.

How to test the overhead yourself

  1. Pick a service with steady traffic, such as one canary instance.
  2. Run it for an hour with the agent, then for an hour without it, under similar load.
  3. Compare CPU use, memory use, and latency between the two hours.
  4. If the difference is within your comfort level, roll out wider.

Scaling to large fleets

Because the work is shared across instances, adding more instances does not multiply the collection cost. In fact, more instances give more samples and a smoother, more reliable picture. Large systems with thousands of containers can profile every service without drowning in data.

Impact on cost

Profiling often pays for itself. A small percentage saved in a hot function, multiplied by the hundreds of machines running that code, can cut the number of machines needed. Companies that run large fleets have long reported that continuous profiling finds savings that no manual review would catch. Always check Google’s current pricing page for the service itself, since pricing terms may change.

Short
collection windows of a few seconds
Spread
collection shared across the fleet
Small
overhead that you should still verify yourself

Production example: trimming a fleet

In the spirit of Google’s own Google-Wide Profiling findings, a team running a few hundred containers finds that two functions, a text parser and a data conversion routine, account for a large share of CPU. After optimizing them, the service handles the same traffic with noticeably fewer containers. The savings recur every month without any further work.

!
Do not assume, measure

Overhead claims are averages. A very tight, latency-sensitive loop or a very small container may feel the agent more than a large server does. Trial first on a small slice of traffic, then widen.

SSecurity, Access, and Privacy

Profiles describe your code, so treat them with care.

Two different jobs, two different roles

Google Cloud uses IAM, short for Identity and Access Management, to decide who may do what. For Profiler there are two main jobs. One is sending profiles, which is the job of the application’s service account. The other is viewing profiles, which is the job of engineers. Keep these separate. The application should be able to upload but not to browse, and engineers should be able to browse but not impersonate the application.

WhoWhat they need to doType of permission
Application service accountRegister and upload profilesProfiler agent role only
Developers and SREsOpen the Profiler page and read flame graphsProfiler viewing role
Project administratorsEnable the API and grant rolesAdministrative roles, kept to a small group
AuditorsReview who changed accessRead access to audit logs

What a profile contains

A profile contains function names, file names, line numbers, and counts. It does not normally contain your users’ data, request bodies, or passwords. That is one reason profiling is considered low risk. However, function and file names can reveal how your code is organized, and sometimes names include sensitive words such as a customer or a project code name. Treat profile access like source code access and give it to people who are already allowed to see the code.

Authentication for the agent

Inside Google Cloud, the best way is an attached service account, with no key file anywhere. On Kubernetes, use Workload Identity so each pod receives short-lived credentials. Outside Google Cloud, prefer workload identity federation, which swaps your existing proof of identity for a short-lived Google token. Avoid long-lived key files, because anyone who copies a key can pretend to be that service account until it is deleted.

Network and encryption

Uploads use encrypted HTTPS connections. The agent only needs outbound access to Google’s API address. If your company limits outbound traffic, allow the Profiler API address, or use Private Google Access so that instances without public addresses can still reach Google APIs. In organizations that use VPC Service Controls, which draw a protective boundary around Google services, make sure the Profiler API is included correctly in the perimeter so that agents inside it can upload.

Auditing

Administrative changes, such as granting a role or enabling the API, are recorded in audit logs. Review these records when you investigate who gained access to profile data and when.

Identity

Least privilege

Give the application only the agent role and give people only the viewing role they need.

Secrets

No long-lived keys

Use attached identities, Workload Identity, or federation.

Data

Know what is inside

Profiles show code structure, not user data. Protect them like source code.

Network

Outbound only

Allow the agent to reach the Profiler API, with private routes where needed.

Perimeter

Service controls

Include Profiler in your perimeter rules so uploads are not blocked by mistake.

Evidence

Audit logs

Review role grants and API changes regularly.

!
Common slip

Giving the application a broad role like editor “so it just works”. If the application is ever compromised, the attacker inherits that power. Grant the one agent role and nothing else for this purpose.

TTroubleshooting and Observing the Profiler Itself

When the flame graph is empty or looks wrong, walk this checklist.

1

Is the API enabled?

Confirm that the Cloud Profiler API is turned on in the same project the agent uploads to.

2

Does the identity have the agent role?

Check the service account used by the running application, not your own account.

3

Is the right project selected?

Profiles land in the project the agent was told to use. Look at the matching project in the console.

4

Did the agent actually start?

Read your application logs for start-up messages or errors from the agent.

5

Can the application reach Google?

Check outbound network rules, proxies, and private access settings.

6

Is there real work happening?

An idle service yields almost nothing. Send traffic and wait a few minutes.

7

Are the filters too narrow?

Widen the time range, choose another profile type, and clear version filters.

Common symptoms and likely causes

SymptomLikely causeFirst thing to try
No data appears at allAPI off, wrong project, or missing permissionCheck API, project, and the agent role
Permission denied in agent logsService account lacks the agent roleGrant the agent role to the right account
Only some profile types appearRuntime does not support the othersCheck language support in the docs
Function names show as numbersSymbols were stripped from the buildBuild with symbols or enable debug information
Data appears from one instance onlyOthers failed to start the agentCompare logs between instances
Graph looks too flatTime range too wide or load too lightNarrow the range, add traffic
Graph shows mostly the agent itselfApplication nearly idleProfile under realistic load

Watching the health of profiling

Because profiling is an observability tool, it deserves a little observability of its own. Review your application logs for agent warnings, check that new versions still show up in Profiler after each deployment, and add a simple team habit of looking at the profile after major releases. If profiles stop arriving, treat it like any other monitoring gap.

i
Neat trick

If profiles appear from a test environment but not from production, the cause is almost always identity or network. Compare the service account and the outbound rules between the two.

WWorking with the Rest of Google Cloud

Profiler is strongest when it talks to its neighbors.

With Cloud Monitoring

Monitoring tells you when something is wrong. Profiler tells you why. A neat team habit is to link the dashboard for each service to its Profiler page, so that anyone who sees a CPU spike can jump straight to the flame graph for the same time range.

With Cloud Trace

Trace finds the slow service in a chain of services. Profiler then explains the slowness inside that service. Together they take you from “the checkout page is slow” to “this exact function in the pricing service is the cause”.

With Cloud Logging and Error Reporting

Logs describe events, and errors show crashes. If a log line reveals that something is retrying over and over, Profiler may show the retry loop eating CPU. If out-of-memory crashes appear in Error Reporting, heap profiles show which function holds the memory.

With deployment pipelines

If you include the version label in every deploy, Profiler can compare releases. Some teams add a review step after each release: open compare mode between the new and previous versions, and look for newly wide bars. This turns performance into a routine check instead of a rare emergency.

With budgets and cost reviews

When the finance team asks why compute costs rose, a flame graph can show which function grew between months. This changes the conversation from “buy fewer machines” to “make this function cheaper”.

flowchart LR
  A["Cloud Monitoring alert: latency high"] --> B["Cloud Trace: slow service identified"]
  B --> C["Cloud Profiler: hot function identified"]
  C --> D["Developer fixes code"]
  D --> E["Pipeline deploys new version"]
  E --> F["Profiler compare mode confirms improvement"]
  F --> G["Monitoring shows latency back to normal"]
    
Figure 7: Monitoring, Trace, and Profiler working as one investigation chain.
Everyday analogy

Think of a hospital. The triage nurse notices a patient is unwell (monitoring). The general doctor finds which part of the body is affected (trace). The specialist examines that organ closely and finds the exact cause (profiler). Each step narrows the search, and no step replaces the others.

DDesign Patterns and Anti-Patterns

Habits that help, and habits that hurt.

Helpful patterns

Pattern

Profile by default

Bake the agent into your base image or shared library so every service has it from day one.

Pattern

Stable service names

Keep the name fixed across releases and use the version label for the release number.

Pattern

Post-release comparison

After each deploy, compare the new version with the previous one for regressions.

Pattern

Canary first

Enable the agent on a small slice of traffic before rolling out widely.

Pattern

Profile under load tests

Run realistic load tests with profiling on, then fix findings before launch.

Pattern

Record findings

Save screenshots and notes in tickets so knowledge outlives the retention window.

Anti-patterns to avoid

ANTI-PATTERN 01Avoid
What it looks like

Optimizing a function because it looks ugly, without checking how much of the profile it uses.

Why it hurts

Hours go into a function that contributes one percent, while a boring function using sixty percent stays untouched.

Do this instead

Always start from the widest bars in the flame graph and estimate the possible gain before changing code.

ANTI-PATTERN 02Avoid
What it looks like

Changing the service name with every release, such as “checkout-v41” and then “checkout-v42”.

Why it hurts

History fragments into many tiny services, and compare mode cannot line releases up.

Do this instead

Keep one service name and put the release in the version field.

ANTI-PATTERN 03Avoid
What it looks like

Profiling only in a quiet test environment and assuming production behaves the same.

Why it hurts

Real traffic mixes, data sizes, and concurrency can shift the hot spots completely.

Do this instead

Use production profiles as the main source of truth and use test profiles to verify fixes.

ANTI-PATTERN 04Avoid
What it looks like

Treating a profile as exact and arguing over differences of a fraction of a percent.

Why it hurts

Sampling has natural noise, so tiny differences mean nothing.

Do this instead

Focus on big, repeatable differences and confirm them across several time windows.

ANTI-PATTERN 05Avoid
What it looks like

Giving the application an owner role or a downloaded key just to get profiling to work.

Why it hurts

It creates a serious security risk to solve a small permission problem.

Do this instead

Grant only the agent role to an attached or federated identity.

BBest Practices and Common Mistakes

A short, practical rulebook you can pin to the wall.

Best practices

  • Start the agent early and keep it on. Continuous data is the whole point.
  • Label versions clearly. Use a build number or a short commit identifier so releases can be compared.
  • Profile under realistic load. An idle service tells you nothing.
  • Pick the right profile type. Match the type to the symptom, as in the chapter on types.
  • Change one thing at a time. Then measure again.
  • Check the overhead on a canary. Verify it on your own workload before wide rollout.
  • Keep build symbols. Names make flame graphs readable.
  • Give least-privilege access. Separate the agent role from the viewing role.
  • Review profiles after each major release. Make it a routine, like reading test results.
  • Write down what you learned. Notes survive longer than profile data.

Common mistakes beginners make

Mistakes

  • Forgetting to enable the API
  • Granting the role to the wrong account
  • Profiling an idle service and concluding nothing is wrong
  • Optimizing small functions that barely appear
  • Using CPU profiles to chase waiting problems
  • Never comparing before and after a fix

Better habits

  • Follow the setup checklist in order
  • Check which service account the app really uses
  • Generate load before reading the graph
  • Start with the widest bars
  • Switch to wall time when CPU is low but users wait
  • Use compare mode after every important fix
!
Keep perspective

Speed is not the only goal. Code that is a little slower but much clearer may be the better choice when the function barely appears in the profile. Optimize where the data says it matters, and leave the rest readable.

RReal-World Usage Patterns

How different teams put continuous profiling to work.

Google and Google-Wide Profiling

The idea behind Cloud Profiler comes from Google’s own internal practice. Google engineers described in a published research paper how sampling programs across their huge fleets revealed where processor time goes, and how small improvements in widely used code translated into large savings. Cloud Profiler brings that approach to customers.

Netflix and the flame graph

Flame graphs became a household tool for performance engineers largely through the work of Brendan Gregg, who popularized them while working at Netflix and elsewhere. Teams at companies of that scale use flame graphs to explain why a service uses more compute after a change, and to catch waste before it reaches customers. Cloud Profiler presents the same style of picture inside Google Cloud.

The startup keeping its bill small

A five-person startup running on Cloud Run adds the agent in their first week. Every Friday they open the flame graph for the week and fix the single widest function. Over months, their instance count stays flat even as customer traffic doubles, because each small fix removes waste. They never had a performance crisis, because they treated performance as a weekly habit.

The e-commerce team before a big sale

Ahead of a major shopping event, a retail team runs a load test with profiling turned on. The flame graph shows that a price-formatting helper and a product-search ranking function use a large share of CPU. They optimize both, rerun the test, and use compare mode to confirm the improvement. On sale day the system holds steady with room to spare.

The platform team in a large enterprise

A central platform team bundles the profiler agent into the company’s standard container images and sets sensible defaults for service names and versions. Hundreds of product teams get profiling without lifting a finger. The platform team then publishes a short guide on reading flame graphs and runs a quarterly review of the most expensive functions across the company.

flowchart TD
  A["Agent baked into base image"] --> B["Every service sends profiles"]
  B --> C["Weekly review of widest bars"]
  C --> D["Fixes tracked as small tickets"]
  D --> E["New version deployed"]
  E --> F["Compare mode confirms savings"]
  F --> G["Capacity plan and budget updated"]
  G --> C
    
Figure 8: A continuous improvement loop built on profiling.

Notice what the stories share. Profiling is not a one-time rescue operation. It becomes a quiet routine that keeps software lean, keeps incident counts low, and keeps cloud bills under control. The tool is simple. The habit is what creates the value.

FFrequently Asked Questions

Quick answers to the questions beginners ask most.

Q1What is Cloud Profiler in one sentence?

It is a Google Cloud service that continuously samples your running applications and shows which functions use the most CPU, memory, or waiting time, drawn as flame graphs.

Q2Will it slow down my application?

It is designed to add only a small overhead by using sampling, short windows, and fleet-wide scheduling. Google’s documentation describes the overhead as low, but you should measure it on your own workload with a canary before wide rollout.

Q3Which languages does it support?

The commonly supported languages are Go, Java, Node.js, and Python. Support can change over time and varies by profile type, so confirm the current list in the official documentation.

Q4Do I have to run my application on Google Cloud?

No. It works best there, but an application running elsewhere can also send profiles if it has network access to Google and valid credentials, preferably through federation.

Q5What is the difference between Profiler and Trace?

Trace follows one request across services and shows which step is slow. Profiler looks inside a service and shows which functions use the most resources. They work well together.

Q6Why is my Profiler page empty?

The usual causes are a disabled API, a missing agent role, the wrong project, an agent that did not start, blocked network access, or an idle application. Follow the troubleshooting checklist in order.

Q7What does a wide bar in a flame graph mean?

It means that function, including everything it calls, accounts for a large share of the measured resource. Start your investigation with the widest bars.

Q8What is the difference between self cost and total cost?

Self cost counts only the function’s own lines. Total cost counts the function plus everything it calls. High total cost with low self cost means the real problem is in a helper below it.

Q9Which profile type should I look at first?

Start with CPU time for slow, busy services. Use wall time when users wait but the processor is idle. Use heap profiles for growing memory and allocated heap for heavy cleanup work.

Q10Can profiles reveal my users’ private data?

Profiles contain function names, file names, line numbers, and counts, not request contents. Still, treat access like access to source code, because names can reveal how your system is built.

Q11How long does Google keep the profiles?

Profiles are kept for a limited retention period and then removed automatically. Check the current documentation for the exact window and save important findings in your own tickets.

Q12Is Cloud Profiler free?

Pricing terms can change, so check Google’s pricing page for the current answer. Also remember that the machines and traffic your application uses are billed in the usual way.

Q13Should I name my service differently for each release?

No. Keep a stable service name and use the version field for the release. This keeps history together and lets compare mode work well.

Q14How do I know my fix worked?

Use compare mode to place the version before the fix next to the version after it, with similar traffic. The target function should be visibly narrower.

Q15Can profiling replace load testing?

No. Load testing creates realistic pressure. Profiling shows where the pressure goes. Use them together for the best results.

SSummary and Key Takeaways

Everything important, in one place.

Key Takeaways

  • Cloud Profiler is continuous profiling for production. It samples live applications and shows which functions use the most CPU, memory, or waiting time.
  • Sampling keeps it cheap. Short windows, snapshots instead of full recording, and fleet-wide scheduling keep overhead small, though you should still verify it on your own system.
  • The flame graph is the main picture. Wide bars mean big shares, and stacked bars show who called whom. Always begin with the widest bars.
  • Pick the profile type to match the symptom. CPU for busy services, wall time for waiting, heap for leaks, allocated heap for cleanup pressure, and contention for lock fights.
  • Setup is a short ordered path. Enable the API, give the application’s service account the agent role, start the language agent early, send real traffic, then open the Profiler page.
  • Use service names and versions wisely. A stable name with a clear version lets compare mode prove that a fix helped or that a release caused a regression.
  • Profiler works best with its neighbors. Monitoring raises the alarm, Trace finds the slow service, and Profiler finds the guilty function. Keep access least-privilege and make profiling a regular habit.