Sampling profiler for Python programs written in Rust with extremely low overhead
—
Complete command-line profiling tool providing three main subcommands for different profiling scenarios. Supports extensive configuration for production environments, development workflows, and advanced profiling scenarios.
Records profiling samples to files in various formats. Creates flame graphs, speedscope profiles, and other visualization formats for offline analysis.
py-spy record [OPTIONS] [TARGET]
# Record to flamegraph (SVG)
py-spy record -o profile.svg --pid 12345
py-spy record -o profile.svg -- python myprogram.py
# Record to speedscope JSON
py-spy record -f speedscope -o profile.json --pid 12345
# Record to Chrome trace format
py-spy record -f chrometrace -o trace.json --pid 12345
# Record raw flamegraph data
py-spy record -f raw -o profile.txt --pid 12345Target Options:
--pid PID or -p PID: Profile existing process by PID (decimal or hex)-- PYTHON_PROGRAM [ARGS...]: Launch and profile new Python programOutput Options:
--output FILE or -o FILE: Output filename (auto-generated if not specified)--format FORMAT or -f FORMAT: Output format (flamegraph, speedscope, chrometrace, raw)Recording Options:
--duration SECONDS or -d SECONDS: Recording duration (unlimited if not specified)--rate RATE or -r RATE: Sampling rate in Hz (default: 100)Provides live console view of profiling data, similar to Unix top command. Updates in real-time showing function call distribution and thread activity.
py-spy top [OPTIONS] [TARGET]
# Live view of existing process
py-spy top --pid 12345
# Live view of new Python program
py-spy top -- python myprogram.pyDisplay Options:
--rate RATE or -r RATE: Sampling rate in Hz (default: 100)--refresh-seconds SECONDS: Display refresh interval (default: 1.0)Takes single snapshot of call stacks for all threads. Useful for debugging hung processes or getting immediate stack trace information.
py-spy dump [OPTIONS] [TARGET]
# Simple stack dump
py-spy dump --pid 12345
# Dump with local variables
py-spy dump --locals --pid 12345
# JSON format output
py-spy dump --json --pid 12345Output Options:
--locals: Include local variables in stack frames--json: Output in JSON format--pid PID, -p PID
# Process ID to profile (decimal or hex)
py-spy record --pid 12345 -o profile.svg
py-spy record --pid 0x3039 -o profile.svg
-- PYTHON_PROGRAM [ARGS...]
# Launch and profile new Python program
py-spy record -o profile.svg -- python -m mymodule --arg value
py-spy top -- python script.py arg1 arg2--native, -n
# Include native C/C++/Cython stack traces
py-spy record --native -o profile.svg --pid 12345
--nonblocking
# Non-blocking sampling (reduced performance impact)
py-spy record --nonblocking -o profile.svg --pid 12345
--subprocesses, -s
# Profile child processes and subprocess spawns
py-spy record --subprocesses -o profile.svg --pid 12345
--gil
# Only show threads holding the Global Interpreter Lock
py-spy top --gil --pid 12345
--idle, -i
# Include idle/sleeping threads in results
py-spy record --idle -o profile.svg --pid 12345--full-filenames
# Show full Python file paths instead of shortened versions
py-spy dump --full-filenames --pid 12345
--include-thread-ids
# Include thread IDs in flamegraph output
py-spy record --include-thread-ids -o profile.svg --pid 12345
--show-line-numbers
# Include line numbers in stack traces
py-spy dump --show-line-numbers --pid 12345--core CORE_FILE
# Analyze Python process from core dump (Linux only)
py-spy dump --core /path/to/core.dump# Requires root privileges
sudo py-spy record -o profile.svg --pid 12345# Requires SYS_PTRACE capability
docker run --cap-add=SYS_PTRACE image_name
# Or in docker-compose.yml:
# cap_add:
# - SYS_PTRACEsecurityContext:
capabilities:
add:
- SYS_PTRACE# Profile development server
py-spy record -o dev-profile.svg -- python manage.py runserver
# Monitor performance during development
py-spy top -- python myapp.py
# Debug hanging script
py-spy dump --locals --pid 12345# Low-impact production profiling
py-spy record --nonblocking -d 30 -o prod-profile.svg --pid 12345
# Profile with subprocesses (e.g., gunicorn workers)
py-spy record --subprocesses -d 60 -o worker-profile.svg --pid 12345
# Profile only GIL-holding threads
py-spy record --gil -d 30 -o gil-profile.svg --pid 12345# Include native extensions (C/C++/Cython)
py-spy record --native -o native-profile.svg --pid 12345
# Generate speedscope format for detailed analysis
py-spy record -f speedscope -o analysis.json --pid 12345
# High-frequency sampling for detailed profiling
py-spy record -r 1000 -d 10 -o detailed.svg --pid 12345# Before optimization
py-spy record -o before.svg -- python myapp.py input.txt
# After optimization
py-spy record -o after.svg -- python myapp.py input.txt
# Compare using speedscope format
py-spy record -f speedscope -o before.json -- python myapp.py input.txt
py-spy record -f speedscope -o after.json -- python myapp.py input.txt0: Successful completion1: Error occurred (permission denied, process not found, etc.)# Force colored output when piping to pager
CLICOLOR_FORCE=1 py-spy top --pid 12345 | less -RInstall with Tessl CLI
npx tessl i tessl/pypi-py-spy