Skip to content

py-spy

A sampling profiler for Python that shows where a running program spends its time, without changing its code.

Stars
15.6k
Forks
557
Licence
MIT
Language
Rust
Last update
9 days ago
Type
Dev tool

What it is

py-spy watches a running Python program from outside and records which functions it is spending time in, producing flame graphs, live top-style views, or single call-stack dumps. It runs as a separate process and reads the target's memory, so you do not need to restart the program or add profiling code to it. The README says it is written in Rust and is low overhead enough to use on production code.

  • Generate an interactive SVG flame graph with py-spy record -o profile.svg --pid PID
  • View a live updating list of the functions using the most time with py-spy top
  • Dump the current call stack of each Python thread to find where a program is stuck
  • Profile child processes of a program by passing --subprocesses

Great for

  • Developers diagnosing slow Python programs without changing the code
  • Engineers investigating a hung process by dumping its current call stacks
  • Teams who need to profile production services that cannot be restarted
  • People profiling programs that use multiprocessing or gunicorn worker pools

Not ideal for

  • Users on unsupported platforms: the README lists Linux, OSX, Windows and FreeBSD, and native-extension profiling has limited platform support in its table
  • Anyone who needs exact call counts or deterministic tracing, since this is a sampling profiler
  • Users who cannot run as root when attaching to an existing process on Linux without changing system settings
Step-by-step guide: how to use py-spyInstall, first run, examples, tips and FAQs

How to get it

  1. 1

    Install with a package manager

    Install prebuilt binary wheel from PyPI

    pip install py-spy

    Install on macOS with Homebrew

    brew install py-spy
  2. 2

    Run it

    • Install py-spy with pip install py-spy
    • Find the PID of your running Python program
    • Run py-spy top --pid PID for a live view, or py-spy record -o profile.svg --pid PID for a flame graph
    • Open the generated SVG file in a browser to explore the results
  3. 3

    Get the most out of it

    • Use --format to output speedscope profiles or raw data instead of SVG
    • Use --native to profile native C, C++ or Cython extensions on supported platforms
    • Use --locals with py-spy dump to see local variables in each stack frame
    • Run py-spy record -- python myprogram.py to avoid needing root on Linux

Downloads

Strengths

  • Does not need changes to the profiled program or restarting it
  • The README describes it as running outside the target process, which reduces overhead risk
  • Supports multiple output formats including flame graphs and speedscope profiles

Trade-offs

  • Attaching to an existing process by PID usually requires root on Linux, and always requires root on OSX per the README
  • Native extension profiling works only on some platforms and needs symbols for best results
  • Reads interpreter memory, so results depend on matching Python versions and may be less reliable when binaries are stripped

How it compares

ProjectStarsTypeLevelUpdatedBest for
py-spy (this)15.6kDev toolbeginner9 days agoDevelopers diagnosing slow Python programs without changing the code
laravel-debugbar19.3kLibrarybeginner9 days agoLaravel developers investigating slow pages or unexpected database queries

Stats synced from GitHub. The assessment above was drafted with AI from the project's README on 2026-10-29 and may miss recent changes — check the README before relying on a command. MIT licence: free to use, modify and distribute, including commercially, as long as you keep the copyright notice.