Library / SDK
astrofrog/psrecord avatar
astrofrog/psrecord

psrecord turns a process's CPU and memory use into a chart

Record the CPU and memory activity of a process :chart_with_upwards_trend:

682 stars79 forksPythonBSD-2-Clause

At a glance

What is it?
psrecord is a small Python utility that uses psutil to record the CPU and memory activity of a running process, either one you already have or one it starts for you, and it can write the samples to a file, plot them with matplotlib, or do both. The plotting dependency is optional, which keeps the core install tiny for a tool that runs inside a profiling loop.
Who is it for?
Adopt psrecord if you need a quick before and after picture of what a process actually costs in CPU and memory, since it is a one-command measurement with a file output and a chart. Skip it if you need continuous monitoring over long periods, since the tool is for a bounded recording, and if you cannot install psutil, since that is a hard dependency rather than an optional one.
Can I use it commercially?
Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 17 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What it actually measures

psrecord is a small utility that uses the psutil library to record the CPU and memory activity of a process.

The scope is narrow, and that is the appeal. It is not a profiler, it does not tell you where the time went inside the program, and it does not sample stacks or attributes. What it does is sample a process's CPU and memory over time and hand you the series.

The requirement list explains where the numbers come from. Python 2.7 or 3.3 and higher, psutil 1.0 or later, and matplotlib as optional, used for plotting. The current packaging narrows the Python range, with the project metadata requiring Python 3.10 or newer, so the requirements text in the documentation is older than the declared support.

The dependency is the psutil library, which is the sensible choice because psutil already handles the platform differences for reading process information, so the work left in psrecord is the sampling loop and the output.

The project is Python, BSD-2-Clause licensed, and the author is Thomas Robitaille. The package is still under development and is therefore experimental, which is the phrase used in the documentation and it matches the Development Status 3 - Alpha classifier in the package metadata. The last push was on 2026-10-06 and the recent tags are v1.4 and v1.3, both from April 2024.

The coverage badge at the top points at Codecov, and the repository carries a tox.ini and a pre-commit config, so the testing and linting setup is present even though the tool itself is small.

Installing, and the extra that decides what you can do

Installation is a single pip line:

bash
pip install psrecord

And if you want the plotting, there is an extra:

bash
pip install psrecord[plot]

The optional dependency structure is worth understanding because it shapes how you would deploy the tool. The core install pulls in only psutil, and matplotlib comes with the plot extra. That matters in practice for a utility like this, since you will often run it inside a container, on a build machine or in a CI image where adding a plotting stack you do not need is pure weight.

The extras are declared in the package metadata as optional-dependencies, with a test extra that pulls pytest at 7.0 or newer and a plot extra that pulls matplotlib.

The console script is registered in the project metadata as psrecord, mapped to psrecord.main:main, so the command name on your path is the package name. The version is dynamic, taken from setuptools_scm with a version_file of psrecord/_version.py, which means the version in the metadata is derived from the git tags rather than written by hand. The build system requires setuptools 64 or newer along with setuptools_scm 8 or newer.

There is a CHANGES.md at the root and the documentation is a README.rst, which is the older reStructuredText format and the reason the project file lists readme = "README.rst".

Two ways to use it, and they are not equivalent

The usage documentation opens with the basics, and the two modes are worth comparing before you pick one.

The first records an existing process. The example is:

bash
psrecord 1330 --log activity.txt

where 1330 is an example of a process ID which you can find with ps or top. The documentation notes you should use sudo for a root process, which is the permission model talking: reading another user's process is restricted on Unix, so the tool needs the rights to do it.

The second mode starts the process itself, by specifying the command in quotes:

bash
psrecord "hyperion model.rtin model.rtout" --log activity.txt

The difference is not cosmetic. Attaching to a running process measures a process that was already doing whatever it does, which may include a warm-up period, a cache being filled or a steady state reached before you started looking. Launching the process under psrecord means the very first allocations are included, and the run is reproducible from the command line.

For a performance question of the form why is this so slow, the second mode is usually the right one, because the sample then covers the whole lifetime of the run rather than an arbitrary slice of it. For a question about whether a long-running service is drifting, the first mode is what you want.

The second mode also implies a lifecycle question. psrecord has to know when to stop sampling, and the answer is that the recording ends when the process it launched ends.

The output options, and how to control the shape of the recording

Three flags control what you get, and they compose.

The log file and the plot are separate options. `--log activity.txt` writes the activity to a file and `--plot plot.png` produces a chart. The documentation shows the combination, recording to a file and making a plot at the same time:

bash
psrecord 1330 --log activity.txt --plot plot.png

The chart example in the documentation is the screenshot.png file at the repository root, and the documentation links to it directly.

The duration controls how long the recording runs. By default the monitoring continues until the process is stopped, and you can specify a maximum duration in seconds:

bash
psrecord 1330 --log activity.txt --duration 10

That default is the one to be careful about. If you attach to a process that never exits, the recording never ends either, so a forgotten run leaves a file growing and a process polling. Setting a duration when you are measuring a bounded workload is cheap insurance.

The interval controls the sampling rate. The process is polled as often as possible by default, and it is possible to set the time between samples in seconds:

bash
psrecord 1330 --log activity.txt --interval 2

Polling as fast as possible is the right default for a short burst, since you want the resolution, and it is the wrong default for a long run, where the sampling overhead and the size of the output both grow with the number of samples.

Including subprocesses changes what the number means

There is one option that changes the interpretation of the result rather than just its resolution, and it is easy to miss.

To include sub-processes in the CPU and memory stats, use:

bash
psrecord 1330 --log activity.txt --include-children

The default is to measure only the named process. That is the right choice for a single-purpose program, but it is wrong for anything that forks workers, and a lot of real software does exactly that. A web server with a worker pool, a build tool, a language runtime with a garbage collector thread, and a job queue that spawns workers are all cases where the parent's CPU and memory are a fraction of the real cost.

So the flag is not a detail about how the tool works, it is a question about which number you are trying to answer. If you are comparing two versions of the same program, use the same setting both times, and if the program spawns children, use the flag.

There is a related subtlety in how the CPU figure is read. A process that spawns children and waits is, from the parent's point of view, idle while the work happens, which is exactly the kind of thing that makes a naive measurement look better than reality.

Running the tests and reporting problems

The test instructions are short and are the last part of the documentation.

To run tests you need pytest, which you can install with:

bash
pip install pytest

And then run the tests with:

bash
pytest psrecord

The argument is the package directory rather than the repository root, which is a small detail worth copying exactly, since a bare pytest would collect from wherever it happens to be invoked.

The repository setup supports that. There is a tox.ini for running the suite across environments, a pre-commit config for the hooks, and the test extra in the package metadata so pytest is declared rather than assumed.

For problems, the documentation points at the issue tracker in the repository. For a utility this small, that is usually the fastest route, and there is a good chance the answer is a one-line fix that arrives as a pull request.

The one thing worth noting about the overall shape of this project is that it has not moved much since April 2024, when v1.3 and v1.4 were tagged, while the packaging has been kept current. The classifiers now list Python 3.10 through 3.14 and the requires-python has moved to 3.10 or newer, and the ruff configuration selects the F, E, W, I and UP rule sets with a line length of 100, matched by black at the same line length. So the code has been modernised to run on current Python without the feature set having changed, which is a sensible way to maintain a tool that works.

For a utility whose job is to answer a question about one process on one machine, that is enough. It does one thing, it does it with a well-tested dependency, and it produces two kinds of output you can look at.

Editorial conclusion

Adopt psrecord if you need a quick before and after picture of what a process actually costs in CPU and memory, since it is a one-command measurement with a file output and a chart. Skip it if you need continuous monitoring over long periods, since the tool is for a bounded recording, and if you cannot install psutil, since that is a hard dependency rather than an optional one. Verify first that you can run psrecord against the process, which needs the right permissions for a process owned by another user, that you know whether you want children included in the numbers, and that you install the plot extra if you want a chart rather than just a log file.

Frequently asked questions

How do I record the CPU and memory usage of a process with psrecord?

Run `psrecord 1330 --log activity.txt` with the process ID, which you can find with ps or top, and use sudo for a root process. You can also start the process yourself by quoting the command, for example `psrecord "hyperion model.rtin model.rtout" --log activity.txt`, which measures from the start of the run rather than attaching to something already running.

How do I make psrecord produce a chart?

Install it with the plot extra using `pip install psrecord[plot]`, which pulls in matplotlib, and pass the `--plot plot.png` option. The log file and the plot options can be combined, for example `psrecord 1330 --log activity.txt --plot plot.png`, and the documentation shows a sample chart in the screenshot.png file at the repository root.

How do I control how long psrecord runs and how often it samples?

The duration option sets a maximum recording time in seconds, as in `psrecord 1330 --log activity.txt --duration 10`, since by default the monitoring continues until the process stops. The interval option sets the time between samples in seconds, as in `psrecord 1330 --log activity.txt --interval 2`, since by default the process is polled as often as possible.

Official sources

  1. astrofrog/psrecord on GitHub
  2. Issues
  3. License: BSD-2-Clause
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/astrofrog-psrecord.svg)](https://hysenlabs.com/projects/astrofrog-psrecord)

Was this useful?