Process & Resource Management
ps, htop, signals, nohup, and resource limits on Linux - manage Python web workers, Celery processes, and long-running scripts without orphan zombies or OOM kills.
Search across all documentation pages
ps, htop, signals, nohup, and resource limits on Linux - manage Python web workers, Celery processes, and long-running scripts without orphan zombies or OOM kills.
pgrep -af "uvicorn|celery|gunicorn"
kill -TERM <pid>
sleep 5
kill -KILL <pid> # only if still running
htop -p <pid>When to reach for this:
# Find billing-api master and workers
pgrep -af gunicorn
# Graceful reload (if USR2/HUP configured) or TERM
sudo kill -TERM "$(pgrep -f 'gunicorn.*billing-api' | head -1)"
sleep 10
sudo ss -tlnp | grep 8000
# Check open files for connection leak
PID=$(pgrep -f 'uvicorn app.main:app' | head -1)
ls -l /proc/$PID/fd | wc -l
cat /proc/$PID/limits | grep "open files"What this demonstrates:
pgrep -af shows full command line for Python processes/proc inspection for fd leaks| Signal | Python service effect |
|---|---|
| SIGTERM | Uvicorn/Gunicorn stops accepting; drains requests |
| SIGINT | Same as Ctrl+C in foreground dev |
| SIGHUP | Reload config in some daemons |
| SIGKILL | Immediate death - no finally blocks |
# app registers SIGTERM handler for cleanup
import signal
def handle_term(signum, frame):
close_db_pool()
signal.signal(signal.SIGTERM, handle_term)ps -fp.dmesg -T | rg -i oom.LimitNOFILE in systemd.| Alternative | Use When | Don't Use When |
|---|---|---|
| systemd restart | Production services | Quick local experiment |
| Docker stop | Container grace period | Bare metal VM |
| Kubernetes delete pod | Orchestrated roll | SSH troubleshooting |
| py-spy | Sampling stuck Python | Simple restart suffices |
Match upstream load balancer drain timeout - often 10-30s for APIs.
One process per CPU with --workers N under gunicorn; each appears in pgrep.
celery control shutdown or TERM worker; allow task acks_late to finish.
nice -n 10 uv run python batch.py reduces CPU contention with API on same VM.
systemd-run -p MemoryMax=2G ... caps runaway worker on shared host.
Last resort performance/debug - huge overhead; try py-spy first.
ss for listening ports; lsof -p for open files/sockets per PID.
High load with low CPU may be IO wait - check iostat.
Identify parent with ps -o ppid= -p ZPID; restart parent process.
available column in free -h matters more than free cache reading.
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.
Reviewed by Chris St. John·Last updated Jul 16, 2026