memory_profiler

Line-by-line and time-based memory profiling for Python code, with a CLI and decorator API for tracking down leaks.

Tool
PyPI
v0.61.0
4,574stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
43/100Fair
Development Activity0
Maintenance0
Community72
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
58/100Fair
Architecture62
Code Quality58
Innovation55
Learning Curve55

memory_profiler is a pure Python module for monitoring the memory consumption of a process, including line-by-line analysis of memory usage inside decorated functions. It wraps psutil to sample RSS memory over time and exposes both a @profile decorator for per-line breakdowns and a memory_usage() function for programmatic sampling of any process, Python callable, or code string.

Beyond the importable API, the package ships the mprof command-line tool for recording full memory-usage timelines of any executable — Python or not — and plotting them with matplotlib, including flame-graph views of nested function calls, trend-line slope detection for spotting leaks, and separate tracking of forked child processes in multiprocessing workloads.

What You Get

  • @profile decorator - annotate any function to get a line-by-line memory usage report when the script runs under python -m memory_profiler.
  • memory_usage() function - sample memory over time for the current process, an arbitrary PID, or a specific Python callable/args tuple.
  • mprof CLI - run, plot, list, clean, and remove recorded memory-usage timelines for any executable, not just Python scripts.
  • Child process tracking - --include-children sums memory across forked children, --multiprocess tracks each child individually in the same plot.
  • IPython/Jupyter magics - %memit and %mprun bring the same line-by-line and one-shot memory measurements into notebook cells.
  • pdb breakpoint integration - --pdb-mmem=X drops into the debugger automatically once a decorated function crosses a memory threshold.

Common Use Cases

  • Finding a memory leak - a developer notices RSS climbing over a long-running job and uses mprof run/mprof plot with the trend-slope option to confirm growth isn’t flattening out.
  • Profiling a specific function - decorating a suspect function with @profile and running under -m memory_profiler to see exactly which line allocates the most memory.
  • Comparing memory across multiprocessing workers - using mprof run --multiprocess to see whether one worker process is consuming disproportionate memory.
  • Debugging in a notebook - using the %memit/%mprun IPython magics to check the memory cost of a single expression without leaving Jupyter.

Under The Hood

Architecture memory_profiler.py is a single flat module (no package, no src layout) exposing top-level functions and classes: _get_memory/_get_child_memory sample RSS via psutil or resource/tracemalloc backends, MemTimer (a multiprocessing.Process subclass) polls memory on an interval in a separate process and streams samples back over a Pipe, LineProfiler/CodeMap implement line-level tracing to attribute memory deltas to source lines, and MemoryProfilerMagics wraps the same primitives as IPython cell/line magics. mprof.py is a separate top-level module implementing the mprof CLI as a flat set of *_action() functions dispatched from main(), which shells out to memory_profiler’s memory_usage() with streaming enabled to write .dat files, then reads them back for plot_action()/flame_plotter() (matplotlib) and peak_action(). There’s no dependency injection or plugin system — the two modules communicate through direct function calls and on-disk mprofile_*.dat files, so changing that on-disk format in one module would break the other.

Tech Stack Pure Python 3.7+, with a single hard runtime dependency, psutil, declared in setup.cfg. Several soft dependencies are guarded by try/except ImportError: IPython (for the notebook magics), the stdlib tracemalloc module (used as an alternative sampling backend), and matplotlib (only needed for mprof plot/--flame). Packaging uses classic setuptools (setup.py + setup.cfg, with a minimal pyproject.toml build-system block rather than a fully modern pyproject-only config) and exposes a single console-script entry point, mprof = mprof:main. There is no database or web framework involved — it distributes as two flat py_modules plus a CLI wrapper.

Code Quality 22 test files under test/ exercise the decorator, async functions, generators, multiprocessing, precision flags, unicode streams, the tracemalloc backend, and the mprof CLI itself, run via pytest across a Python version matrix in CI. The lint_python.yml workflow runs bandit, black, flake8, isort, codespell, and mypy, but most of these steps are advisory (|| true) rather than blocking, and the main modules carry no type annotations despite mypy being invoked. Naming is plain and consistent, error handling favors early returns and warnings over raised exceptions in a few spots (a missing backend falls back with a warning rather than failing). The README states the project is no longer actively maintained, which is consistent with the multi-year gap since the last commit and a sizeable backlog of open issues.

What Makes It Unique The line-by-line memory attribution technique — tracing execution and diffing RSS after each source line inside a decorated function — is memory_profiler’s defining contribution, and for years it was close to the reference implementation of that approach in the Python ecosystem. Pairing it with time-based mprof recording, including a flamegraph view correlating timestamps to named function calls and a trend-slope option for leak triage, gives it a broader feature set than a plain “watch RSS over time” tool. It isn’t conceptually novel by current standards — newer sampling profilers offer lower overhead and native-code visibility — but its API and terminology are still the ones most Python developers reach for first when asked to “profile memory line by line.”

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search