Skip to content

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:

Language: Python
>>> 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 function
  • tottime: total time spent inside the function, excluding sub-calls
  • percall: time per call based on tottime
  • cumtime: cumulative time including everything the function called
  • percall: time per call based on cumtime
  • filename:lineno(function): location of the profiled code

Key Features

  • Loads profile data from one or more files written by cProfile or profile, or from a Profile instance 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:

Language: Python
>>> 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:

Language: Python
>>> 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:

Language: Python
>>> 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:

Language: Python
>>> 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 cProfile output 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() and print_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:

Language: Python
>>> 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.

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.

intermediate tools

For additional information on related topics, take a look at the following resources:


By Leodanis Pozo Ramos • Updated May 19, 2026