Capture CPU and allocation profiles for deployed Workers and Durable Objects using the Cloudflare dashboard, Cloudflare CLI (command-line interface), or the Cloudflare API. Use profiles to find expensive functions and allocating code.
Use a CPU profile to identify functions that consume CPU time. This is the default profile type.
Use a Heap profile to identify code that allocates memory. It collects a stack trace every 512 kB of memory allocated during capture, recording the chain of function calls responsible for each sampled allocation.
A Heap profile measures allocations, not retained memory. It is not a heap snapshot and does not show whether allocated memory remains live.
Your Worker or Durable Object instance needs traffic before and during the capture. Capture targets a recently active, already-loaded isolate, rather than starting a new invocation.
Send requests that exercise the code you want to investigate. Capturing a profile does not invoke your code for you.
The historical log time range and filters do not control capture. A profile records activity during the selected capture duration, not past requests shown in logs.
-
In the Cloudflare dashboard, go to Workers & Pages and select your Worker:
Go to Workers & Pages ↗ -
Select Observability. In the view dropdown, select Flamegraph.
-
In Profile type, select CPU or Heap.
-
In Duration (ms), enter a capture duration from 1000 to 50000 milliseconds. The default is 10000 milliseconds.
-
In Version, select Latest or a version in the active deployment.
-
Select Capture profile. The button displays Capturing... while capture is in progress.
-
In the Cloudflare dashboard, go to Durable Objects:
Go to Durable Objects ↗ -
Select your namespace, then select the target instance.
-
Select Observability. In the view dropdown, select Flamegraph.
-
In Profile type, select CPU or Heap.
-
In Duration (ms), enter a capture duration from 1000 to 50000 milliseconds. The default is 10000 milliseconds.
-
In Version, select Latest or a version in the active deployment.
-
Select Capture profile. The button displays Capturing... while capture is in progress.
When capture completes, the dashboard displays the profile as a flamegraph.
Install cf and sign in before capturing a profile. To select the target account, refer to Select an account.
Run the following to see all the available options for the profiling command:
cf workers versions profile --helpThe command requires a positional version identifier and --worker-id. Use latest, a version's universally unique identifier (UUID), or a UUID prefix of at least eight characters.
latest selects the most recently created version, not necessarily a deployed version. If that version is not running, replace latest in the examples with the running version's identifier.
Set --duration-ms to a value from 1000 to 50000 milliseconds. For either Workers or Durable Objects, use --profile-type cpu for CPU profiles or --profile-type heap for allocation profiles.
The command writes raw binary pprof data to standard output.
-
Set
$WORKER_IDto your Worker ID or name. -
Ensure there is consistent traffic to the Worker running the selected version.
-
Capture a CPU profile for 5 seconds and save it to
worker-cpu.pprof:cf workers versions profile latest \ --worker-id "$WORKER_ID" \ --duration-ms 5000 \ --profile-type cpu > worker-cpu.pprof
-
Set
$WORKER_IDto the ID or name of the Worker that owns your Durable Object namespace, not a Worker that only calls it through a binding.Set
$NAMESPACE_IDto the namespace ID and$DURABLE_OBJECT_IDto the instance ID, a 64-character hexadecimal string. -
Ensure there is consistent traffic to the target instance. Ensure it is active and running the selected Worker version.
-
Capture a heap profile for 5 seconds and save it to
durable-object-heap.pprof. Pass both--namespace-idand--actor-idto target that exact instance:cf workers versions profile latest \ --worker-id "$WORKER_ID" \ --duration-ms 5000 \ --profile-type heap \ --namespace-id "$NAMESPACE_ID" \ --actor-id "$DURABLE_OBJECT_ID" > durable-object-heap.pprof
Use an API token with Workers Scripts Read permission or the Content Read-Only Workers role. Set $CLOUDFLARE_API_TOKEN to your token and $ACCOUNT_ID to your account ID.
The latest version selects the most recently created version, not necessarily a deployed version. If you uploaded a newer version without deploying it, replace latest in the URL with the deployed version's UUID.
The selected version must be loaded and running, with traffic during capture. The API returns a gzip-compressed pprof profile.
Use these fields in the request body:
| Field | Meaning |
|---|---|
duration_ms |
Required integer from 1000 to 50000 milliseconds. |
profile_type |
Optional: cpu (default) or heap. |
namespace_id |
Durable Object namespace ID. Required together with actor_id for a Durable Object capture. |
actor_id |
Durable Object instance ID, a 64-character hexadecimal string. Required together with namespace_id for a Durable Object capture. |
-
Set
$WORKER_IDto your Worker ID or name. -
Send traffic to the Worker running the requested version.
-
Send a
POSTrequest to capture the profile. This example captures a CPU profile for 10 seconds and saves it toworker-cpu.pprof.gz.curl --fail --silent --show-error --request POST \ "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/workers/$WORKER_ID/versions/latest/profile" \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ --header "Content-Type: application/json" \ --data '{ "duration_ms": 10000 }' \ --output worker-cpu.pprof.gz
-
Set
$WORKER_IDto the ID or name of the Worker that owns your Durable Object namespace, not a Worker that only calls it through a binding.Set
$NAMESPACE_IDto the namespace ID and$DURABLE_OBJECT_IDto the instance ID, a 64-character hexadecimal string. -
Send traffic to the target instance. Ensure it is active and running the requested Worker version.
-
Send a
POSTrequest with bothnamespace_idandactor_id. This example captures a heap profile for 10 seconds and saves it todurable-object-heap.pprof.gz.To capture a CPU profile, change
profile_typetocpu.curl --fail --silent --show-error --request POST \ "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/workers/$WORKER_ID/versions/latest/profile" \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ --header "Content-Type: application/json" \ --data "{ \"duration_ms\": 10000, \"profile_type\": \"heap\", \"namespace_id\": \"$NAMESPACE_ID\", \"actor_id\": \"$DURABLE_OBJECT_ID\" }" \ --output durable-object-heap.pprof.gz
In the dashboard flamegraph, each frame represents a function in the captured call stacks. Callers appear above their callees, the functions they call.
Frame width is proportional to CPU time or allocated memory, depending on the profile type. The graph is not a timeline: horizontal position does not indicate when a function ran.
Select a frame to focus on its subtree. Use the breadcrumbs to return to a parent frame, or All frames to reset the view.
Use Search frames to find function names or source locations. Switch to Table to compare these values:
| Value | Meaning |
|---|---|
| Self | CPU time or allocated memory attributed to the frame, excluding descendants |
| Total | CPU time or allocated memory attributed to the frame and its descendants |
| Percent of profile | Share of the whole capture |
Percentages remain relative to the whole capture, even when you focus on a subtree.
Use pprof-compatible tools to inspect profiles captured through the CLI, API, or dashboard. In the dashboard, select Download profile to download the raw pprof profile.
Capture requests are rate limited, and the API returns HTTP 429 when you exceed the limit. Wait before retrying, and follow the Retry-After header when present.
The API can also return these error messages:
| Error message | Meaning or action |
|---|---|
No recent executions were found for this Worker. |
Send traffic to the selected Worker version or target Durable Object instance, then retry capture. |
The Worker has no loaded isolate in its recent execution locations. |
Send traffic to the target version or Durable Object instance, then retry capture. |
Worker profiling is unavailable in this environment. |
Profiling is unavailable in the target environment. |
This Worker does not support runtime profiling. |
The selected Worker does not support profiling. |
The Worker runtime could not start profiling. Please try again. |
Retry capture. |