Registry / observability / pyinstrument

pyinstrument

JSON →
library5.1.3pypypi✓ verified 27d ago

Pyinstrument is a powerful call stack profiler for Python that helps developers understand why their code is slow. It operates by sampling the call stack at regular intervals, providing a clear, interactive visualization of time spent in different functions. The current stable version is 5.1.2, and the library maintains an active release cadence with frequent updates addressing bugs and introducing new features, particularly around its HTML rendering capabilities.

pip install pyinstrument
INSTALL
IMPORT
SIG · PYINSTRUMENT
P
pyinstrument
observabilitypythonv5.1.3
Install
1.7s avg
Import
131ms
Disk
17MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v5.1.3 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.138s · 18.5MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 1.7s · import 0.124s · 19MB
17MB installed
● package 17MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Profiler
from pyinstrument import Profiler
HTMLRenderer
from pyinstrument.renderers import HTMLRenderer
ConsoleRenderer
from pyinstrument.renderers import ConsoleRenderer

This quickstart demonstrates how to profile a section of code using Pyinstrument's `Profiler` class and its `start()`/`stop()` methods, followed by generating both console text output and an interactive HTML report. For profiling an entire script from the command line, you can use `pyinstrument your_script.py`.

from pyinstrument import Profiler import time import os def my_slow_function(): time.sleep(0.05) another_slow_part() def another_slow_part(): time.sleep(0.02) # Using the context manager (recommended for specific code blocks) profiler = Profiler() profiler.start() for _ in range(5): my_slow_function() profiler.stop() # Output to console print("\n--- Console Output ---") print(profiler.output_text(unicode=True, color=True)) # Generate HTML report # For simplicity, we'll write to a file directly. In a real app, # you might return this HTML via a web framework. html_output = profiler.output_html() output_filename = os.path.join(os.getcwd(), "pyinstrument_profile.html") with open(output_filename, "w") as f: f.write(html_output) print(f"\nHTML report saved to: {output_filename}") print("Open the HTML file in your browser to view the interactive profile.")
pyinstrument --version
Debug
Known issues
breakingIn Pyinstrument v5.0.0, the mechanism for detecting 'library' code (code not directly part of your application) was changed. This might alter how the profiler categorizes and displays frames, potentially affecting filtering or interpretation of results for users who relied on the previous classification.
fix
Review your profiling reports after upgrading to v5.0.0+ to ensure the 'library' code classification still aligns with your expectations. Adjust custom renderers or filtering if necessary.
affects: >=5.0.0
gotchaPyinstrument, like most profilers, introduces some overhead. While it's designed to be low-overhead, profiling very short-lived functions or extremely high-frequency code paths can still show distorted results. The sampling interval (`--interval` CLI option or `Profiler(interval=...)` parameter) can affect both overhead and precision.
fix
For critical performance measurements, compare results with and without the profiler. Use the `--interval` option (e.g., `pyinstrument --interval 0.0001`) to balance overhead and precision. Consider using the `with Profiler():` context manager for profiling only specific, critical sections of code to minimize overall impact.
affects: <5.1.0 (improved in 5.1.0)
gotchaMismatched calls to `profiler.start()` and `profiler.stop()` can lead to 'call stack without an active session' errors or incomplete profiles. This often happens in complex control flows or when exceptions interrupt profiling.
fix
Always ensure `start()` and `stop()` calls are properly balanced. The `with Profiler() as profiler:` context manager (introduced in v4.7.0) is highly recommended as it automatically handles starting and stopping, even with exceptions, greatly reducing the chance of such errors.
affects: <5.1.2 (bug fixed in 5.1.2, but good practice remains)
breakingPyinstrument versions prior to 4.7.3 could crash on Python 3.12 and later when profiling code that mutates the `locals()` dictionary, affecting compatibility with certain libraries (e.g., `glom`).
fix
Upgrade to Pyinstrument v4.7.3 or newer to resolve compatibility issues with Python 3.12+ and libraries that modify `locals()` during execution.
affects: <4.7.3 on Python 3.12+
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'pyinstrument_cext'
This error occurs when the `pyinstrument_cext` C extension, a critical component of Pyinstrument, fails to compile or is not properly installed or located within the Python environment, particularly in restricted or containerized deployment settings like Docker or AWS Lambda.
fix
Ensure Pyinstrument is installed in the correct virtual environment using `pip install pyinstrument`. If issues persist, verify that the build process for your deployment environment allows C extensions to compile correctly, or consider using a Python version for which pre-built wheels for `pyinstrument_cext` are readily available.
Larger HTML files not loading in any browser
The generated HTML profile report can become excessively large and complex, especially when profiling extensive codebases or using the `--show-all` option, which can cause web browsers to struggle with parsing and rendering the file efficiently due to resource limitations.
fix
To resolve this, reduce the complexity of the profile by using command-line options like `--hide '*/lib/*'` or `--hide-regex '.*vendor.*'` to exclude irrelevant library code. Alternatively, in the Python API, adjust the `filter_threshold` when rendering the report or consider using alternative renderers such as `speedscope` for better visualization of large profiles.
No samples were recorded.
This message indicates that the code being profiled executed too quickly for Pyinstrument's default sampling interval (which is 0.001 seconds or 1 millisecond) to capture any call stack samples during its execution.
fix
Decrease the profiling interval to a smaller value to capture samples from very fast code. In the Python API, initialize the profiler with `profiler = Profiler(interval=0.0001)`. When using the command line, use the `--interval 0.0001` option.
pyinstrument script.py where script.py contains a class serialized with pickle, you might encounter errors because the serialisation machinery doesn't know where __main__ is.
This occurs when Pyinstrument profiles a script that attempts to `pickle` (serialize) objects, particularly classes defined directly within the `__main__` scope of the script. The `pickle` module struggles to correctly resolve the `__main__` module's context when the script is executed by Pyinstrument.
fix
Refactor your code to define any classes intended for pickling in a separate Python module and import them into your main script. If possible, ensure that the pickling operation occurs outside the section of code being profiled by Pyinstrument.
Upgrade
Version history
5.1.3latest on PyPI · released Jul 29, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
23 hits · last 30 days
node
20
OpenAI (training)
2
Resources
pyinstrument — pip install pyinstrument · libregistry