pstats
The Python pstats module provides a Stats class for reading, manipulating, and printing profiling data produced by cProfile and profile. It turns raw profile output into sorted, filtered reports that reveal where a program spends its time.
Here’s a quick example:
>>> import cProfile, pstats
>>> from pstats import SortKey
>>> cProfile.run("sum(i * i for i in range(1000))", "/tmp/restats")
>>> p = pstats.Stats("/tmp/restats")
>>> p.strip_dirs().sort_stats(SortKey.CUMULATIVE).print_stats(3)
1006 function calls in 0.000 seconds
Ordered by: cumulative time
List reduced from 6 to 3 due to restriction <3>
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 {built-in method builtins.exec}
...
Each row of the report describes one function in the profiled code:
ncalls: number of calls to that functiontottime: total time spent inside the function, excluding sub-callspercall: time per call based ontottimecumtime: cumulative time including everything the function calledpercall: time per call based oncumtimefilename:lineno(function): location of the profiled code
Key Features
- Loads profile data from one or more files written by
cProfileorprofile, or from aProfileinstance directly. - Sorts statistics by call count, internal time, cumulative time, file name, line number, or function name.
- Filters reports with line counts, percentages, or regular expressions.
- Prints caller and callee relationships to trace where time flows between functions.
- Combines results from multiple profiling runs into a single aggregated report.
- Provides an interactive browser through
python -m pstats.
Frequently Used Classes and Functions
| Object | Type | Description |
|---|---|---|
pstats.Stats |
Class | Loads and formats profiling statistics from files or Profile objects. |
pstats.SortKey |
Class | Enumerates valid sort keys such as CALLS, TIME, and CUMULATIVE. |
Stats.strip_dirs() |
Method | Removes leading path information from file names in the report. |
Stats.sort_stats() |
Method | Sorts the statistics by one or more keys. |
Stats.print_stats() |
Method | Prints the profiling report, optionally restricted by count, fraction, or regex. |
Stats.print_callers() |
Method | Prints the functions that called each profiled function. |
Stats.print_callees() |
Method | Prints the functions called by each profiled function. |
Stats.add() |
Method | Merges additional profile files into the current Stats object. |
Stats.dump_stats() |
Method | Writes the loaded statistics to a file for later analysis. |
Examples
Sort by total internal time and show the top five offenders:
>>> import pstats
>>> from pstats import SortKey
>>> p = pstats.Stats("/tmp/restats")
>>> p.sort_stats(SortKey.TIME).print_stats(5)
1005 function calls in 0.000 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 {built-in method builtins.sum}
1001 0.000 0.000 0.000 0.000 <string>:1(<genexpr>)
1 0.000 0.000 0.000 0.000 {built-in method builtins.exec}
...
Filter the report with a regular expression to focus on a specific function:
>>> p.print_stats("inner")
9 function calls in 0.000 seconds
Random listing order was used
List reduced from 5 to 1 due to restriction <'inner'>
ncalls tottime percall cumtime percall filename:lineno(function)
5 0.000 0.000 0.001 0.000 <stdin>:4(inner)
List the callers of a function to see where its time is coming from:
>>> p.strip_dirs().sort_stats(SortKey.CUMULATIVE).print_callers("inner")
Function was called by...
ncalls tottime cumtime
<stdin>:4(inner) <- 5 0.000 0.001 <stdin>:7(outer)
Combine results from multiple profiling runs:
>>> p = pstats.Stats("run1.stats")
>>> p.add("run2.stats", "run3.stats")
>>> p.sort_stats(SortKey.CUMULATIVE).print_stats(10)
24 function calls in 0.001 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
3 0.000 0.000 0.001 0.000 {built-in method builtins.exec}
3 0.000 0.000 0.001 0.000 <string>:1(<module>)
3 0.001 0.000 0.001 0.000 {built-in method builtins.sum}
...
Common Use Cases
The most common tasks for pstats include:
- Inspecting a saved
cProfileoutput file to find the slowest functions in a program. - Sorting profiling data by cumulative time to surface high-level bottlenecks.
- Filtering large reports with regular expressions to focus on a single subsystem.
- Tracing call relationships with
print_callers()andprint_callees(). - Aggregating results from repeated runs to smooth out noise in measurements.
- Browsing profile data interactively with
python -m pstats <file>.
Real-World Example
Profiling a recursive Fibonacci implementation with cProfile and analyzing the output with pstats highlights the cost of repeated calls:
>>> import cProfile, pstats
>>> from pstats import SortKey
>>> def fibonacci(n):
... if n <= 1:
... return n
... return fibonacci(n - 1) + fibonacci(n - 2)
...
>>> cProfile.run("fibonacci(20)", "/tmp/fib.stats")
>>> stats = pstats.Stats("/tmp/fib.stats")
>>> stats.strip_dirs().sort_stats(SortKey.CUMULATIVE).print_stats(5)
21894 function calls (4 primitive calls) in 0.005 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.005 0.005 {built-in method builtins.exec}
1 0.000 0.000 0.005 0.005 <string>:1(<module>)
21891/1 0.005 0.000 0.005 0.005 <stdin>:1(fibonacci)
The report makes the recursive blow-up obvious: a single call to fibonacci(20) triggers more than 21,000 nested invocations, which is the kind of insight pstats exists to surface.
Related Resources
Tutorial
Profiling in Python: How to Find Performance Bottlenecks
In this tutorial, you'll learn how to profile your Python programs using numerous tools available in the standard library, third-party libraries, as well as a powerful tool foreign to Python. Along the way, you'll learn what profiling is and cover a few related concepts.
For additional information on related topics, take a look at the following resources:
- Python 3.12 Preview: Support For the Linux perf Profiler (Tutorial)
- Speed Up Your Python Program With Concurrency (Tutorial)
- Caching in Python Using the LRU Cache Strategy (Tutorial)
- Profiling Performance in Python (Course)
- Speed Up Python With Concurrency (Course)
- Python Concurrency (Quiz)
- Caching in Python With lru_cache (Course)
By Leodanis Pozo Ramos • Updated May 19, 2026