<@ULVA73B9P> my prefect workers were working fine ...
# ask-marvin
j
@Marvin my prefect workers were working fine and now they are using 100% of the CPU. I am not sure why, what can I use to debug or alleviate CPU pressure? It is running as a process worker in Azure Container Apps
m
thought for 437.0 seconds
Got it — let’s get your process worker under control. Assuming Prefect 3.x. A few targeted changes can both diagnose the cause and immediately reduce CPU. First, a couple quick questions to narrow it down: - Did this start after a recent image or Prefect upgrade? - Is CPU pegged even when no flows are running, or only when runs are in progress? - Do your worker logs show websocket/cancellation observer errors? Immediate mitigations (safe to apply now) - Reduce concurrency on the worker
Copy code
prefect worker start -p <your-pool> --limit 1
Then raise gradually (2–4) if needed. - Poll less frequently and heartbeat less often to cut background CPU
Copy code
# Set these in your container env or before starting the worker
  export PREFECT_WORKER_QUERY_SECONDS=30       # default 10
  export PREFECT_WORKER_HEARTBEAT_SECONDS=60   # default 30
  export PREFECT_WORKER_PREFETCH_SECONDS=15    # default 10
  export PREFECT_LOGGING_LEVEL=INFO            # avoid DEBUG
  prefect worker start -p <your-pool> --limit 2
- Scale out instead of up - Run 2–3 worker replicas with low
--limit
(1–2 each) in Azure Container Apps. What to check to diagnose the spike 1) Confirm current Prefect settings
Copy code
prefect config view --show-defaults
Look for
worker.query_seconds
,
worker.heartbeat_seconds
,
worker.prefetch_seconds
, and your logging level. 2) Look for websocket fallback (can increase CPU if it’s polling)
Copy code
# Start the worker and watch logs for these keywords
   prefect worker start -p <your-pool> 2>&1 | grep -i "websocket\|cancell\|observer\|poll"
If you see messages about the FlowRunCancellingObserver websocket failing and falling back to polling, check network/firewall/proxy rules from your ACA container to Prefect Cloud/Server for wss:// connectivity. 3) Identify whether CPU comes from the worker loop or your flow processes - The process worker runs flow runs as child processes. In ACA, exec into the container and use `top`/`ps` to see which PID is hot:
Copy code
ps -o pid,pcpu,comm -e | grep -i python
If child processes are hot, it’s your flow code; use
--limit
and consider optimizing the flow, or split into more, smaller replicas. 4) Profile the worker if possible (best effort in containers)
Copy code
pip install py-spy
   # Start the worker, get its PID, then:
   py-spy top -p <worker-pid>
   # Or capture a flamegraph
   py-spy record -o profile.svg -p <worker-pid> --duration 30
If attaching is blocked in ACA, run the same container image locally to profile or add a lightweight sampler like pyinstrument to a test run. 5) Check for logging overhead - If
PREFECT_LOGGING_LEVEL=DEBUG
, log formatting + network log sinks can burn CPU. Keep
INFO
for workers. - If sending logs to remote sinks, ensure they’re non-blocking/buffered. 6) Concurrency and scheduling pressure - Large
--limit
values increase simultaneous subprocesses and API churn. - If you have many scheduled runs, higher
prefetch_seconds
can increase CPU; keep it modest (10–15). Azure Container Apps specifics - Verify the container’s CPU limit/requests didn’t change recently (ACA shows 100% when your container hits its CPU limit). - If you deploy with a lower CPU quota than before, the same workload can appear pegged; add a bit more CPU or scale out with lower
--limit
. If you can share: - Prefect version (
prefect version
) - Worker command you run - Snippets of recent worker logs around the time CPU spikes (especially websocket/cancellation observer messages) - Whether the CPU spikes persist when no flow runs are executing I’ll tailor the next steps based on that.