# Austin: sampling CPython frame stacks from outside the process

> A frame stack sampler for CPython written in C that attaches to a running process, reads the interpreter's virtual memory, and emits samples with no instrumentation and no code changes. The interesting tension is that the README still advertises memory profiling after the heap option was removed.

**P403n1x87/austin** — Python frame stack sampler for CPython

- Repository: https://github.com/P403n1x87/austin
- Website: https://pypi.org/project/austin-dist/
- Stars: 2,212 · Forks: 67
- Language: C
- License: GPL-3.0
- Published: 2026-10-08 · Updated: 2026-10-08 · Language: en
- Canonical page: https://hysenlabs.com/projects/p403n1x87-austin

## Reading the interpreter's memory instead of instrumenting it

Austin is a Python frame stack sampler for CPython written in pure C. The mechanism is stated plainly in the README: samples are collected by reading the CPython interpreter virtual memory space to retrieve information about the currently running threads along with the stack of the frames being executed.

That is the whole design in one sentence, and it explains the rest of the project's character. Nothing is injected into the target application. There is no import to add, no decorator to apply, no agent to deploy. The consequence the README draws from this is that Austin can be used to build statistical profilers with minimal impact on the target application and without requiring any instrumentation.

The key features list is five lines: zero instrumentation, minimal impact, fast and lightweight, time and memory profiling, and built-in support for multi-process applications such as `mod_wsgi`. The multi-process point deserves more attention than it gets. Sampler projects usually assume one process, one interpreter, one main thread. Austin names the case where a WSGI host forks workers and the interesting work happens in a child, which is exactly where a naive profiler attaches to the wrong thing.

The repository metadata agrees with the README on the language, recording C as the primary language, and the tree is consistent with an autotools project rather than a Python package: `configure.ac`, `Makefile.am`, `src/`, `test/`, a `Dockerfile`, and separate `README` and `README.md` files.

## One package name across five package managers

The distribution name is not the project name, and this trips people up. The tool is called Austin, and the PyPI package is `austin-dist`. The repository's recorded homepage is the PyPI page for `austin-dist`, so the two agree, but a search for the bare name finds a city in Texas and a good deal of unrelated material.

The README states that on all supported platforms and architectures Austin can be installed from PyPI with `pip` or `pipx`:

```bash
FROM  ubuntu:24.04
COPY  . /austin
RUN   apt-get update && \
      apt-get install -y autoconf build-essential libunwind-dev binutils-dev libiberty-dev zlib1g-dev && \
      cd /austin && \
      autoreconf --install && \
      ./configure && \
      make && \
      make install
```

## Austin emits samples, not profiles

Austin does not draw a flame graph. The README says the simplest way to turn it into a full-fledged profiler is to use it together with the VS Code extension, or combine it with FlameGraph or Speedscope. Its own binary output can be piped into other external or custom tools for further processing, and the README shows a third-party Python TUI built on that principle.

This division of labour is the main architectural decision in the project and it is a deliberate one. The sampler does one job, and it does it in C, where the sampling loop can run at a rate a Python-implemented profiler cannot reach. Everything about interpretation, aggregation and presentation belongs to a tool that is easier to change.

The output format is where that decision has teeth. Version 4.0.0, published on 2025-11-01, made the MOJO binary output format the default and dropped support for the augmented collapsed stack format entirely. If you have a wrapper script, a dashboard or a stored archive of samples written in the old format, that script is now reading a format the sampler will not produce.

The same release more than doubled the maximum attainable sampling rate, added support for the `exec` system call, fixed a bug where sampling would halt if Austin failed to retrieve valid thread information, and fixed a macOS bug that stopped Austin attaching to a process a second time on CPython 3.13. A sampler that silently stops sampling is the worst failure mode this tool has, so it is worth knowing the fix landed rather than assuming it is still open.

## Version 4 renamed flags and dropped features

The flag surface changed in v4.0.0 in ways that are easy to miss because the release notes bury them in a bullet list. The `--sleepless` and `-s` options were replaced by the `--cpu` and `-c` option. The exclude-empty option, removed back in v3.7.0, is also gone. The heap option was removed outright.

Two of those deserve to be spelled out for anyone evaluating the project now.

The `--cpu` rename matters if you script Austin. A command written for an earlier version will not fail loudly in every case, and the difference between asking the sampler to ignore sleeping time and asking it to attribute CPU time is a change in what your numbers mean, not just what they are called.

The heap removal is the contradiction in this repository, and it is worth putting both facts in front of you rather than picking one. The README's key features list still advertises time and memory profiling as of the version on the default branch. The v4.0.0 release notes say `Removed the heap option`. Both are current. A reader who trusts the README will look for memory numbers that the current binary will not produce. The practical rule is that the README describes the project's design lineage and the release notes describe the current binary, and when they disagree about a feature, the release notes win.

Support boundaries moved in the same release: CPython 3.14 was added and CPython 3.8 was dropped. Version 3.6.0 had already dropped CPython 2 and 3.3 through 3.7, so the supported range narrows steadily. Version 3.7.0 added CPython 3.13 and improved support for Python processes running in containers; version 3.6.0 added CPython 3.12 and support for sub-interpreters.

## What the sampler can and cannot tell you

A statistical sampler answers different questions from an instrumenting profiler, and the difference is not a matter of degree. Austin reports which frames appeared in a stack across many samples. It does not count every function call, so a function called frequently but briefly can be invisible next to one called rarely and slowly. The README's own framing, minimal impact on the target application and no instrumentation required, is the same property seen from the other side.

Attaching to a running process is the other half. Austin can be pointed at a live interpreter, which makes it useful for environments where restarting into a profiler is not an option. The releases show that this is not a casual feature: v3.7.0 specifically improved support for processes running in containers, and v4.0.0 fixed a macOS re-attach bug with CPython 3.13. Container and platform cases are where samplers of this kind tend to break, and the project keeps fixing them.

There is also a license consideration worth stating without overstating. Austin is released under the GPL-3.0, with `COPYING` and `LICENSE.md` both present in the tree and a GPLv3 badge in the README. For a command line tool invoked as a separate process that is usually straightforward, but if you plan to link the sampler into a proprietary product rather than run it, the copyleft terms are the thing to examine before anything else.

## Where austin fits next to cProfile and py-spy

The comparison the README invites is with other profilers rather than with one named competitor, and it points to a survey of open source Python profilers for the wider landscape. Against `cProfile` and `profile` from the standard library, the distinction is exact rather than a matter of taste. Those tools are deterministic, they count every call, and they require the code to be running under the profiler's control. Austin is statistical, attaches externally, and needs no code change. If you need an exact call count for a small script, the standard library answers that question and Austin does not.

Against a sampling profiler written in Python, the distinction is about where the sampling loop lives and how fast it can run. Austin's answer, C with a stack unwinder, buys a higher attainable sampling rate at the cost of a build step and a GPL license. The v4.0.0 doubling of the maximum sampling rate is the concrete version of that trade.

Against flame graph tooling in general, Austin is not competing at all. Speedscope, FlameGraph and the VS Code extension are named as the layers that turn samples into something readable.

The maintenance picture supports a reasonable adoption decision. The repository is not archived, the last push was on 2026-09-28, and the release cadence is roughly annual for major versions with patch releases in between. The README asks for sponsorship rather than corporate backing, which is a fair signal about the project's funding model but also a fair signal about who carries the maintenance load for a tool that depends on CPython internals changing between releases.

## Conclusion

Austin is the right tool when you have a production Python process you cannot restart with a profiler attached, and the wrong tool when you need to attribute time to a specific line on demand, because a statistical sampler answers with distributions rather than exact answers. The README lists memory profiling as a headline feature while release v4.0.0 says the heap option was removed, so treat the README as describing an earlier design and the release notes as the current one. Start with `pipx install austin-dist` and pipe the output into Speedscope or FlameGraph, then read the sampling options rather than assuming the flags from a blog post still exist, since `--sleepless` was replaced by `--cpu` in the same release.

## FAQ

### How do I install the Austin Python profiler?

Install the `austin-dist` package, which is the distribution name for the Austin profiler. The README documents `pip install austin-dist` and `pipx install austin-dist`, plus Chocolatey and Scoop on Windows, Homebrew on macOS, apt and Snap on Linux, and Conda Forge for Anaconda users.

### Does Austin need any changes to the code it profiles?

No. Austin collects samples by reading the CPython interpreter virtual memory space from outside the process, and the README lists zero instrumentation as a key feature. That is the point of the tool: it can attach to a process without importing anything into it.

### Can Austin profile memory as well as CPU time?

The README lists time and memory profiling among the key features, but the v4.0.0 release notes say the heap option was removed. Treat the release notes as describing the current binary, and check the sampling options in the version you actually install before relying on memory figures.

### What changed in Austin v4.0.0?

Version 4.0.0 added CPython 3.14 support and dropped CPython 3.8, made the MOJO binary output format the default while removing the augmented collapsed stack format, replaced `--sleepless` and `-s` with `--cpu` and `-c`, removed the heap option, more than doubled the maximum sampling rate, and added support for the `exec` system call.

### How does Austin compare with cProfile?

They answer different questions. `cProfile` counts every function call deterministically and needs the code to run under its control, while Austin samples the stack statistically from outside the process with no instrumentation. For exact call counts on a small script, the standard library tool is the better fit.

### What license is Austin released under?

Austin is distributed under the GPL-3.0, with `COPYING` and `LICENSE.md` both present in the repository and a GPLv3 badge in the README. Running it as a separate command line process and linking it into a product are different situations under those terms.

## Sources

- [License: GPL-3.0](https://github.com/P403n1x87/austin/blob/master/LICENSE)
- [P403n1x87/austin on GitHub](https://github.com/P403n1x87/austin)
- [Project website](https://pypi.org/project/austin-dist/)
- [README](https://github.com/P403n1x87/austin/blob/master/README.md)
- [Releases](https://github.com/P403n1x87/austin/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/p403n1x87-austin
