Rupesh Raut
04/14/2026, 11:26 AMprefect server metrics something over the internet, please provide official info along with documentation and code snippet to enable this feature.Marvin
04/14/2026, 11:26 AMMarvin
04/14/2026, 11:35 AMprefect server metrics CLI command in 3.x (that subcommand does not exist).
- The official way to expose metrics is:
- A Prometheus /api/metrics endpoint on the Prefect Server
- A lightweight Prometheus HTTP server in each Prefect client/worker process
Below are the official ways to enable both, with docs and code.
How to expose Prometheus metrics from Prefect Server
- Enable the server’s Prometheus endpoint and restart your server:
# via environment variable
export PREFECT_SERVER_METRICS_ENABLED=true
# legacy alias also accepted: PREFECT_API_ENABLE_METRICS=true
# or persist to your profile
prefect config set PREFECT_SERVER_METRICS_ENABLED=true
# start the server
prefect server start
- Verify:
curl <http://localhost:8080/api/metrics>
- Docs and source
- Settings reference: Prefect settings reference
- Server API settings: Server API settings (docs)
- Source (settings): prefect/settings/models/server/api.py
- Source (endpoint): prefect/server/api/server.py (exposes /api/metrics)
How to expose per-worker Prometheus metrics
Enable the client metrics HTTP server in each worker process (this gives you per-worker metrics to scrape):
# set on each worker
export PREFECT_CLIENT_METRICS_ENABLED=true
export PREFECT_CLIENT_METRICS_PORT=4201 # default is 4201
# then start the worker
prefect worker start -p <your-work-pool>
- Verify:
curl http://<worker-host>:4201/metrics
- Docs and source
- Client metrics settings: Client metrics settings (docs)
- Settings reference: Prefect settings reference
- Source (settings): prefect/settings/models/client.py
- Source (service): start_client_metrics_server() docs
What you can monitor per worker
- From the API/UI: worker ONLINE/OFFLINE status, last heartbeat, and heartbeat interval.
- CLI:
prefect work-pool inspect "my-pool" --output json
- UI: Work Pools page shows worker list, status, and last heartbeat.
- From Prometheus (per worker): client-side Prefect metrics (events/log websocket counters, etc.) on the port you enable (e.g., 4201).
- Note: There is no built-in “active runs per worker” metric exposed by the API today. Workers do track concurrency internally, but that count is not exported as a Prometheus metric. To correlate load, combine:
- Worker heartbeats + status (UI/API)
- Flow run states by pool/queue (API)
- Infra-level metrics (CPU/memory) via node-exporter/cAdvisor or OTLP resource metrics (see below)
Optional: OS-level resource metrics (OpenTelemetry)
If you want CPU/memory usage for flow run subprocesses exported to an OTLP collector:
export PREFECT_TELEMETRY_ENABLE_RESOURCE_METRICS=true
# Point to your OTLP collector
export OTEL_EXPORTER_OTLP_METRICS_ENDPOINT="<http://collector:4318/v1/metrics>"
# or
export OTEL_EXPORTER_OTLP_ENDPOINT="<http://collector:4318>"
- Source (resolution logic): prefect/telemetry/_metrics.py
- Settings (telemetry): prefect/settings/models/telemetry.py
Prometheus scrape examples
- Prometheus config to scrape both the server and a worker:
```
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'prefect-server'Marvin
04/14/2026, 11:35 AMMinimal Docker Compose example
services:
prefect-server:
image: prefecthq/prefect:latest
environment:
PREFECT_SERVER_METRICS_ENABLED: "true"
PREFECT_API_URL: "http://0.0.0.0:8080/api"
ports:
- "8080:8080"
command: prefect server start
worker-a:
image: prefecthq/prefect:latest
environment:
PREFECT_API_URL: "http://prefect-server:8080/api"
PREFECT_CLIENT_METRICS_ENABLED: "true"
PREFECT_CLIENT_METRICS_PORT: "4201"
ports:
- "4201:4201"
command: prefect worker start -p default
depends_on:
- prefect-server
```
A couple of important notes
- There is no prefect server metrics CLI command in Prefect 3.x. Use the /api/metrics endpoint by enabling server metrics as shown above.
- Per-worker “load” is best approximated today by:
- Worker status and heartbeats (UI/CLI/API)
- Scraping each worker’s client metrics port
- Infra-level metrics (CPU/memory) via exporters or OTLP
- Optionally, query running flow runs by work pool/queues to see demand
If you share how you’re running workers (Docker, Kubernetes, systemd), I can provide a tailored snippet for that environment.Rupesh Raut
04/14/2026, 11:41 AMPREFECT_SERVER_METRICS_ENABLED=true
and in the server start, I have written, prefect server start --workers 4
I want to see stats/metrics for each server worker
# HELP python_gc_objects_collected_total Objects collected during gc
# TYPE python_gc_objects_collected_total counter
python_gc_objects_collected_total{generation="0"} 103756.0
python_gc_objects_collected_total{generation="1"} 49896.0
python_gc_objects_collected_total{generation="2"} 31223.0
# HELP python_gc_objects_uncollectable_total Uncollectable objects found during GC
# TYPE python_gc_objects_uncollectable_total counter
python_gc_objects_uncollectable_total{generation="0"} 0.0
python_gc_objects_uncollectable_total{generation="1"} 0.0
python_gc_objects_uncollectable_total{generation="2"} 0.0
# HELP python_gc_collections_total Number of times this generation was collected
# TYPE python_gc_collections_total counter
python_gc_collections_total{generation="0"} 1580.0
python_gc_collections_total{generation="1"} 142.0
python_gc_collections_total{generation="2"} 10.0
# HELP python_info Python platform information
# TYPE python_info gauge
python_info{implementation="CPython",major="3",minor="11",patchlevel="5",version="3.11.5"} 1.0
# HELP process_virtual_memory_bytes Virtual memory size in bytes.
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 3.077439488e+09
# HELP process_resident_memory_bytes Resident memory size in bytes.
# TYPE process_resident_memory_bytes gauge
process_resident_memory_bytes 3.7056512e+08
# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
# TYPE process_start_time_seconds gauge
process_start_time_seconds 1.77616650375e+09
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 10.959999999999999
# HELP process_open_fds Number of open file descriptors.
# TYPE process_open_fds gauge
process_open_fds 17.0
# HELP process_max_fds Maximum number of open file descriptors.
# TYPE process_max_fds gauge
process_max_fds 1024.0
# HELP prefect_events_emitted_total The number of events emitted by Prefect event clients
# TYPE prefect_events_emitted_total counter
# HELP prefect_events_observed_total The number of events observed by Prefect event subscribers
# TYPE prefect_events_observed_total counter
# HELP prefect_event_websocket_connections_total The number of times Prefect event clients have connected to an event stream, broken down by direction (in/out) and connection (initial/reconnect)
# TYPE prefect_event_websocket_connections_total counter
# HELP prefect_event_websocket_checkpoints_total The number of checkpoints performed by Prefect event clients
# TYPE prefect_event_websocket_checkpoints_total counter
# HELP prefect_logs_observed_total The number of logs observed by Prefect log subscribers
# TYPE prefect_logs_observed_total counter
# HELP prefect_log_websocket_connections_total The number of times Prefect log clients have connected to a log stream, broken down by direction (in/out) and connection (initial/reconnect)
# TYPE prefect_log_websocket_connections_total counterMarvin
04/14/2026, 11:41 AMMarvin
04/14/2026, 11:44 AMMarvin
04/14/2026, 1:03 PMMarvin
04/14/2026, 1:05 PMslabtop -sc # live view, sort by cache size
cat /proc/meminfo | egrep 'Slab|SReclaimable|SUnreclaim'
cat /proc/slabinfo | sort -k3 -n | tail -n 25
egrep 'dentry|inode_cache|kmalloc|skbuff' /proc/slabinfo | sort -k3 -n | tail -n 10
- dentry/inode_cache growth → high file churn (lots of files/dirs created/read).
- skbuff_* growth → high/long‑lived TCP traffic or many idle sockets.
- kmalloc-* growth → generic kernel allocations; correlate with other signals.
- Check for file descriptor/socket leakage by the worker process
PID=$(pgrep -f 'prefect worker start')
ls -l /proc/$PID/fd | wc -l
lsof -p $PID | wc -l
ss -s
ss -tanp | grep $PID
- Check temp/work directories for churn or orphaned files
du -sh /tmp
find /tmp -maxdepth 1 -type d -name 'prefect*' -print
Environment questions (to tailor next steps)
- How are you running the worker: Process, Docker, or Kubernetes worker?
- OS/distro and kernel version; container runtime (Docker/Moby/containerd), if any.
- Prefect version and Python version.
- Approx. flow runs/day and whether they create many small files or large logs locally.
- Are you persisting results/logs locally or to remote storage?
- Any resource limits on the worker container/host?
Common causes and Prefect-aware mitigations
- Heavy file churn → dentry/inode slab growth
- Ensure flow runs are not leaving temp dirs/files behind (e.g., if runs crash before cleanup).
- Periodically prune temp dirs:
sudo find /tmp -maxdepth 1 -type d -name 'prefect*' -mtime +1 -exec rm -rf {} +
- Prefer remote result storage (object storage) over local disk for large/temporary outputs.
- Many open/idle sockets → skbuff_* growth
- Look for reconnect storms (network instability to API). The worker should have only a small number of steady connections.
- If you see a large/monotonic count of TCP connections for the worker PID, we should investigate logs/events clients or any custom code opening sockets and not closing.
- Docker hosts (Process/Docker workers)
- Configure container log rotation (json‑file driver) to avoid inode/dentry churn:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "3"
}
}
- Prune unused images/volumes regularly (carefully): docker system prune and docker image prune.
- Kubernetes nodes
- Ensure container log rotation is enabled on the node.
- Check if pods mount paths with high file churn; verify that cleanup jobs run.
- Reduce worker concurrency → less churn per host
- Set a work pool concurrency limit to cap simultaneous runs:
prefect work-pool set-concurrency-limit "my-pool" N
Then observe slab trends again.
- Make restarts intentional
- If a slow kernel-memory creep is unavoidable in your environment or workload, schedule a controlled restart of the worker (e.g., daily) via your process manager or orchestrator rather than waiting for OOM.
Add observability for correlation
- Enable per‑worker Prometheus metrics (Prefect client metrics):
export PREFECT_CLIENT_METRICS_ENABLED=true
export PREFECT_CLIENT_METRICS_PORT=4201
prefect worker start -p <your-pool>
Then scrape http://<worker-host>:4201/metrics alongside node‑level exporters (e.g., node_exporter) so you can correlate flow activity with slab growth.
- Client metrics setting ref: Client metrics settings (docs)Marvin
04/14/2026, 1:05 PMslabtop -sc (after a few days of uptime).
- Trend of ls -l /proc/$PID/fd | wc -l for the worker process over time.
- Whether you’re on bare metal, Docker, or Kubernetes (plus versions).
- Any evidence of leftover temp dirs or large local log/result directories.
With those, I can recommend targeted fixes (e.g., cleaning a specific temp path, adjusting logging, or addressing connection churn).