py-spy logo

py-spy

Zero‑overhead sampling profiler for live Python applications

A low‑overhead, Rust‑based sampling profiler that attaches to running Python processes without code changes, generating flame graphs, live top views, and stack dumps across Linux, macOS, Windows, and FreeBSD.

Overview

Overview

py-spy is a Rust‑implemented sampling profiler that can attach to any running CPython process without modifying its code. By reading the target's memory directly, it provides accurate timing information while keeping overhead minimal, making it safe for use in production environments.

Capabilities & Deployment

The tool offers three sub‑commands: record for generating flame‑graph SVGs or speedscope files, top for a live, top‑like view of hot functions, and dump for a one‑off stack trace with optional locals. It supports profiling native extensions (--native), tracing subprocesses (--subprocesses), and works on Linux, macOS, Windows, and FreeBSD. Installation is straightforward via pip, Homebrew, Cargo, or distribution packages, and the binary runs out‑of‑process, avoiding any impact on the profiled application.

Developers, SREs, and performance engineers can quickly diagnose bottlenecks, even in multi‑process services, without redeploying or restarting the application.

Highlights

No code instrumentation; attaches to running processes
Extremely low overhead thanks to Rust and out‑of‑process sampling
Generates flame graphs, speedscope files, live top view, and stack dumps
Supports native extension profiling and automatic subprocess tracing

Pros

  • Safe for production use
  • Cross‑platform support for Linux, macOS, Windows, and FreeBSD
  • Simple installation via pip, Homebrew, Cargo, etc.
  • Multiple output formats for flexible analysis

Considerations

  • Root or sudo may be required to attach to existing processes
  • Limited to CPython; does not support PyPy or Jython
  • Native profiling needs symbols and is platform‑restricted
  • Strict security policies can block memory‑reading operations

Managed products teams compare with

When teams consider py-spy, these hosted platforms usually appear on the same shortlist.

Blackfire Continuous Profiler logo

Blackfire Continuous Profiler

Low-overhead continuous profiling for app performance optimization.

Datadog Continuous Profiler logo

Datadog Continuous Profiler

Always-on code profiling to cut latency and cloud costs.

Elastic Universal Profiling logo

Elastic Universal Profiling

Whole-system, always-on profiling with no instrumentation.

Looking for a hosted option? These are the services engineering teams benchmark against before choosing open source.

Fit guide

Great for

  • Developers debugging performance issues in live services
  • Ops teams needing quick insight without redeploying
  • Projects using C/C++ or Cython extensions that require combined profiling
  • Applications employing multiprocessing or Gunicorn workers

Not ideal when

  • Environments where root access cannot be granted
  • Projects using alternative Python interpreters
  • Scenarios requiring deterministic, line‑by‑line tracing
  • Systems with hardened security that block process memory reads

How teams use it

Generate flame graph for a production web service

Visualize hot paths without restarting, identify bottlenecks, and reduce latency.

Live monitoring of a data‑processing script

Use `py-spy top` to see real‑time function usage and spot stalls.

Profile a Cython‑accelerated module

Enable `--native` to include native frames, helping optimize compiled extensions.

Trace multiprocessing workers in a Gunicorn deployment

Attach with `--subprocesses` to collect samples from all worker processes.

Tech snapshot

Rust99%
Python1%
Shell1%

Tags

performance-analysisprofilerpythonprofiling

Frequently asked questions

Why do we need another Python profiler?

py-spy can profile any running Python program without code changes, making it safe for production where other profilers add noticeable overhead.

How does py-spy work?

It reads the target process's memory via system calls, inspects the interpreter state, and reconstructs call stacks without running inside the Python process.

Can py-spy profile native extensions?

Yes, using the `--native` flag. For best results the extension should be compiled with symbols.

How can I profile subprocesses?

Pass the `--subprocesses` flag; py-spy will automatically attach to child Python processes and include their samples.

When do I need to run py-spy with sudo?

Attaching to an existing process often requires root on Linux and always on macOS; creating the process with py-spy avoids this requirement.

Project at a glance

Active
Stars
14,853
Watchers
14,853
Forks
496
LicenseMIT
Repo age7 years old
Last commit2 weeks ago
Primary languageRust

Last synced yesterday