Skip to content
Docs

Troubleshoot and optimize Active CPU usage on Fluid compute

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.

Mike DarlingtonDev Success Engineer

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 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

Copy link to headingUnderstand Active CPU

In Fluid compute, 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:

SignalWhat it means
Active CPUTime spent actively executing code
Function invocationsNumber of function requests
Active CPU per invocationApproximate CPU work per request
Invocation durationWall-clock time, including waiting and streaming
Provisioned memoryMemory 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.

This guide covers the current Fluid compute model. Legacy Function Duration uses a different wall-clock model and is outside this workflow.

Copy link to headingBefore 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.

Copy link to heading1. Confirm the usage source

First, confirm which compute products contribute to the selected usage. Routing Middleware 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.
  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.

Copy link to heading2. 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, 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.

Copy link to heading3. Interpret the pattern

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

What changedLikely causeStart with
Active CPU and invocations both increasedMore traffic or a changed request mixRequest amplification, bots, route mix, caching
Active CPU per invocation increasedMore CPU work per requestRendering, transforms, compilation, media work
Duration increased, but Active CPU did notMore waiting or streamingUpstream APIs, databases, and long responses
Active CPU increased with errors or cold startsProcess errors or repeated initializationRuntime Logs, startup code, uncaught exceptions
Active CPU stayed stable, but memory roseLonger in-flight requestsStreaming, 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.

Copy link to heading4. Common causes and fixes

Copy link to headingRequest 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
  • Route mix changes
  • Automated traffic
  • Bot traffic
  • Cache misses on high-volume routes

The Edge Requests view 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 do not invoke the function.

Copy link to headingRepeated 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, 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 only when freshness and privacy requirements allow it.
  • With Cache Components, use 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; 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.

Copy link to headingPer-request transforms and media work

Inspect hot handlers for large JSON parsing, transformation, and serialization pipelines. Because Active CPU counts code execution, 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 when safe.

For image or Open Graph generation, pregenerate invariant Open Graph images or cache eligible outputs. Do not weaken password-hashing parameters to reduce CPU; remove duplicate work around the security control instead.

Copy link to headingWaiting on background work

Use the preloading pattern to start independent I/O together. This can shorten wall time, but work between awaits still consumes Active CPU.

Next.js after() and Vercel waitUntil() can finish the response first, but work continues within the function lifecycle. CPU-intensive background work still consumes Active CPU.

Copy link to headingUncaught errors and process stops

Check Runtime Logs for process-level errors. Under Fluid compute error isolation, 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.

Copy link to headingAdjust memory for CPU-bound functions

For CPU-bound functions, test the memory setting. 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 can be normal. If high throttling coincides with latency or timeouts, test a larger memory configuration and verify the tradeoff.

Copy link to heading5. 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

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.

Copy link to headingVercel Plugin

The 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.

Terminal
npx plugins add vercel/vercel-plugin

Copy link to heading6. 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.

Copy link to headingRelated resources

More Fluid compute guides