Flameshow: a flamegraph you can explore in the terminal
A terminal Flamegraph viewer.
At a glance
- What is it?
- Flameshow is a Python terminal viewer for flamegraphs, with zoom, percentages, keyboard and mouse control, and support for pprof, Brendan Gregg's format, Austin, Speedscope and Google Trace. The judgement is that the terminal-native choice is a real advantage over a browser for a profiling tool, and that the format coverage and the split-out renderer package are what make it extensible.
- Who is it for?
- Flameshow fits a Go or Python developer who profiles a service over SSH, or who works somewhere a browser-based profiler is awkward, and who wants to zoom into a profile without leaving the terminal. It does not fit a team that needs a shared or persistent profiling session, since a terminal UI is single-user by construction, and it does not fit a workflow built on a format the project does not yet parse.
- Can I use it commercially?
- Yes. MIT 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 22 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 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A flamegraph that lives in your terminal
Flameshow is a terminal flamegraph viewer, and it is written in pure Python.
The feature list is short. It renders flamegraphs in your terminal. It supports zooming in and displaying percentages. Keyboard input is prioritised, and all operations can also be performed with the mouse. It can switch to different sample types.
That list is a good description of the project. A flamegraph is a two-dimensional visualisation, and rendering it in a terminal means dealing with cell widths, colour, and a viewport that can be smaller than the graph. The mouse support is the detail that stands out, because most terminal profilers are keyboard-only, and the documentation says hovering over a span shows its details and clicking zooms it.
The interesting architectural decision is that the renderer is not part of this project. Flameshow is built on `flamegraph-textual`, and the renderer is available as a separate package:
pip install flamegraph-textualSo there are two packages. The renderer takes profile data and draws a flamegraph, and Flameshow is the application around it: argument parsing, file loading, format detection, and the interactive shell. That split means the rendering work can be used by other tools, and it means the dependency versions of the two have to line up.
The project is built on Textual, the Python TUI framework, and the README says so directly at the end. The `textual` dependency at `^0.37.1` and the `flamegraph-textual` dependency at `^0.1.0` are the two that matter for the rendering stack, and the `textual` version in particular is a fast-moving one.
Installing it three ways, and the pprof workflow
The install section offers pip and Nix, and the development section adds a third path for contributors.
Because Flameshow is pure Python, pip is the straightforward route:
pip install flameshowNix is the alternative, and it can either run without installing or install imperatively:
nix run github:laixintao/flameshow
# Or if you want to install it imperatively:
nix profile install github:laixintao/flameshowThe `nix run` form is the one worth noting for a profiling tool, because it means you can run the viewer against a profile on a machine where you do not want to install a Python environment, and the same is true of the pipx-style isolation that `nix profile` gives you.
The usage example is the Go goroutine dump, and it is two commands:
$ curl http://localhost:9100/debug/pprof/goroutine -o goroutine.out
$ flameshow goroutine.outThe first is the standard Go pprof HTTP endpoint, which is served by a Go program with the net/http/pprof import. The second hands the file to the viewer. The important property is that the profile is a file, so the viewing step is entirely decoupled from the machine that produced it, and you can copy a `goroutine.out` from a production host to your laptop and explore it there.
The console script is registered in `pyproject.toml` as `flameshow = 'flameshow.main:main'`, so the command name matches the package name.
For development, the README points at the standard poetry flow:
git clone [email protected]:laixintao/flameshow.git
cd flameshow
pip install poetry
poetry installThe repository also has a `flake.nix` and a `flake.lock` at the root, so the Nix path is defined in the repository rather than being a packaging convention, and `poetry.lock` pins the Python dependency tree.
The TUI keys, and what a mouse can do
The available actions are listed on the footer of the interface once you are in, which is a sensible design for a full-screen TUI where a permanent help panel would cost space.
The keys are `q` for quit, `h` `j` `k` `l` or the arrow keys for moving around, `Enter` to zoom in and `Esc` to zoom out. You can also use a mouse: hovering over a span shows its details, and clicking zooms it.
The `h` `j` `k` `l` set is the vim movement convention, which fits a project whose README says keyboard input is prioritised, and it pairs with the `+`/`-` style zoom in and out of most terminal graph viewers. The important thing is that zooming is a stack operation rather than a reset, so you can descend into a stack frame and come back out to where you were, which is how you actually read a flamegraph.
The `Enter` to zoom in and `Esc` to zoom out pair, and clicking a span to zoom it is the mouse equivalent of the same action, so the two input methods are not competing features but the same feature with a second binding.
The `sample type` switching mentioned in the feature list is the other interaction that matters. A profile file can contain several kinds of samples, and a flamegraph of the wrong kind is a misleading picture. Being able to switch within the same view, rather than regenerating and reloading, keeps the comparison in one place.
The interface is built on Textual, which is why the project lists `Environment :: Console :: Curses` among its classifiers along with `Environment :: Console`. The rendering itself happens in the `flamegraph-textual` package.
Five profile formats, and an honest admission about the rest
The supported formats section starts with a statement of fact that shapes the whole design: as far as the author knows, there is no standard specification for profiles, and different languages or tools might generate varying profile formats.
What is supported is a list of five. Golang pprof. Brendan Gregg's Flamegraph format. Python Austin. Speedscope, in both evented and sampled variants. And the Google Trace Event format.
The author's comment on the rest is unusually candid. They say they are actively working on supporting more formats, and admit they might not be familiar with every tool and its specific format, and invite you to reach out and submit an issue if you would like Flameshow to integrate with a tool you love.
This is the real constraint of the project, and it is worth understanding before you adopt it. A flamegraph viewer is a format-specific tool, not a universal one. If your profiler emits something not on that list, Flameshow cannot show it, and the workaround is to convert the profile into one of the supported formats first.
The five formats cover a lot of ground in practice. pprof covers Go and anything else using the pprof ecosystem, and the protobuf dependency at `^4.25` in the project metadata is what the pprof parser needs. Brendan Gregg's format is the original folded-stacks text format that most other flamegraph tools also read, so it is the widest interoperability format in the list. Austin covers Python. Speedscope covers a range of JavaScript profilers. The Google Trace Event format covers Chrome's tracing output.
`iteround` at `^1.0.4` is in the dependency list.
The licence metadata and the repository licence do not agree
There is a discrepancy here that anyone shipping this inside a product needs to resolve.
The repository's licence field reports MIT, and there is a `LICENSE` file at the repository root. The `pyproject.toml` metadata says something different: `license = "GPLv3"`. The README itself carries no licence statement at all, and the badge row in the README covers tests, codecov, PyPI version, Python versions, PyPI downloads and the black code style, but not the licence.
So the two licence declarations do not agree with each other.
The practical point is that GPLv3 is not a permissive licence, and if the metadata is right, embedding Flameshow in a closed-source product carries copyleft obligations. That is a licensing observation rather than legal advice, and the `LICENSE` file at the repository root is the text that decides the question. Reading it before you depend on the package is a five-minute task with a large potential consequence.
The rest of the packaging is conventional. The build backend is `poetry-core`, the Python requirement is `^3.10` with classifiers for 3.10, 3.11 and 3.12, and the project is marked as `Typing:: Typed`. The classifiers list Windows 10, Windows 11, MacOS and POSIX Linux as supported operating systems. Formatting is black with a line length of 79, and the dev dependencies are pytest with pytest-asyncio, pytest-cov, flake8 and ipdb. There is a `.flake8` file at the root and a `.bumpversion.cfg` for the version bumps.
Editorial conclusion
Flameshow fits a Go or Python developer who profiles a service over SSH, or who works somewhere a browser-based profiler is awkward, and who wants to zoom into a profile without leaving the terminal. It does not fit a team that needs a shared or persistent profiling session, since a terminal UI is single-user by construction, and it does not fit a workflow built on a format the project does not yet parse. Verify first that the profile format your tool emits is on the supported list, since the documentation is explicit that there is no standard profile specification and that support is added format by format, that the `flamegraph-textual` version you install is compatible with the `textual` version, and that the licence terms are what you expect, because the project metadata declares GPLv3 while the repository licence field reports MIT.
Frequently asked questions
How do I install Flameshow?
It is pure Python, so `pip install flameshow` is enough. You can also run it through Nix with `nix run github:laixintao/flameshow`, or install it with `nix profile install github:laixintao/flameshow`. The development setup uses poetry, with `pip install poetry` followed by `poetry install` after cloning the repository.
How do I view a Go pprof profile with Flameshow?
Fetch the profile with `curl http://localhost:9100/debug/pprof/goroutine -o goroutine.out` and then run `flameshow goroutine.out`. Because the profile is a file, you can also copy it from another machine and open it locally.
Which profile formats does Flameshow support?
Golang pprof, Brendan Gregg's Flamegraph format, Python Austin, Speedscope in both evented and sampled variants, and the Google Trace Event format. The documentation notes there is no standard profile specification and that support is being added format by format, and invites issues for tools you would like it to handle.
What are the keyboard shortcuts in the Flameshow TUI?
Press `q` to quit, `h` `j` `k` `l` or the arrow keys to move around, `Enter` to zoom in and `Esc` to zoom out. A mouse works too: hovering over a span shows its details and clicking zooms it.
Is the flamegraph renderer a separate package from Flameshow?
Yes. The renderer lives in `flamegraph-textual`, which is installed with `pip install flamegraph-textual` and is declared as a `^0.1.0` dependency of Flameshow. Flameshow is the application around it, built on the Textual TUI framework.
Official sources
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.
[](https://hysenlabs.com/projects/laixintao-flameshow)Was this useful?