---
title: Troubleshoot and optimize Active CPU usage on Fluid compute
description: Diagnose which routes drive Active CPU usage and learn to optimize it. Separate traffic growth from per-request CPU work, fix common Active CPU usage patterns, and verify the change after shipping.
url: /kb/guide/optimize-active-cpu-on-fluid-compute
canonical_url: "https://vercel.com/kb/guide/optimize-active-cpu-on-fluid-compute"
published: 2026-08-05
last_updated: 2026-08-05
authors: Mike Darlington
related:
  - /docs/observability
  - /docs/functions/usage-and-pricing
  - /docs/routing-middleware
  - /docs/pricing/manage-and-optimize-usage
  - /docs/query
  - /docs/observability/insights
  - /docs/caching/cache-status
  - /docs/caching/runtime-cache
  - /docs/caching
  - /docs/functions/functions-api-reference/vercel-functions-package
  - /docs/logs/runtime
  - /docs/fluid-compute
  - /docs/functions/configuring-functions/memory
  - /docs/agent-resources/vercel-plugin
install_vercel_plugin: npx plugins add vercel/vercel-plugin
---

Active CPU reflects the compute time your code is actively executing on a virtual CPU. When it climbs, the cause is usually one of two things: you're serving more traffic, or each request is doing more CPU work than it used to. A project-level chart can confirm the increase, but the useful question is route-level: which routes changed, and did traffic rise, or did the work per request get heavier?

[Vercel Observability](https://vercel.com/docs/observability) gives you route-level views and filters to make that comparison and verify the impact after you ship a change. Use it to inspect requests, resource usage, function duration, invocations, regions, and time windows, then verify whether a change reduced CPU per invocation after deployment.

In this guide, you'll learn how to:

- Identify the routes driving Active CPU usage
  
- Separate traffic growth from per-request CPU growth
  
- Find and fix the most common CPU-heavy patterns
  
- Run a safe, read-only agent investigation
  
- Verify a change after shipping
  

## Understand Active CPU

In [Fluid compute](https://vercel.com/docs/functions/usage-and-pricing#active-cpu), Active CPU is the CPU time your code consumes. It excludes time spent waiting on external I/O. These signals measure different parts of function usage:

| Signal                    | What it means                                    |
| ------------------------- | ------------------------------------------------ |
| Active CPU                | Time spent actively executing code               |
| Function invocations      | Number of function requests                      |
| Active CPU per invocation | Approximate CPU work per request                 |
| Invocation duration       | Wall-clock time, including waiting and streaming |
| Provisioned memory        | Memory allocated while requests are in flight    |

Parsing, serializing, transforming responses, rendering pages, compiling content, hashing, compression, and image generation can all increase Active CPU. Waiting on external I/O usually increases duration, not Active CPU.

## Before you begin

Choose the scope you want to investigate:

- Team
  
- Project
  
- Environment
  
- Increase window
  
- Comparison window
  
- Recent deployment or release window, if known
  

Use the same scope throughout the investigation. Comparing different environments, routes, status codes, or time windows can make traffic changes appear to be CPU changes.

## 1\. Confirm the usage source

First, confirm which compute products contribute to the selected usage. [Routing Middleware](https://vercel.com/docs/routing-middleware#pricing) also uses Fluid compute, and Active CPU pricing, so disabling Fluid for regular Functions does not, by itself, remove every Active CPU source.

In the Vercel dashboard:

1. Select the team.
   
2. Open [Usage](https://vercel.com/docs/pricing/manage-and-optimize-usage#viewing-usage).
   
3. Choose the relevant time window.
   
4. Filter to the affected project.
   
5. Compare Active CPU with Function invocations and provisioned memory.
   
6. Check whether usage is concentrated in a region, project, or compute source.
   

This confirms whether you are investigating the right project and product area before moving into route-level analysis.

## 2\. Find the routes driving Active CPU

After confirming the project-level increase, use route-level data.

1. In the Vercel dashboard, Open **Observability**.
   
2. Go to the **Functions** view.
   
3. Select the same environment and time window.
   
4. Use the route list to compare Active CPU and invocations.
   
5. For each hot route, calculate Active CPU per invocation:
   
   `Active CPU per invocation = Function CPU time / Function invocations`
   

For example, a route with 22 seconds of Active CPU across 2200 invocations uses about 10 ms of Active CPU per invocation.

If you have [Query enabled](https://vercel.com/docs/query), you can inspect the same pattern more directly:

- Chart **Function CPU Time** with the `Sum` aggregation.
  
- Group by route.
  
- Filter to the same project, environment, and time window.
  
- Repeat with **Function Invocations**.
  
- Compare CPU per invocation across the current and previous windows.
  

Do not act on a project-wide chart alone. Rank routes by route-level usage, then compare like-for-like windows.

## 3\. Interpret the pattern

Use the route-level comparison to decide where to start.

| What changed                                    | Likely cause                              | Start with                                      |
| ----------------------------------------------- | ----------------------------------------- | ----------------------------------------------- |
| Active CPU and invocations both increased       | More traffic or a changed request mix     | Request amplification, bots, route mix, caching |
| Active CPU per invocation increased             | More CPU work per request                 | Rendering, transforms, compilation, media work  |
| Duration increased, but Active CPU did not      | More waiting or streaming                 | Upstream APIs, databases, and long responses    |
| Active CPU increased with errors or cold starts | Process errors or repeated initialization | Runtime Logs, startup code, uncaught exceptions |
| Active CPU stayed stable, but memory rose       | Longer in-flight requests                 | Streaming, slow I/O, provisioned memory         |

If CPU per invocation rose for a hot route, begin with repeated rendering, compilation, and per-request transformation. If total Active CPU rose while CPU per invocation stayed stable, begin with traffic growth, request amplification, and cache behavior.

## 4\. Common causes and fixes

### Request amplification and traffic mix

If the total Active CPU increased while the CPU per invocation stayed stable, investigate request amplification before changing the hot-path code.

Check the following:

- Framework or deployment changes
  
- [Prefetch behavior](https://nextjs.org/docs/app/guides/prefetching)
  
- Route mix changes
  
- Automated traffic
  
- Bot traffic
  
- Cache misses on high-volume routes
  

The [Edge Requests view](https://vercel.com/docs/observability/insights#edge-requests) can help show whether new request volume, rather than new CPU-heavy code, caused the increase. Caching can reduce Active CPU when responses are safe to cache. Requests served from the [CDN cache](https://vercel.com/docs/caching/cache-status) do not invoke the function.

### Repeated rendering and compilation

If a route has high CPU per invocation and frequent cache misses, inspect rendering and compilation work. Check for:

- Dynamic rendering, where static or cached output would be safe
  
- Per-request MDX or markdown compilation
  
- Rebuilding the same page shell for every request
  
- Repeated data formatting or transformation
  
- Cache headers that prevent eligible responses from being cached
  

For Next.js App Router, identify the caching model before editing:

- If your app runs [without Cache Components](https://nextjs.org/docs/app/guides/caching-without-cache-components), request-time APIs such as `cookies()`, `headers()`, the page's `searchParams` prop, and `connection()`, along with `fetch(..., { cache: 'no-store' })`, can make a route render dynamically. Use [explicit fetch caching or revalidation](https://nextjs.org/docs/app/api-reference/functions/fetch) only when freshness and privacy requirements allow it.
  
- With [Cache Components](https://nextjs.org/docs/app/getting-started/caching), use [`use cache`](https://nextjs.org/docs/app/api-reference/directives/use-cache) for stable work that you can include in prerendered output, and put request-time work below `Suspense` so the surrounding shell can stay prerendered. For shared request-time reuse, follow [Runtime Cache guidance](https://vercel.com/docs/caching/runtime-cache); treat the default in-memory cache state as per-instance and ephemeral rather than shared storage.
  

If a hot route compiles stable MDX or markdown per request, compile it during the build. Otherwise, cache only when sharing, freshness, and privacy permit it.

### Per-request transforms and media work

Inspect hot handlers for large JSON parsing, transformation, and serialization pipelines. Because [Active CPU counts code execution](https://vercel.com/docs/functions/usage-and-pricing), selecting only the needed rows and fields before data reaches the function reduces work. Check hot handlers for:

- Large JSON parsing
  
- Expensive object transformations
  
- Unbounded loops over large result sets
  
- Repeated compression
  
- Per-request image generation
  
- Per-request Open Graph image generation
  
- Duplicate password hashing or cryptographic work
  

Reduce the amount of data that reaches the function by selecting only the needed rows and fields upstream. Avoid recompressing unchanged output and [cache reusable compression results](https://vercel.com/docs/caching/runtime-cache) when safe.

For image or Open Graph generation, [pregenerate invariant Open Graph images](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/opengraph-image) or [cache eligible outputs](https://vercel.com/docs/caching). Do not weaken password-hashing parameters to reduce CPU; remove duplicate work around the security control instead.

### Waiting on background work

Use the [preloading pattern](https://nextjs.org/docs/app/guides/caching-without-cache-components#preloading-data) to start independent I/O together. This can shorten wall time, but work between awaits still [consumes Active CPU](https://vercel.com/docs/functions/usage-and-pricing).

Next.js [`after()`](https://nextjs.org/docs/app/api-reference/functions/after) and Vercel [`waitUntil()`](https://vercel.com/docs/functions/functions-api-reference/vercel-functions-package#waituntil) can finish the response first, but work continues within the function lifecycle. CPU-intensive background work still consumes Active CPU.

### Uncaught errors and process stops

Check [Runtime Logs](https://vercel.com/docs/logs/runtime) for process-level errors. Under [Fluid compute error isolation](https://vercel.com/docs/fluid-compute#isolation-boundaries-and-global-state), Vercel logs the error, lets current requests finish, and then stops the affected process.

After fixing the error, compare:

- Error rate
  
- Cold starts
  
- Invocations
  
- Active CPU per invocation
  
- Affected routes
  

A handled 5xx response does not by itself prove that the process stopped. Look for process-level errors and matching runtime signals.

### Adjust memory for CPU-bound functions

For CPU-bound functions, test the [memory setting](https://vercel.com/docs/functions/configuring-functions/memory#memory-configuration-considerations). More memory provides more CPU and can reduce Active CPU time, but it can also increase provisioned memory.

After changing the memory, compare both:

- Active CPU per invocation
  
- Provisioned memory
  

Low average [CPU throttling](https://vercel.com/docs/observability/insights#cpu-throttling) can be normal. If high throttling coincides with latency or timeouts, test a larger memory configuration and verify the tradeoff.

## 5\. Investigate with an agent

If you want an agent to investigate, start with read-only access and require route-level evidence before approving changes. Provide the team scope, project, production environment, exact increase window, hot routes, deployment IDs, and recent releases.

To get started with your coding agent, copy and adapt this prompt:

### Agent prompt

```txt
Investigate why Fluid Active CPU increased for <project> in <team> during <window>.
Start read-only. First, inspect the metrics schema for that team scope — it is the
source of truth for available metrics:

  vercel metrics schema --scope <team> --format json

Where available, query Function CPU Time and Invocations by route over the same
team, project, environment, and window, then derive CPU per invocation from the
matching totals:

  vercel metrics <cpu-metric-id> --scope <team> --project <project> --prod --since <start> --until <end> --aggregation sum --group-by route --order-by value --limit 50 --format json
  vercel metrics <invocation-metric-id> --scope <team> --project <project> --prod --since <start> --until <end> --aggregation sum --group-by route --order-by value --limit 50 --format json

If grouped results truncate a route you care about, re-run with a --filter on that
route. If Function metrics are unavailable (they require Observability Plus), use
the dashboard's Functions view instead and say so in your findings.

Corroborate with deployment metadata and runtime logs:

  vercel list <project> --scope <team> --environment production --status READY
  vercel inspect <deployment-id-or-url> --scope <team>
  vercel logs --scope <team> --project <project> --environment production --since <start> --until <end> --no-branch --json

Note that `vercel inspect --logs` prints build output, not Active CPU evidence.

Then inspect hot Route Handlers, Server Actions, layouts/pages, dynamic rendering,
uncached fetches, loops, transformations, background work, and upstream latency.
If cold starts or Node.js process stops rise, inspect the startup and module-scope
initialization. Return route evidence, the trigger, and a baseline before
recommending changes. Do not edit, deploy, change settings, purge caches, or
mutate data without my explicit approval.
```

### Vercel Plugin

The [Vercel Plugin](https://vercel.com/docs/agent-resources/vercel-plugin) turns your AI coding agent (e.g., OpenAI Codex, Claude Code, or Cursor) into a Vercel expert. It adds skills, slash commands, and current knowledge of the tools this template uses, including Vercel Connect, Vercel Blob, and AI Gateway. The plugin is optional; it isn't required to follow this guide.

`npx plugins add vercel/vercel-plugin`

## 6\. Verify the fix

After deploying one change, compare the same route across comparable windows.

Check the following indicators:

- Function CPU Time divided by Function invocations
  
- Total Function invocations
  
- Error rate
  
- Cache status
  
- Duration
  
- Provisioned memory
  

Use the same route, environment, status, and time window shape. For example, compare the same weekday and traffic period before and after deployment.

Do not treat a lower total Active CPU as proof by itself. Traffic may have dropped, the route mix may have changed, or errors may have prevented work from completing. A strong fix should reduce Active CPU per invocation for the affected route without increasing errors or introducing unintended caching behavior.

## Related resources

- [Fluid compute usage and pricing](https://vercel.com/docs/functions/usage-and-pricing)
  
- [Observability](https://vercel.com/docs/observability)
  
- [Query](https://vercel.com/docs/query)
  
- [Vercel caching](https://vercel.com/docs/caching)
  
- [Next.js caching](https://nextjs.org/docs/app/getting-started/caching)