Technical Documentation: ClementTsang/bottom
ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference
Overview (`README.md`)
Table of contents
Features
As (yet another) process/system visualization and management application, bottom supports the typical features:
Graphical visualization widgets for:
- CPU usage over time, at an average and per-core level
- RAM and swap usage over time
- Network I/O usage over time
- Temperature over time
- Disk I/O usage over time
with support for zooming in/out the current time interval displayed.
Widgets for displaying info about:
A process widget for displaying, sorting, and searching info about processes, as well as support for:
Cross-platform support for Linux, macOS, and Windows, with more planned in the future.
Customizable behaviour that can be controlled with command-line options or a config file, such as:
- Custom and built-in colour themes
- Customizing widget behaviour
- Changing the layout of widgets
- Filtering out entries in some widgets
And more:
You can find more details in the documentation.
Support
Official
bottom officially supports the following operating systems and corresponding architectures:
- macOS (
x86_64,aarch64) - Linux (
x86_64,i686,aarch64) - Windows (
x86_64,i686)
These platforms are tested to work for the most part and issues on these platforms will be fixed if possible.
Furthermore, binaries are built and tested using the most recent version of stable Rust at the time.
For more details on supported platforms and known problems, check out the documentation.
Unofficial
bottom may work on a number of platforms that aren't officially supported. Note that unsupported platforms:
- Might not be tested in CI to build or pass tests (see here for checked platforms).
- Might not be properly tested by maintainers prior to a stable release.
- May only receive limited support, such as missing features or bugs that may not be fixed.
Note that some unsupported platforms may eventually be officially supported (e.g., FreeBSD).
A non-comprehensive list of some currently unofficially-supported platforms that may compile/work include:
- FreeBSD (
x86_64) - Linux (
armv6,armv7,powerpc64le,riscv64gc,loongarch64) - Android (
arm64) - Windows (
arm64) - NetBSD (
x86_64)
For more details on unsupported platforms and known problems, check out the documentation.
Installation
Cargo
Installation via cargo can be done by installing the bottom crate:
# You might need to update the stable version of Rust first.
# Other versions might work, but this is not guaranteed.
rustup update stable
# Install the binary from crates.io.
cargo install bottom --locked
# If you use another channel by default, you can specify
# the what channel to use like so:
cargo +stable install bottom --locked
# --locked may be omitted if you wish to not use the
# locked crate versions in Cargo.lock. However, be
# aware that this may cause problems with dependencies.
cargo install bottomAlternatively, you can use cargo install using the repo as the source.
# You might need to update the stable version of Rust first.
# Other versions might work, but this is not guaranteed.
rustup update stable
# Option 1 - Download an archive from releases and install
curl -LO https://github.com/ClementTsang/bottom/archive/0.14.9.tar.gz
tar -xzvf 0.14.9.tar.gz
cargo install --path . --locked
# Option 2 - Manually clone the repo and install
git clone https://github.com/ClementTsang/bottom
cd bottom
cargo install --path . --locked
# Option 3 - Install using cargo with the repo as the source
cargo install --git https://github.com/ClementTsang/bottom --locked
# You can also pass in the target-cpu=native flag to try to
# use better CPU-specific optimizations. For example:
RUSTFLAGS="-C target-cpu=native" cargo install --path . --lockedAlpine
bottom is available as a package for Alpine Linux via apk:
apk add bottomPackages for documentation (bottom-doc) and completions for Bash (bottom-bash-completion), Fish (bottom-fish-completion), and Zsh (bottom-zsh-completion) are also available.
Arch Linux
bottom is available as an official package that can be installed with pacman:
sudo pacman -S bottomIf you want the latest changes that are not yet stable, you can also install bottom-git from the AUR:
# Using paru
paru -S bottom-git
# Using yay
yay -S bottom-gitDebian / Ubuntu
A .deb file is provided on each stable release and
nightly builds for x86, aarch64, and armv7.
Some examples of installing it this way:
# x86-64
curl -LO https://github.com/ClementTsang/bottom/releases/download/0.14.9/bottom_0.14.9-1_amd64.deb
sudo dpkg -i bottom_0.14.9-1_amd64.deb
# ARM64
curl -LO https://github.com/ClementTsang/bottom/releases/download/0.14.9/bottom_0.14.9-1_arm64.deb
sudo dpkg -i bottom_0.14.9-1_arm64.deb
# ARM
curl -LO https://github.com/ClementTsang/bottom/releases/download/0.14.9/bottom_0.14.9-1_armhf.deb
sudo dpkg -i bottom_0.14.9-1_armhf.deb
# musl-based
curl -LO https://github.com/ClementTsang/bottom/releases/download/0.14.9/bottom-musl_0.14.9-1_amd64.deb
sudo dpkg -i bottom-musl_0.14.9-1_amd64.debExherbo Linux
bottom is available as a rust package that can be installed with cave:
cave resolve -x repository/rust
cave resolve -x bottomFedora / CentOS / AlmaLinux / Rocky Linux
COPR
[!WARNING]
atim/bottomseems to be unmaintained and may be outdated (relevant issue)
bottom is available on COPR:
sudo dnf copr enable atim/bottom -y
sudo dnf install bottomTerra
bottom is also available via Terra:
sudo dnf install --repofrompath 'terra,https://repos.fyralabs.com/terra$releasever' --setopt='terra.gpgkey=https://repos.fyralabs.com/terra$releasever/key.asc' terra-release
sudo dnf install bottomRPM
.rpm files are also generated for x86 in the releases page.
For example:
curl -LO https://github.com/ClementTsang/bottom/releases/download/0.14.9/bottom-0.14.9-1.x86_64.rpm
sudo dnf install ./bottom-0.14.9-1.x86_64.rpmGentoo
Available in the official Gentoo repo:
sudo emerge --ask sys-process/bottomNix
Available in Nixpkgs as bottom:
nix profile install nixpkgs#bottombottom can also be installed and configured through the home-manager module:
{
programs.bottom.enable = true;
}openSUSE
Available in openSUSE Tumbleweed:
zypper in bottomSnap
bottom is available as a snap:
sudo snap install bottom
# To allow the program to run as intended
sudo snap connect bottom:mount-observe
sudo snap connect bottom:hardware-observe
sudo snap connect bottom:system-observe
sudo snap connect bottom:process-controlSolus
Available in the Solus repos:
sudo eopkg it bottomVoid
Available in the void-packages repo:
sudo xbps-install bottomHomebrew
The formula is available here:
brew install bottomMacPorts
Available here:
sudo port selfupdate
sudo port install bottomChocolatey
Chocolatey packages are located here:
choco install bottomScoop
Available in the Main bucket:
scoop install bottomwinget
The winget package can be found here:
winget install bottom
# If you need a more specific app id:
winget install Clement.bottomYou can uninstall via Control Panel, Options, or winget --uninstall bottom.
Windows installer (MSI)
You can manually install bottom as a Windows program by downloading and using the .msi file from the latest release.
Conda
You can install bottom using conda with this conda-smithy repository:
# Add the channel
conda config --add channels conda-forge
conda config --set channel_priority strict
# Install
conda install bottomgah
bottom can also be installed on Linux or macOS using gah:
gah install bottomghr
bottom can be installed using ghr like so:
ghr install clementtsang/bottommise
bottom is available via mise:
mise use -g bottom@latestPre-built binaries
You can also use the pre-built release binaries:
To use, download and extract the binary that matches your system. You can then run by doing:
./btmor by installing to your system following the procedures for installing binaries to your system.
Auto-completion
The release binaries in the releases page are packaged with
shell auto-completion files for Bash, Zsh, fish, Powershell, Elvish, Fig, and Nushell. To install them:
- For Bash, move
btm.bashto$XDG_CONFIG_HOME/bash_completion or /etc/bash_completion.d/. - For Zsh, move
_btmto one of your$fpathdirectories. - For fish, move
btm.fishto$HOME/.config/fish/completions/. - For PowerShell, add
_btm.ps1to your PowerShell profile. - For Elvish, the completion file is
btm.elv. - For Fig, the completion file is
btm.ts. - For Nushell, use
btm.nu.
The individual auto-completion files are also included in the stable/nightly releases as completion.tar.gz if needed.
Usage
You can run bottom using btm.
- For help on flags, use
btm -hfor a quick overview orbtm --helpfor more details. - For info on key and mouse bindings, press
?inside bottom or refer to the documentation page.
You can find more information on usage in the documentation.
Configuration
bottom accepts a number of command-line arguments to change the behaviour of the application as desired.
Additionally, bottom will automatically generate a configuration file on the first launch, which can be changed.
More details on configuration can be found in the documentation.
Troubleshooting
If some things aren't working, give the troubleshooting page
a look. If things still aren't working, then consider asking a question
or filing a bug report if you think it's a bug.
Documentation
The main documentation page can be found at https://bottom.pages.dev, using Cloudflare Pages. If needed, a mirror hosted using
Github Pages is also available at https://clementtsang.github.io/bottom.
Contribution
Whether it's reporting bugs, suggesting features, maintaining packages, or submitting a PR, contribution is always welcome! Please read
CONTRIBUTING.md for details on how to contribute to bottom.
Contributors
Thanks to all contributors:
Thanks
This application was written with many,
many libraries, as well as many services and
programs, all built on top of the work of many talented people. bottom would not exist without all of this.And of course, thank you again to all contributors and package maintainers!
I also really appreciate anyone who has used bottom, and those
who go out of their way to report bugs or suggest ways to improve things. I hope
it's been a useful tool for others.To those who support my work financially via donations, thank you so much.
Thanks to JetBrains for providing access to tools that I use to develop bottom
as part of their open source support program.Also thanks to SignPath.io for providing a free code signing service, and to the
SignPath Foundation for the certificate.
Overview (`docs/README.md`)
Extended Documentation
This is where the extended documentation resides, hosted on GitHub Pages. We use MkDocs,
Material for MkDocs, and mike.
Documentation is currently built using Python 3.11, though it should work fine with older versions.
Running locally
One way is to just run serve.sh. Alternatively, the manual steps are, assuming your current working directory
is the bottom repo:
# Change directories to the documentation.
cd docs/
# Create and activate venv.
python -m venv venv
source venv/bin/activate
# Install requirements
pip install -r requirements.txt
# Run mkdocs
venv/bin/mkdocs serveDeploying
Deploying is done via mike in order to get versioning. Typically,
this is done through CI, but can be done manually if needed.
Nightly docs
cd docs
mike deploy nightly --pushStable docs
cd docs
# Rename the previous stable version
mike retitle --push stable $OLD_STABLE_VERSION
# Set the newest version as the most recent stable version
mike deploy --push --update-aliases $RELEASE_VERSION stable
# Append a "(stable)" string to the end.
mike retitle --push $RELEASE_VERSION "$RELEASE_VERSION (stable)"Overview (`schema/README.md`)
Config JSON Schema
Generation
These are automatically generated from the code using schemars. The schemars
derives are locked behind the generate_schema feature flag to avoid building unnecessary code for normal builds.
Meanwhile, the generator itself lives in a separate scripts/schema_gen helper crate. You can
generate them like so:
# Will print out to stdout
cargo run --manifest-path scripts/schema_gen/Cargo.toml
# e.g. for nightly
cargo run --manifest-path scripts/schema_gen/Cargo.toml > schema/nightly/bottom.json
# e.g. for a specific version
cargo run --manifest-path scripts/schema_gen/Cargo.toml -- 0.12.0 > schema/v0.12.0/bottom.jsonAlternatively, run the scripts/schema/generate.sh script (for stable releases) or scripts/schema/nightly.sh
(for nightly), which does all of this for you.
Publication
To publish these schemas:
Stable
- Run
scripts/schema/generate.sh <YOUR_VERSION>. - Make a PR and merge it.
- Then, make a PR to schemastore to update the catalog.
Here's an example of a PR.
Nightly
- Run
scripts/schema/nightly.sh. - Make a PR and merge it.
Overview (`scripts/hooks/README.md`)
Git Hooks
Optional pre-push git hook. These are checked again in CI anyway, but may make it easier to check for issues upfront pre-push.
Overview (`scripts/schema_gen/README.md`)
schema_gen
This is just a tool to automatically generate JSON Schema for bottom's config.
Content Index (`docs/content/index.md`)
hide:
- navigation
- toc
title: Home
`bottom`
A customizable cross-platform graphical process/system monitor for the terminal, supporting Linux, macOS, and Windows. Inspired by other tools like gtop, gotop, and htop.
This site serves as extended documentation for bottom alongside the README.md.
!!! Warning
Some areas of this site are still in progress and may be missing details. Feel free to suggest/contribute changes!Installation
!!! Tip
It's as good idea to first check out the [Support](support/official.md) page to see if your system is officially supported!!!! Tip
If you're facing some issues during/after installation, check out the [Troubleshooting](troubleshooting.md) page for some common problems and solutions.To install bottom, refer to the installation section of the README.md,
which contains a list of all the installation methods.
Usage and configuration
The command to run bottom is btm.
You can refer to the usage pages for more details on using bottom (e.g. keybinds, some features, a general overview of what each widget does).
To configure bottom (e.g. how it behaves, how it looks, etc.) refer to the command-line options page for temporary settings, or the config file page for more permanent settings.
Contribution
New contributors are always welcome! See the contribution section for how to contribute to
bottom, whether it be filing issues, writing documentation, creating pull requests, etc.
Content Configuration Config File Index (`docs/content/configuration/config-file/index.md`)
Config File
For persistent configuration, and for certain configuration options, bottom supports config files.
Default Config File
If no config file argument is given, it will automatically look for a config file at these locations:
| OS | Default Config Location |
|---|---|
| macOS | $HOME/Library/Application Support/bottom/bottom.toml $HOME/.config/bottom/bottom.toml $XDG_CONFIG_HOME/bottom/bottom.toml |
| Linux | $HOME/.config/bottom/bottom.toml $XDG_CONFIG_HOME/bottom/bottom.toml |
| Windows | C:\Users\\AppData\Roaming\bottom\bottom.toml |
If the config file doesn't exist at the path, bottom will automatically try to create a new config file at the location
with default values.
JSON Schema
The configuration file also has JSON Schema support to make it easier to manage, if your
IDE/editor supports it.
Mkdocs.Yml (`docs/mkdocs.yml`)
Site information
site_name: bottom
site_author: Clement Tsang
site_url: https://bottom.pages.dev
site_description: >-
A customizable cross-platform graphical process/system monitor for the
terminal. Supports Linux, macOS, and Windows.
docs_dir: "content/"
Project information
repo_name: ClementTsang/bottom
repo_url: https://github.com/ClementTsang/bottom
edit_uri: "edit/main/docs/content/"
copyright: Copyright © 2019 - 2026 Clement Tsang
Theming
theme:
name: material
font:
code: IBM Plex Mono
features:
- content.action.edit
- navigation.expand
- navigation.footer
- navigation.indexes
- navigation.instant
- navigation.instant.progress
- navigation.sections
- navigation.tabs
- navigation.top
- search.highlight
- search.suggest
- toc.integrate
- toc.follow
icon:
edit: material/pencil
palette:
# Palette toggle for automatic mode
- media: "(prefers-color-scheme)"
scheme: default
toggle:
icon: material/brightness-auto
name: Switch to light mode
# Light mode
- media: "(prefers-color-scheme: light)"
primary: indigo
accent: indigo
toggle:
icon: material/weather-sunny
name: Switch to dark mode
# Dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
primary: black
accent: indigo
toggle:
icon: material/weather-night
name: Switch to system preference
custom_dir: "overrides"
extra_css:
- stylesheets/extra.css
Extensions
markdown_extensions:
- admonition
- attr_list
- toc:
anchorlink: true - pymdownx.inlinehilite
- pymdownx.keys:
Override to make it case-sensitive
key_map:
{
"a": "a",
"b": "b",
"c": "c",
"d": "d",
"e": "e",
"f": "f",
"g": "g",
"h": "h",
"i": "i",
"j": "j",
"k": "k",
"l": "l",
"m": "m",
"n": "n",
"o": "o",
"p": "p",
"q": "q",
"r": "r",
"s": "s",
"t": "t",
"u": "u",
"v": "v",
"w": "w",
"x": "x",
"y": "y",
"z": "z",
"A": "A",
"B": "B",
"C": "C",
"D": "D",
"E": "E",
"F": "F",
"G": "G",
"H": "H",
"I": "I",
"J": "J",
"K": "K",
"L": "L",
"M": "M",
"N": "N",
"O": "O",
"P": "P",
"Q": "Q",
"R": "R",
"S": "S",
"T": "T",
"U": "U",
"V": "V",
"W": "W",
"X": "X",
"Y": "Y",
"Z": "Z",
} - pymdownx.details
- pymdownx.highlight
- pymdownx.superfences
- mdx_truly_sane_lists # See https://github.com/mkdocs/mkdocs/issues/545#issuecomment-522196661
- pymdownx.tabbed:
alternate_style: true
plugins:
- tags
- search
- mike:
canonical_version: stable - git-revision-date-localized:
type: date - privacy
- redirects:
redirect_maps:
nightly-release.md: "https://github.com/ClementTsang/bottom/releases"
extra:
Versioning
version:
provider: mike
default: stable
alias: true
Used for the nightly banner
nightly: false
Navigation
nav:
- "Home": index.md
- "Support":
- "Official Support": support/official.md
- "Unofficial Support": support/unofficial.md
- "Usage":
- "General Usage": usage/general-usage.md
- "Basic Mode": usage/basic-mode.md
- "Widgets":
- "CPU Widget": usage/widgets/cpu-graph.md
- "Memory Graph Widget": usage/widgets/memory-graph.md
- "Network Graph Widget": usage/widgets/network-graph.md
- "Process Widget": usage/widgets/process.md
- "Disk Widget": usage/widgets/disk.md
- "Temperature Widget": usage/widgets/temperature-table.md
- "Temperature Graph Widget": usage/widgets/temperature-graph.md
- "Disk I/O Graph Widget": usage/widgets/disk-io-graph.md
- "Battery Widget": usage/widgets/battery.md
- "Auto-Complete": usage/autocomplete.md
- "Configuration":
- "Command-line Options": configuration/command-line-options.md
- "Config File":
- configuration/config-file/index.md
- "CPU Widget": configuration/config-file/cpu-graph.md
- "Disk Table Widget": configuration/config-file/disk-table.md
- "Memory Graph Widget": configuration/config-file/memory-graph.md
- "Network Graph Widget": configuration/config-file/network-graph.md
- "Processes Widget": configuration/config-file/processes.md
- "Temperature Table Widget": configuration/config-file/temperature-table.md
- "Temperature Graph Widget": configuration/config-file/temperature-graph.md
- "Disk I/O Graph Widget": configuration/config-file/disk-io-graph.md
- "Flags": configuration/config-file/flags.md
- "Layout": configuration/config-file/layout.md
- "Styling": configuration/config-file/styling.md
- "Contribution":
- "Issues, Pull Requests, and Discussions": contribution/issues-and-pull-requests.md
- "Documentation": contribution/documentation.md
- "Packaging and Distribution": contribution/packaging-and-distribution.md
- "Development":
- "Development Environment": contribution/development/dev_env.md
- "Testing": contribution/development/testing.md
- "Logging": contribution/development/logging.md
- "Build Process": contribution/development/build_process.md
- "Deploy Process": contribution/development/deploy_process.md
- "Troubleshooting": troubleshooting.md
hooks:
- ./hooks/nightly_redirect.py
- ./hooks/nightly_banner.py
exclude_docs: |
nightly-release.md
Requirements (`docs/requirements.txt`)
TODO: We may want to migrate off of mkdocs since mkdocs-material is
now on maintenance mode... this might be kinda hard to do though.
mkdocs == 1.6.1
mkdocs-material == 9.7.7
mdx_truly_sane_lists == 1.3
mike == 2.1.4
mkdocs-git-revision-date-localized-plugin == 1.4.5
mkdocs-redirects == 1.2.2
Content Troubleshooting (`docs/content/troubleshooting.md`)
Troubleshooting/Known Issues
The graph points look broken/strange
It's possible that your graphs don't look great out of the box due to the reliance on
braille characters to draw them. This could cause problems if
your terminal's font does not support them, or your terminal is not configured properly to draw them.
<figcaption><sub>An example of missing braille fonts in Powershell</sub></figcaption>Some possible solutions are included below.
Use dot markers instead
One alternative is to use the --dot_marker option to render graph charts using dots instead of the braille characters,
which generally seems better supported out of the box, at the expense of looking less intricate:
<figcaption><sub>Example using `btm --dot_marker`</sub></figcaption>Use a font that supports braille fonts
Another (better) alternative is to install a font that supports braille fonts, and configure your terminal emulator to
use it. For example, installing something like UBraille or
Iosevka and ensuring your terminal uses it should work.
Linux/macOS/Unix
Solutions mostly depend on what terminal emulator you are using, so unfortunately, I can't give specific instructions.
Here are some possible solutions:
- Uninstalling
gnu-free-fontsif installed, as that is known to cause problems with braille markers - Installing a font like
ttf-symbolaorttf-ubraillefor your terminal emulator to try and automatically fall back to - Configuring your terminal emulator to use specific fonts for the
U+2800toU+28FFrange.- For example for kitty, do
symbol_map U+2800-U+28FF Symbola.
- For example for kitty, do
For some more possible solutions:
- Check out this issue from gotop about the same issue.
- See ratatui's FAQ (ratatui is the underlying
library bottom uses to draw things).
Windows and Powershell
Note: I would advise backing up your registry beforehand if you aren't sure what you are doing!
Let's say you're installing Iosevka. The steps you can take are:
Install the font itself.
Open the registry editor, which you can do either by
Win+Rand openingregedit, or just opening it from the Start Menu.In the registry editor, go to
textHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFontHere, add a new
String value, and set theNameto a bunch of 0's (e.g.000- make sure the name isn't already used), then set theDatato the font name (e.g.Iosevka).text<figcaption><sub>The last entry is the new entry for Iosevka</sub></figcaption>Then, open the Command Prompt/PowerShell, and right-click on the top bar, and open "Properties":
From here, go to "Font", and set the font to your new font (so in this example, Iosevka):
Why can't I see all my temperature sensors on Windows?
This is a known issue, some sensors may require admin privileges to get sensor data.
Why don't I see dual batteries on Windows reported separately? (e.g. Thinkpads)
This is a known issue which seems to be with how batteries are being detected on Windows.
Why can't I see all my temperature sensors on WSL?
This is a known limitation with WSL. Due to how it works, hosts may not expose their
temperature sensors and therefore, temperature sensors might be missing.
Why does WSL2 not match Task Manager?
This is a known limitation with WSL2. Due to how WSL2 works, the two might not match
up in terms of reported data.
Why can't I see all my processes/process data on macOS?
You may have to run the program with elevated privileges to work around it - for example:
sudo btm!!! Warning
Please note that you should be certain that you trust any software you grant root privileges.
There are measures taken to try to maximize the amount of information obtained without elevated privileges. For example,
one can modify the instructions found on the [htop wiki](https://github.com/hishamhm/htop/wiki/macOS:-run-without-sudo)
on how to run htop without sudo for bottom. However, **please** understand the potential security risks before doing so!My configuration file isn't working
If your configuration files aren't working, here are a few things to try:
Check the formatting
It may be handy to refer to the automatically generated config files or the
sample configuration files. The config files also
follow the TOML format.
Also make sure your config option settings are in the right location - for example, to set your temperature type, you must
set it under the [flags] table:
[flags]
temperature_type = "f"Meanwhile, if you want to set a custom colour or styling scheme, it would be under the [styles] table - for example:
[styles.tables.headers]
colour = "LightBlue"
bold = trueTo help validate your configuration files, there is JSON Schema support if your IDE/editor
supports it.
Check the configuration file location
Make sure bottom is reading the right configuration file. By default, bottom looks for config files at these locations:
| OS | Default Config Location |
|---|---|
| macOS | $HOME/Library/Application Support/bottom/bottom.toml ~/.config/bottom/bottom.toml $XDG_CONFIG_HOME/bottom/bottom.toml |
| Linux | ~/.config/bottom/bottom.toml $XDG_CONFIG_HOME/bottom/bottom.toml |
| Windows | C:\Users\\AppData\Roaming\bottom\bottom.toml |
If you want to use a config file in another location, use the --config or -C flags along with the path to the configuration file, like so:
btm -C path_to_configMy installation through snap has some widgets that are blank/show no data
Make sure bottom is given the correct permissions in order to collect data. Snapcraft
explains how to do so, but the TL;DR is:
sudo snap connect bottom:mount-observe
sudo snap connect bottom:hardware-observe
sudo snap connect bottom:system-observe
sudo snap connect bottom:process-controlI don't see any NVIDIA GPU information while using a musl-based binary
The underlying interface we use for NVIDIA GPU information, nvml, only works with glibc and does not work with musl at the moment (see this forum post for some more details). As such, bottom may fail to get NVIDIA GPU information when using a musl-based binary until this is resolved. This applies to Linux and Windows from my understanding.
To resolve this, use glibc-based binary builds if possible (e.g. the gnu binaries/non-musl packages in releases).
Still having issues?
If you're still having issues, feel free to open a discussion
question about it, and I (or others) can try to help.
Content Configuration Command Line Options (`docs/content/configuration/command-line-options.md`)
Command-line Options
The following options can be provided to bottom in the command line to change the behaviour of the program. You can also
see information on these options by running btm -h, or run btm --help to display more detailed information on each option:
General Options
| Option | Behaviour |
|---|---|
--autohide_time |
Temporarily shows the time scale in graphs. |
-b, --basic |
Hides graphs and uses a more basic look. |
-C, --config_location |
Sets the location of the config file. |
-t, --default_time_value <TIME> |
Default time value for graphs. |
--default_widget_count <N> |
Sets the N'th selected widget type as the default. |
--default_widget_type <WIDGET> |
Sets the default widget type. Use --help for more info. |
--disable_click |
Disables mouse clicks. |
--disable_keys |
Disables keyboard shortcuts, INCLUDING the ones that stop |
| bottom. | |
-m, --dot_marker |
Uses a dot marker for graphs. |
-e, --expanded |
Expand the default widget upon starting the app. |
--hide_time |
Hides the time scale from being shown. |
-r, --rate <TIME> |
Sets how often data is refreshed. |
--retention <TIME> |
How far back data will be stored up to. |
--show_table_scroll_position |
Shows the list scroll position tracker in the widget title |
| for table widgets. | |
-d, --time_delta <TIME> |
The amount of time changed upon zooming. |
Disk Options
| Option | Behaviour |
|---|---|
--disk_use_binary_prefix |
Displays the disk widget with binary prefixes (e.g. GiB, MiB) instead of decimal prefixes (e.g. GB, MB). |
Process Options
| Option | Behaviour |
|---|---|
-S, --case_sensitive |
Enables case sensitivity by default when searching. |
-u, --current_usage |
Calculates process CPU usage as a percentage of current usage rather than total usage. |
--disable_advanced_kill |
Hides additional stopping options on Unix-like systems. |
--read_only |
Prevents performing any actions that affect the system (e.g. stopping processes). |
--get_threads |
Also gather process thread information. |
-g, --group_processes |
Groups processes with the same name by default. No effect if --tree is set. |
--hide_k_threads |
Hide kernel threads from being shown. |
--process_memory_as_value |
Defaults to showing process memory usage by value. |
--process_command |
Shows the full command name instead of the process name by default. |
-R, --regex |
Enables regex by default while searching. |
-T, --tree |
Makes the process widget use tree mode by default. |
--tree_collapse |
Collapse the process tree by default. |
-n, --unnormalized_cpu |
Show process CPU% usage without averaging over the number of CPU cores. |
-W, --whole_word |
Enables whole-word matching by default while searching. |
Temperature Options
| Option | Behaviour |
|---|---|
-c, --celsius |
Use Celsius as the temperature unit. Default. |
-f, --fahrenheit |
Use Fahrenheit as the temperature unit. |
-k, --kelvin |
Use Kelvin as the temperature unit. |
CPU Options
| Option | Behaviour |
|---|---|
--cpu_left_legend |
Puts the CPU chart legend on the left side. |
--default_cpu_entry |
Sets which CPU entry type is selected by default. |
-a, --hide_avg_cpu |
Hides the average CPU usage entry. |
Memory Options
| Option | Behaviour |
|---|---|
--memory_legend |
Where to place the legend for the memory chart widget. |
--enable_cache_memory |
Enable collecting and displaying cache and buffer memory. |
--free_arc |
Subtract ARC memory that can be freed from memory usage. |
--short_gpu_names |
Use short GPU names in the memory widget. |
Network Options
| Option | Behaviour |
|---|---|
--network_legend |
Where to place the legend for the network chart widget. |
--network_use_bytes |
Displays the network widget using bytes. |
--network_use_binary_prefix |
Displays the network widget binary prefixes (e.g. GiB, MiB) instead of decimal prefixes (e.g. GB, MB). |
--network_use_log |
Displays the network widget with a log scale. |
--show_packets |
Displays packet rate and average packet size info. |
--use_old_network_legend |
Uses a separate network legend. |
--network_start_zeroed |
Show total network usage from app startup rather than on boot. |
Battery Options
| Option | Behaviour |
|---|---|
--battery |
Shows the battery widget in non-custom layouts. |
GPU Options
| Option | Behaviour |
|---|---|
--disable_gpu |
Disable collecting and displaying NVIDIA and AMD GPU information. |
Style Options
| Option | Behaviour |
|---|---|
--theme <SCHEME> |
Use a built-in colour theme, use '--help' for info on the colours. |
Other Options
| Option | Behaviour |
|---|---|
-h, --help |
Prints help info (for more details use --help.) |
-V, --version |
Prints version information. |
Content Contribution Documentation (`docs/content/contribution/documentation.md`)
Documentation
When should documentation changes be done?
- Whenever a new feature is added, a bug is fixed, or a breaking change is made, it should be documented where
appropriate (ex:README.md, changelog, etc.) - New methods of installation are always appreciated and should be documented
What pages need documentation?
There are a few areas where documentation changes are often needed:
- The
README.md - The help menu inside of the application (located here)
- The extended documentation (what you're reading right now)
- The
CHANGELOG.md
How should I add/update documentation?
Fork the repository to make changes in.
Where you're adding documentation will probably affect what you need to do:
`README.md` or `CHANGELOG.md`
For changes to
README.mdandCHANGELOG.md, just follow the formatting provided and use any editor.Generally, changes to
CHANGELOG.mdwill be handled
by a maintainer, and the contents of the file should follow the Keep a Changelog
format, as well as link to the relevant PR or issues.Help menu
For changes to the help menu, try to refer to the existing code within
src/constants.rson how the help menu is generated.Extended documentation
For changes to the extended documentation, you'll probably want at least Python 3.11 (older and newer versions
should be fine), MkDocs, Material for MkDocs,mdx_truly_sane_lists, and optionally Mike installed. These can help with
validating your changes locally.You can do so through
pipor your system's package managers. If you usepip, you can use venv to cleanly install
the documentation dependencies:bash# Change directories to the documentation. cd docs/ # Create venv, install the dependencies, and serve the page. ./serve.shThis will serve a local version of the docs that you can open on your browser. It will update as you make changes.
Once you have your documentation changes done, submit it as a pull request. For more information regarding that,
refer to Issues, Pull Requests, and Discussions.
AI Policy
Documentation should never be generated by AI. The point of documentation in this project is to communicate things between humans. Follow the AI policy; changes that do not follow it
may be closed or hidden.
Content Contribution Issues And Pull Requests (`docs/content/contribution/issues-and-pull-requests.md`)
Issues, Pull Requests, and Discussions
Discussions
Discussions are open in the repo. As for the difference between discussions and issues:
- Open an issue if what you have enough information to properly fill out any details needed for a report or request.
- Open a discussion otherwise (e.g. asking a question).
Opening an issue
Bug reports
When filing a bug report, please use the bug report template and fill in as much as you can. It is incredibly difficult for a maintainer to fix a bug when it cannot be reproduced, and giving as much detail as possible generally helps to make it easier to reproduce the problem!
Feature requests
Please use the feature request template and fill it out. Remember to give details about what the feature is along with why you think this suggestion will be useful first! Also, please check whether an existing issue
already covers your specific feature request.
Pull requests
Note: if you want to add a new feature, please first open an appropriate issue to discuss the merits of the feature.
PRs that do not do this may be closed.
The expected workflow for a pull request is:
- Fork the project.
- Make your changes.
- Make any documentation changes if necessary - if you add a new feature, it'll probably need documentation changes. See here for tips on documentation.
- Commit and create a pull request to merge into the
mainbranch. Please fill out the pull request template and checklist. - Ask a maintainer to review your pull request.
- Check if the CI workflow passes. These consist of clippy lints, rustfmt checks, and basic tests. If you are a
first-time contributor, you may need to wait for a maintainer to let CI run. - If changes are suggested or any comments are made, they should probably be addressed.
- Check if the CI workflow passes. These consist of clippy lints, rustfmt checks, and basic tests. If you are a
- Once it looks good, it'll be merged! Note that generally, PRs are squashed to maintain repo cleanliness, though
feel free to ask otherwise if that isn't preferable.
Some other things related to making changes or pull requests:
- Please review your code yourself and test your changes before you create the PR and ask for a review.
- If you are adding or changing any dependency, a justification on why this is necessary must be included.
- Please ensure that any changes made are compatible with the license of bottom.
AI Policy
Note that any contribution, whether it be opening an issue, PRs, or commenting, should follow the AI policy. Contributions that do not follow this may be closed/hidden.
Content Contribution Packaging And Distribution (`docs/content/contribution/packaging-and-distribution.md`)
Packaging and Distribution
Package maintainers are always welcome and appreciated! Here's some info on how one can help with package distribution
and bottom.
Pre-built binaries
The latest stable release can be found here, where you can
find pre-built binaries in either a tar.gz or zip format. Binaries here also include automatically generated shell
completion files for zsh, bash, fish, and Powershell, which you may want to also install during the packaging
process.
You can also find a nightly build in the releases page, built every
day at 00:00 UTC off of the main branch.
In both cases, we use GitHub Actions to create our release binaries.build_releases.yml
contains the GitHub Action workflow for this.
Building manually
If you want to manually build bottom rather than distributing a pre-built binary, you'll need the most recent version
of stable Rust, which you can get with:
rustup update stableYou'll then want to build with:
cargo build --release --lockedManpage and completion generation
bottom uses a build.rs script to automatically generate
a manpage and shell completions for the following shells:
- Bash
- Zsh
- Fish
- Powershell
- Elvish
If you want to generate manpages and/or completion files, set the BTM_GENERATE env var to a non-empty value. For
example, run something like this:
BTM_GENERATE=true cargo build --release --lockedThis will automatically generate completion and manpage files in target/tmp/bottom/. If you wish to regenerate the
files, modify/delete either these files or set BTM_GENERATE to some other non-empty value to retrigger the build
script.
You may override the default directories used to generate both completion and manpage files by specifying theCOMPLETION_DIR and MANPAGE_DIR environment variables respectively.
For more information, you may want to look at either the build.rs
file or the binary build CI workflow.
Adding an installation source
Once you've finished your installation source, if you want to mention it in the main bottom repo, fork the repo and add
the installation method and any details to the README.md
file under the Installation section, as well as a corresponding
table of contents entry. Once that's done, open a pull request - these will usually be approved of very quickly.
You can find more info on the contribution process here.
Content Support Official (`docs/content/support/official.md`)
Official support
bottom officially supports the following operating systems and corresponding architectures:
- macOS (
x86_64,aarch64) - Linux (
x86_64,i686,aarch64) - Windows (
x86_64,i686)
These platforms are tested to work (with caveats, see below) and issues on these platforms will be fixed if possible.
Furthermore, binaries are expected to be built and tested using the most recent version of stable Rust - if you are manually building
bottom from the repo/source, then please try that as well.
If you encounter any issues, see the troubleshooting page or open an issue/discussion on GitHub.
Content Support Unofficial (`docs/content/support/unofficial.md`)
Unofficial support
Systems and architectures that aren't officially supported may still work, but there are no guarantees on how much will
work. For example, it might only compile, or it might run with bugs/broken features. Furthermore, while it will depend
on the problem at the end of the day, issues on unsupported platforms are likely to go unfixed.
Unofficially supported platforms known to compile/work:
- FreeBSD on x86 (built and tested in CI)
- Linux on ARMv7 and ARMv6 (built in CI)
- Linux on PowerPC 64 LE (built in CI)
- Linux on an RISC-V (built in CI, tested to run on an Allwinner D1 Nezha)
- NetBSD on x86 (built in CI)
If you encounter any issues, see the troubleshooting page or open an issue/discussion on
GitHub - though as mentioned, unsupported platforms may go unfixed.
Content Usage Autocomplete (`docs/content/usage/autocomplete.md`)
Auto-Complete
The release binaries in the releases page are packaged with
shell auto-completion files for Bash, Zsh, fish, Powershell, Elvish, Fig, and Nushell. To install them:
- For Bash, move
btm.bashto$XDG_CONFIG_HOME/bash_completion or /etc/bash_completion.d/. - For Zsh, move
_btmto one of your$fpathdirectories. - For fish, move
btm.fishto$HOME/.config/fish/completions/. - For PowerShell, add
_btm.ps1to your PowerShell profile. - For Elvish, the completion file is
btm.elv. - For Fig, the completion file is
btm.ts. - For Nushell, source
btm.nu.
The individual auto-completion files are also included in the stable/nightly releases as completion.tar.gz if needed.
Content Usage Basic Mode (`docs/content/usage/basic-mode.md`)
Basic Mode
Basic mode is a special layout that removes all of the graphs and provides an interface that resembles (a very stripped-down version of) htop.
Basic mode can be enabled either through a command line flag:
btm -b
# or
btm --basicor through the config:
[flags]
basic = trueNotes
In this mode, widgets that use tables (temperatures, processes, disks, and batteries) are only shown one at a time.
One can switch between these widgets either by clicking the arrow buttons or by using the general widget selection shortcuts (for example, ++ctrl+left++ or ++H++)
to switch which widget is shown.
Also note that in this mode, widget expansion and custom layouts are disabled.
Key bindings
Basic mode follows the same key bindings as normal, barring widget expansion being disabled, and that the ++"%"++ key while selecting the memory widget toggles between total usage and percentage.
Content Usage General Usage (`docs/content/usage/general-usage.md`)
General Usage
You can run bottom with:
btmFor help regarding the command-line options, use:
# For a simple overview of flags
btm -h
# For more details
btm --helpYou can also see keybinds and basic usage details in bottom by pressing ++question++, which will open a help menu.
Features
Expansion
By default, bottom is somewhat like a dashboard - a bunch of different widgets, all showing different things, and they all cram together to fit into one terminal.
If you instead just want to see one widget - maybe you want to look at a graph in more detail, for example - you can "expand" the currently selected
widget using the ++e++ key, which will hide all other widgets and make that widget take up all available terminal space.
You can leave this state by either pressing ++e++ again or pressing ++esc++.
Widget selection
To allow for widget-specific keybindings and expansion, there is the idea of widget selection in bottom, where you can focus on a specific widget to work with it.
This can be done with the mouse (just click on the widget of interest) or keyboard (ex: ++ctrl+"Direction"++, see Key bindings for alternatives).
Key bindings
These are global or common keyboard shortcuts for the application, which you can see in-app through the ++question++ shortcut.
Note that key bindings are generally case-sensitive.
| Binding | Action |
|---|---|
| ++q++, ++Q++, ++ctrl+c++ | Quit |
| ++esc++ | Close dialog windows, search, widgets, or exit expanded mode |
| ++ctrl+r++ | Reset display and any collected data |
| ++f++ | Freeze/unfreeze updating with new data |
| ++question++ | Open help menu |
| ++e++ | Toggle expanding the currently selected widget |
| ++ctrl+up++ ++shift+up++ ++K++ ++W++ | Select the widget above |
| ++ctrl+down++ ++shift+down++ ++J++ ++S++ | Select the widget below |
| ++ctrl+left++ ++shift+left++ ++H++ ++A++ | Select the widget on the left |
| ++ctrl+right++ ++shift+right++ ++L++ ++D++ | Select the widget on the right |
| ++up++ , ++k++ | Move up within a widget |
| ++down++ , ++j++ | Move down within a widget |
| ++left++ ++h++ ++alt+h++ | Move left within a widget |
| ++right++ ++l++ ++alt+l++ | Move right within a widget |
| ++g+g++ , ++home++ | Jump to the first entry |
| ++G++ , ++end++ | Jump to the last entry |
| ++page-up++ , ++page-down++ | Scroll up/down a table by a page |
| ++ctrl+u++ | Scroll up a table by half a page |
| ++ctrl+d++ | Scroll down a table by half a page |
Mouse bindings
| Binding | Action |
|---|---|
| ++lbutton++ | Selects the widget |
Content Configuration Config File Cpu Graph (`docs/content/configuration/config-file/cpu-graph.md`)
CPU Configuration
If you want to change some of the default behaviour of the CPU graph widget, you can configure things under the [cpu] section.
Default CPU graph selection
You can configure which CPU graph is shown by default on startup by setting cpu.default. Defaults to "all", which
shows all entries.
[cpu]
# One of "all" (default), "average"/"avg"
default = "average"Show decimal
You can configure whether CPU usage values are shown with a decimal place by setting cpu.show_decimal. Defaults
to false.
[cpu]
show_decimal = trueHide average CPU entry
You can hide the average CPU entry entirely by setting cpu.hide_avg_cpu. Defaults to false.
[cpu]
hide_avg_cpu = truePlace legend on the left
You can place the CPU chart legend on the left side by setting cpu.left_legend. Defaults to false.
[cpu]
left_legend = trueAverage CPU row
In basic mode, you can give the average CPU entry a dedicated row by setting cpu.basic_average_cpu_row. Defaults to false.
[cpu]
basic_average_cpu_row = trueContent Configuration Config File Disk Io Graph (`docs/content/configuration/config-file/disk-io-graph.md`)
Disk I/O Graph Configuration
The disk I/O graph widget is configured under [disk_io_graph].
Showing Read/Write Lines
By default, both the read and write rate lines are shown. They can be toggled off independently.
[disk_io_graph]
# Whether to show the read rate line. Defaults to true.
show_read = true
# Whether to show the write rate line. Defaults to true.
show_write = trueLegend Labels
By default, legend entries are labelled by disk name (e.g. sda, nvme0n1). To use mount points
instead (e.g. /, /home):
[disk_io_graph]
legend = "mount"Valid values are "disk" (default) and "mount".
Logarithmic Scale
The y-axis can be switched to a logarithmic scale:
[disk_io_graph]
use_log = trueLegend Position
The location of the legend can be set with legend_position. Valid values are none, top-left, top, top-right,left, right, bottom-left, bottom, and bottom-right. Defaults to top-right.
[disk_io_graph]
legend_position = "top-right"Show Unmounted Devices (Linux only)
By default, only mounted devices are shown. To also show unmounted devices on Linux, enable include_unmounted:
[disk_io_graph]
include_unmounted = trueFiltering Entries
You can filter out what entries to show by configuring [disk_io_graph.name_filter] and [disk_io_graph.mount_filter] to filter by
name and mount point respectively. In particular, you can set a list of things to filter with by setting list,
and configure how that list is processed with the other options.
If we wanted to ignoring any entry with a name that matches /dev/sda:
[disk_io_graph.name_filter]
# Whether to ignore any matches. Defaults to true.
is_list_ignored = true
# A list of filters to try and match.
list = ["/dev/sda"]
# Whether to use regex. Defaults to false.
regex = true
# Whether to be case-sensitive. Defaults to false.
case_sensitive = false
# Whether to require matching the whole word. Defaults to false.
whole_word = falseContent Configuration Config File Disk Table (`docs/content/configuration/config-file/disk-table.md`)
Disk Table Configuration
Columns
You can configure which columns are shown by the disk table widget by setting the columns setting:
[disk]
# Pick which columns you want to use in any order.
columns = ["Disk", "Mount", "Used", "Free", "Total", "Used%", "R/s", "W/s"]Default Sort Column
You can customize the default sort column (by default, it sorts by disk name in ascending order). For example, to sort by the read rate:
[disk]
default_sort = "R/s"You can use any valid column name here (e.g. "Disk", "Mount", etc.). Note that if you put a column name that
is not actually used, the default sort will just be the first column shown.
You can also set the sort order by changing disk.sort_order with "Ascending" or "Descending". Defaults to"Ascending":
[disk]
sort_order = "Ascending"Using Binary Prefixes
Disk space uses decimal prefixes (e.g. KB, MB, GB, TB) by default. To display using binary prefixes instead
(e.g. KiB, MiB, GiB, TiB), enable use_binary_prefix:
[disk]
use_binary_prefix = trueShow Unmounted Devices (Linux only)
By default, only mounted devices are shown. To also show unmounted devices on Linux, enable include_unmounted:
[disk]
include_unmounted = trueUnmounted devices show I/O activity but have no used/free space (those require a live mount), so those
columns appear as N/A. Pseudo-devices (loop*, ram*, zram*) are skipped, and you can hide other
noisy devices with the name filter.
Filtering Entries
You can filter out what entries to show by configuring [disk.name_filter] and [disk.mount_filter] to filter by name and mount point respectively. In particular,
you can set a list of things to filter with by setting list, and configure how that list
is processed with the other options.
For example, consider a disk widget showing these entries:
If we wanted to ignoring any entry with a name that matches /dev/sda:
[disk.name_filter]
# Whether to ignore any matches. Defaults to true.
is_list_ignored = true
# A list of filters to try and match.
list = ["/dev/sda"]
# Whether to use regex. Defaults to false.
regex = true
# Whether to be case-sensitive. Defaults to false.
case_sensitive = false
# Whether to require matching the whole word. Defaults to false.
whole_word = falseThis would give us:
We can also combine both the name filter and mount filter. For example:
[disk.name_filter]
is_list_ignored = false
list = ["/dev/sda"]
regex = true
case_sensitive = false
whole_word = false
[disk.mount_filter]
is_list_ignored = true
list = ["/mnt/.*", "/"]
regex = true
case_sensitive = false
whole_word = trueThis gives us:
Content Configuration Config File Flags (`docs/content/configuration/config-file/flags.md`)
Flags
!!! Warning
This section is in progress, and is just copied from the old documentation.You can configure flags by putting them in [flags] table. Example:
[flags]
hide_avg_cpu = trueMost of the command line flags have config file equivalents to avoid having to type them out
each time:
| Field | Type | Functionality |
|---|---|---|
hide_avg_cpu |
Boolean | Deprecated - use cpu.hide_avg_cpu. Hides the average CPU usage. |
dot_marker |
Boolean | Uses a dot marker for graphs. |
cpu_left_legend |
Boolean | Deprecated - use cpu.left_legend. Puts the CPU chart legend to the left side. |
current_usage |
Boolean | Deprecated - use processes.current_usage. Sets process CPU% to be based on current CPU%. |
group_processes |
Boolean | Deprecated - use processes.default_grouped. Groups processes with the same name by default. |
case_sensitive |
Boolean | Deprecated - use processes.case_sensitive. Enables case sensitivity by default. |
whole_word |
Boolean | Deprecated - use processes.whole_word. Enables whole-word matching by default. |
regex |
Boolean | Deprecated - use processes.regex. Enables regex by default. |
basic |
Boolean | Hides graphs and uses a more basic look. |
use_old_network_legend |
Boolean | DEPRECATED - uses the older network legend. |
battery |
Boolean | Shows the battery widget. |
rate |
Unsigned Int (represents milliseconds) or String (represents human time) | Sets a refresh rate in ms. |
default_time_value |
Unsigned Int (represents milliseconds) or String (represents human time) | Default time value for graphs in ms. |
time_delta |
Unsigned Int (represents milliseconds) or String (represents human time) | The amount in ms changed upon zooming. |
hide_time |
Boolean | Hides the time scale. |
temperature_type |
String (one of ["k", "f", "c", "kelvin", "fahrenheit", "celsius"]) | Sets the temperature unit type. |
default_widget_type |
String (one of ["cpu", "proc", "net", "temp", "mem", "disk"], same as layout options) | Sets the default widget type, use --help for more info. |
default_widget_count |
Unsigned Int (represents which default_widget_type) |
Sets the n'th selected widget type as the default. |
disable_click |
Boolean | Disables mouse clicks. |
enable_cache_memory |
Boolean | Deprecated - use memory.cache_memory. Enable cache and buffer memory stats (not available on Windows). |
process_memory_as_value |
Boolean | Deprecated - use processes.default_memory_value. Defaults to showing process memory usage by value. |
tree |
Boolean | Deprecated - use processes.default_tree. Defaults to showing the process widget in tree mode. |
show_table_scroll_position |
Boolean | Shows the scroll position tracker in table widgets. |
show_table_scroll_bar |
Boolean | Shows a scroll bar on the right edge of table widgets. Enabled by default. |
process_command |
Boolean | Deprecated - use processes.process_command. Show processes as their commands by default. |
disable_advanced_kill |
Boolean | Deprecated - use processes.disable_advanced_kill. Disable being able to send signals to processes on supported Unix-like systems. Only available on Linux, macOS, and FreeBSD. |
read_only |
Boolean | Prevents performing any actions that affect the system (e.g. stopping processes). |
network_use_binary_prefix |
Boolean | Deprecated - use network_graph.use_binary_prefix. Displays the network widget with binary prefixes. |
network_use_bytes |
Boolean | Deprecated - use network_graph.use_bytes. Displays the network widget using bytes. |
network_use_log |
Boolean | Deprecated - use network_graph.use_log. Displays the network widget with a log scale. |
disable_gpu |
Boolean | Disable NVIDIA and AMD GPU data collection. |
retention |
String (human readable time, such as "10m", "1h", etc.) | How much data is stored at once in terms of time. |
unnormalized_cpu |
Boolean | Deprecated - use processes.unnormalized_cpu. Show process CPU% without normalizing over the number of cores. |
expanded |
Boolean | Expand the default widget upon starting the app. |
memory_legend |
String (one of ["none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right"]) | Deprecated - use memory_graph.legend_position or memory.legend_position; where to place the legend for the memory widget. |
network_legend |
String (one of ["none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right"]) | Deprecated - use network_graph.legend_position or network.legend_position; where to place the legend for the network widget. |
average_cpu_row |
Boolean | Deprecated - use cpu.basic_average_cpu_row. Moves the average CPU usage entry to its own row when using basic mode. |
tree_collapse |
Boolean | Deprecated - use processes.tree_collapse. Collapse process tree by default. |
autohide_time |
Boolean | Temporarily shows the time scale in graphs. |
table_gap |
String (one of ["none", "space", "line"]) | Controls the gap between table headers and data rows. Defaults to "space". |
disable_keys |
Boolean | Disables keyboard shortcuts, including the ones that stop bottom. |
no_write |
Boolean | Disables writing to the config file. |
hide_k_threads |
Boolean | Deprecated - use processes.hide_k_threads. Hide kernel threads from being shown. |
free_arc |
Boolean | Deprecated - use memory.free_arc. Subtract ARC memory that can be freed from memory usage. |
Content Configuration Config File Layout (`docs/content/configuration/config-file/layout.md`)
Layout
!!! Warning
This section is in progress, and is just copied from the old documentation.bottom supports customizable layouts via the config file. Currently, layouts are controlled by using TOML objects and arrays.
For example, given the sample layout:
[[row]]
[[row.child]]
type="cpu"
[[row]]
ratio=2
[[row.child]]
ratio=4
type="mem"
[[row.child]]
ratio=3
[[row.child.child]]
type="temp"
[[row.child.child]]
type="disk"This would give a layout that has two rows, with a 1:2 ratio. The first row has only the CPU widget.
The second row is split into two columns with a 4:3 ratio. The first column contains the memory widget.
The second column is split into two rows with a 1:1 ratio. The first is the temperature widget, the second is the disk widget.
This is what the layout would look like when run:
Each [[row]] represents a row in the layout. A row can have any number of child values. Each [[row.child]]
represents either a column or a widget. A column can have any number of child values as well. Each [[row.child.child]]
represents a widget. A widget is represented by having a type field set to a string.
The following type values are supported:
"cpu" |
CPU chart and legend |
"mem", "memory" |
Memory chart |
"net", "network" |
Network chart and legend |
"proc", "process", "processes" |
Process table and search |
"temp", "temperature" |
Temperature table |
"temp_graph", "temperature_graph" |
Temperature graph |
"disk" |
Disk table |
"disk_io_graph" |
Disk I/O graph |
"empty" |
An empty space |
"batt", "battery" |
Battery statistics |
Each component of the layout accepts a ratio value. If this is not set, it defaults to 1.
Furthermore, you can have duplicate widgets.
For an example, look at the default config, which contains the default layout.
Content Configuration Config File Memory Graph (`docs/content/configuration/config-file/memory-graph.md`)
Memory Graph Configuration
If you want to change some of the default behaviour of the memory graph widget, you can configure things under the [memory_graph] (or [memory]) section.
Graph legend position
You can change where the legend for the graph is placed within the widget itself (or hidden with "none"). The default is "top-right".
[memory_graph]
# One of ["none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right"]
legend_position = "top-left"Collect/show cache memory
On Linux, you can change whether the memory used by cache/slabs is collected and
shown. By default, it is false.
[memory_graph]
cache_memory = trueShort GPU names
If GPU support is enabled, you can use short_gpu_names to display simplified GPU names in the memory graph widget
instead of the full GPU names. If enabled, then if there's only one GPU, it'll just list the entry as GPU;
if there are multiple GPUs, it'll use entries like GPU0, GPU1, etc. By default, this is disabled.
[memory_graph]
short_gpu_names = trueSubtract free-able ARC from memory
If ZFS is detected (note that the zfs feature must be enabled if built manually), you can enable memory_graph.free_arc to
not count ARC memory in the RAM usage calculations. Disabled
by default.
[memory_graph]
free_arc = trueContent Configuration Config File Network Graph (`docs/content/configuration/config-file/network-graph.md`)
Network Graph Configuration
Settings
If you want to change some of the default behaviour of the network graph widget, you can configure some things in the config file.
| Field | Type | Functionality |
|---|---|---|
show_packets |
Boolean | Displays packet rate and average packet size info. |
legend_position |
String (one of ["none", "top-left", "top", "top-right", "left", "right", "bottom-left", "bottom", "bottom-right"]) | Where to place the legend for the network widget. |
use_bytes |
Boolean | Displays the network widget using bytes. Defaults to bits. |
use_log |
Boolean | Displays the network widget with a log scale. Defaults to a non-log scale. |
use_binary_prefix |
Boolean | Displays the network widget with a binary prefix (e.g. kibibits) rather than a decimal prefix (e.g. kilobits). Defaults to decimal prefixes. |
start_zeroed |
Boolean | Zeroes out the total network usage ("All") counters such that it shows the total usage since the app is started, rather than the total usage since boot. |
Filtering Entries
You can filter out what entries to show by configuring [network_graph.interface_filter] .
In particular, you can set a list of things to filter with by setting list, and configure how that list is processed with the other options.
For example, here we are ignoring any entry with a name that matches the regex eth0.*, or specifically virbr0.
[network_graph.interface_filter]
# Whether to ignore any matches. Defaults to true.
is_list_ignored = true
# A list of filters to try and match.
list = ["virbr0", "eth0slab"]
# Whether to use regex. Defaults to false.
regex = true
# Whether to be case-sensitive. Defaults to false.
case_sensitive = false
# Whether to require matching the whole word. Defaults to false.
whole_word = falseContent Configuration Config File Processes (`docs/content/configuration/config-file/processes.md`)
Processes Configuration
Settings
If you want to change some of the default behaviour of the processes widget, you can configure some things in the config file.
| Field | Type | Functionality |
|---|---|---|
get_threads |
Boolean | Gather process thread information. |
hide_k_threads |
Boolean | Hide kernel threads from being shown. Linux only. |
tree_collapse |
Boolean | Collapse the process tree by default when tree mode is set. |
process_command |
Boolean | Shows the full command name instead of the process name by default. |
disable_advanced_kill |
Boolean | Disable the advanced kill dialog and just show the basic one with no options. Linux, macOS, FreeBSD only. |
default_memory_value |
Boolean | Defaults to showing process memory usage by value. |
default_grouped |
Boolean | Groups processes with the same name by default. No effect if --tree is set. |
regex |
Boolean | Enables regex by default while searching. |
case_sensitive |
Boolean | Enables case sensitivity by default when searching. |
whole_word |
Boolean | Enables whole-word matching by default while searching. |
default_tree |
Boolean | Makes the process widget use tree mode by default. |
current_usage |
Boolean | Calculates process CPU usage as a percentage of current usage rather than total usage. |
unnormalized_cpu |
Boolean | Show process CPU% usage without averaging over the number of CPU cores. |
Columns
You can configure which columns are shown by the process widget by setting the columns setting:
[processes]
# Pick which columns you want to use in any order.
columns = ["cpu%", "mem%", "pid", "name", "read", "write", "tread", "twrite", "state", "user", "time", "gmem%", "gpu%"]Default Sort Column
By default, the process widget starts sorted by CPU usage in descending order. You can change the column it sorts by at startup:
[processes]
default_sort = "mem"Any of the column names accepted by columns work here (e.g. "cpu%", "mem", "pid", "name", "read"). If the
column you pick is not actually shown by the widget, the built-in default is used instead.
The same setting is also exposed as a CLI flag, which takes precedence over the config file:
btm --process_default_sort memYou can also set the default order by changing processes.sort_order with "Ascending" or "Descending". If not set, then by default, it will use a sort order that is reasonable (e.g. descending for CPU/memory usage, ascending for process names).
[processes]
sort_order = "Ascending"Content Configuration Config File Styling (`docs/content/configuration/config-file/styling.md`)
Styling
Various parts of the bottom can be styled, using either built-in themes or custom theming.
Precedence
As there are a few ways styles can be applied to bottom, the order of which styles are prioritized are, in order of
highest precedence to lowest precedence:
- Built-in themes set via command-line args (e.g.
btm --theme gruvbox) - Custom themes set via config file
- Built-in themes set via config file
If nothing is set, it will fall back to the default theme.
Built-in styles
bottom has a few built-in themes:
These themes all also have light variants to support terminals using lighter colours.
To set the theme from the command line:
btm --theme gruvboxTo set the theme using the config file:
[styles]
theme = "gruvbox"Custom styling
bottom's components can also be individually styled by the user to control the colour of the text style.
Colours
!!! Info
Note that anywhere `"colour"` is used, it can be substituted for `"color"`:
```toml
# This is okay
[styles.widgets.widget_title]
colour = "black"
bg_colour = "white"
[styles.cpu]
all_entry_colour = "green"
# This is also okay
[styles.widgets.widget_title]
color = "black"
bg_color = "white"
[styles.cpu]
all_entry_color = "green"
```You can configure the colours for components with strings that are either hex colours (e.g. "#ffffff"), RGB colours
(e.g. "255, 255, 255"), or named colours. Named colours are one of the following strings:
"Black""Red""Green""Yellow""Blue""Magenta""Cyan""Gray""DarkGray""LightRed""LightGreen""LightYellow""LightBlue""LightMagenta""LightCyan""White"
Text
Text can generally be styled using the following TOML table:
[field]
# The foreground colour of text.
colour = "black"
# The background colour of text.
bg_colour = "blue"
# Whether to make the text bold.
bold = false
# Inline table version
field = { colour = "black", bg_colour = "blue", bold = false }All fields are optional; by default if bg_colour is not set then there will be no background colour.
If you just want to style text by setting the foreground colour, for brevity, then you can also just set the field
to be the colour itself. For example:
[styles.widgets]
selected_text = "#fff"Configuration
CPU
These can be set under [styles.cpu]:
| Config field | Details | Examples |
|---|---|---|
all_entry_colour |
The colour of the "All" CPU label | all_entry_colour = "Red" |
avg_entry_colour |
The colour of the average CPU label and graph line | avg_entry_colour = "255, 0, 255" |
cpu_core_colours |
Colour of each CPU threads' label and graph line. Read in order. | cpu_core_colours = ["Red", "Blue", "Green"] |
Temperature Graph
These can be set under [styles.temp_graph]:
| Config field | Details | Examples |
|---|---|---|
temp_graph_colour_styles |
Colour of each temperature sensor's graph line. Read in order. | temp_graph_colour_styles = ["Red", "Blue", "Green"] |
Memory
These can be set under [styles.memory]:
| Config field | Details | Examples |
|---|---|---|
ram_colour |
The colour of the RAM label and graph line | ram_colour = "Red" |
cache_colour |
The colour of the cache label and graph line. Does not do anything on Windows. | cache_colour = "#ffffff" |
swap_colour |
The colour of the swap label and graph line | swap_colour = "255, 0, 255" |
arc_colour |
The colour of the ARC label and graph line | arc_colour = "Blue" |
gpu_colours |
Colour of each GPU's memory label and graph line. Read in order. | gpu_colours = ["Red", "Blue", "Green"] |
Network
These can be set under [styles.network]:
| Config field | Details | Examples |
|---|---|---|
rx_colour |
The colour of the RX (download) label and graph line | rx_colour = "Red" |
tx_colour |
The colour of the TX (upload) label and graph line | tx_colour = "#ffffff" |
rx_total_colour |
The colour of the total RX (download) label in basic mode | rx_total_colour = "0, 0, 0" |
tx_total_colour |
The colour of the total TX (upload) label in basic mode | tx_total_colour = "#000" |
Battery
These can be set under [styles.battery]:
| Config field | Details | Examples |
|---|---|---|
high_battery_colour |
The colour of the battery widget bar when the battery is over 50% | high_battery_colour = "Red" |
medium_battery_colour |
The colour of the battery widget bar when the battery between 10% to 50% | medium_battery_colour = "#ffffff" |
low_battery_colour |
The colour of the battery widget bar when the battery is under 10% | low_battery_colour = "0, 0, 0" |
Tables
These can be set under [styles.tables]:
| Config field | Details | Examples |
|---|---|---|
headers |
Text styling for table headers | headers = { colour = "red", bg_colour = "black", bold = true } |
Graphs
These can be set under [styles.graphs]:
| Config field | Details | Examples |
|---|---|---|
graph_colour |
The general colour of the parts of the graph | graph_colour = "white" |
legend_text |
Text styling for graph's legend text | legend_text = { colour = "black", bg_colour = "blue", bold = true } |
General widget settings
These can be set under [styles.widgets]:
| Config field | Details | Examples |
|---|---|---|
border_colour |
The colour of the widgets' borders | border_colour = "white" |
selected_border_colour |
The colour of a widget's borders when the widget is selected | selected_border_colour = "white" |
widget_title |
Text styling for a widget's title | widget_title = { colour = "black", bg_colour = "blue", bold = true } |
bg_colour |
The background colour of the widgets | bg_colour = "black" |
text |
Text styling for text in general | text = { colour = "black", bg_colour = "blue", bold = true } |
selected_text |
Text styling for text when representing something that is selected | selected_text = { colour = "black", bg_colour = "blue", bold = true } |
disabled_text |
Text styling for text when representing something that is disabled | disabled_text = { colour = "black", bg_colour = "blue", bold = true } |
thread_text |
Text styling for text when representing process thread, only usable on Linux at the moment | thread_text = { colour = "green", bg_colour = "blue", bold = true } |
bar_type |
What to fill bar widgets with (e.g. basic CPU/memory); either "pipe" (default), "block", or "square" |
bar_type = "block" |
Content Configuration Config File Temperature Graph (`docs/content/configuration/config-file/temperature-graph.md`)
Temperature Graph Configuration
The temperature graph widget is configured under [temperature_graph].
Legend Position
The location of the legend can be set with legend_position. Valid values are none, top-left, top, top-right,left, right, bottom-left, bottom, and bottom-right. Defaults to top-right.
[temperature_graph]
legend_position = "top-right"Upper Limit
By default, the y-axis is bounded at 100°C (or the equivalent in the configured temperature unit) and grows
automatically if a reading exceeds that. An explicit upper bound can be set with max_temp (uses the same unit as
the configured temperature unit). Sensor readings above this value will be drawn off the chart.
[temperature_graph]
max_temp = 90.0Filtering Entries
You can filter which sensors to plot by configuring [temperature_graph.sensor_filter]. This works the same way as
the temperature table's filter.
For example, here we are ignoring any sensor that has "cpu" or "wifi" in its name:
[temperature_graph.sensor_filter]
# Whether to ignore any matches. Defaults to true.
is_list_ignored = true
# A list of filters to try and match.
list = ["cpu", "wifi"]
# Whether to use regex. Defaults to false.
regex = false
# Whether to be case-sensitive. Defaults to false.
case_sensitive = false
# Whether to require matching the whole word. Defaults to false.
whole_word = falseContent Configuration Config File Temperature Table (`docs/content/configuration/config-file/temperature-table.md`)
Temperature Table Configuration
The temperature table widget is configured under [temperature].
Default Sort Column
You can customize the default sort column (by default, it sorts by temperature sensor name in ascending order). For example, to sort by temperature:
[temperature]
default_sort = "Temp"You can also set the sort order by changing temperature.sort_order with "Ascending" or "Descending". Defaults to"Ascending":
[temperature]
sort_order = "Ascending"Filtering Entries
You can filter out what entries to show by configuring [temperature.sensor_filter]. In particular you can set a list of things to filter with by setting list, and configure how that list is processed with the other options.
For example, here we are ignoring any sensor that has "cpu" or "wifi" in it.
[temperature.sensor_filter]
# Whether to ignore any matches. Defaults to true.
is_list_ignored = true
# A list of filters to try and match.
list = ["cpu", "wifi"]
# Whether to use regex. Defaults to false.
regex = false
# Whether to be case-sensitive. Defaults to false.
case_sensitive = false
# Whether to require matching the whole word. Defaults to false.
whole_word = falseContent Contribution Development Build Process (`docs/content/contribution/development/build_process.md`)
Build Process
!!! Warning
This section is currently somewhat WIP.!!! Warning
This section is intended for people who wish to work on/build/distribute bottom, not general users.Overview
bottom manages its own binary builds for nightly and stable release purposes. The core build workflow is handled by build_releases.yml, called by a wrapper workflow for nightly and stable releases. Builds take place via GitHub Actions.
The main things built are:
- Binaries for various platforms
- MSI installer for Windows
.debpackage for Debian and its derivatives
This documentation gives a high-level overview of the build process for each part. For the most up-to-date and detailed reference, definitely refer back to the build_releases.yml file.
Binaries
Binaries are built currently for various targets. Note that not all of these are officially supported. The following general steps are performed:
Set up the Rust toolchain for the action runner.
Enable cache.
Build a release build with:
--features deploy, which enables only crates needed for release builds.--lockedto lock the dependency versions.The following env variables set:
BTM_GENERATE: trueCOMPLETION_DIR: "target/tmp/bottom/completion/"MANPAGE_DIR: "target/tmp/bottom/manpage/"
These generate the manpages and shell completions (see Packaging for some more information).
Bundle the binaries and manpage/completions.
Cleanup.
Some builds use cross to do cross-compilation builds for architectures otherwise not natively supported by the runner.
MSI
This builds a full Windows installer using cargo-wix and WiX Toolset 4.
This requires some setup beforehand with some dependencies:
- Net-Framework-Core (handled by Powershell)
- WiX Toolset 4 (needs to be separately installed on GitHub runners as a .NET tool)
- Rust toolchain
After that, cargo wix takes care of the rest.
`.deb`
Currently, .deb files are built for x86 and ARM architectures (armv7, aarch64). This is handled by cargo-deb.
- For x86, this is handled natively with just
cargo-deb. - For ARM, this uses a Docker container, cargo-deb-arm, which correctly sets the dependencies and architecture for the generated
.debfile.
There are additional checks via dpkg to ensure the architecture is correctly set.
Content Contribution Development Deploy Process (`docs/content/contribution/development/deploy_process.md`)
Deploy Process
!!! Warning
This section is currently WIP.!!! Warning
This section is intended for people who wish to work on/build/distribute bottom, not general users.Overview
bottom currently has two main deploy processes to worry about:
Nightly: a daily (00:00 UTC) GitHub action to build binary/installer files, and upload them to the nightly release (example). It can also be triggered manually as either a proper nightly release or a mock release.
Stable: a stable deployment, triggered manually or upon creation of a valid tag. This is a GitHub action that builds binary/installer files and uploads them to a new GitHub release.
Furthermore, this workflow does not handle the following deployments, which must be manually handled:
Nightly
This is, for the most part, automatic, though it can also be used as a way of testing build workflow changes and seeing if binaries can be successfully built at all against all the targets we want to build for.
If one does not want to actually update the nightly release, and just want to test the general builds and workflow, one can run the workflow manually on a branch of choice with "mock" set as the parameter. Changing it to anything else will trigger a non-mock run.
Stable
This can be manually triggered, though the general use-case is setting a tag of the form x.y.z (after checking everything is good, of course). For example:
git tag 0.6.9 && git push origin 0.6.9This will automatically trigger the deployment workflow, and create a draft release with the files uploaded. One still needs to fill in the details and release it.
Furthermore, there are some deployments that are handled by maintainers of bottom that this workflow does not automatically finish. These must be manually handled.
crates.io
Validate everything builds properly and works (you should have done this before releasing though). If good, then deploying on crates.io is as simple as:
cargo publishChocolatey
Upon releasing on GitHub, choco-bottom will automatically be updated with a new PR with the correct deployment files for Chocolatey. Check the PR, merge it if it is correct, then pull locally and deploy following the instructions in the README. Make sure to test installation and running at least once before deploying!
If done correctly, there should be a new build on Chocolatey, which will take some time to validate.
winget
Sometimes, people will kindly do it, but it can also be manually triggered using
winget-bottom.
Note this requires regenerating some secrets.
Content Contribution Development Dev Env (`docs/content/contribution/development/dev_env.md`)
Development Environment
!!! Warning
This section is currently WIP.!!! Warning
This section is intended for people who wish to work on/build/distribute bottom, not general users.Content Contribution Development Logging (`docs/content/contribution/development/logging.md`)
Logging
!!! Warning
This section is currently WIP.!!! Warning
This section is intended for people who wish to work on/build/distribute bottom, not general users.Content Contribution Development Testing (`docs/content/contribution/development/testing.md`)
Testing
!!! Warning
This section is currently WIP.!!! Warning
This section is intended for people who wish to work on/build/distribute bottom, not general users.Content Usage Widgets Battery (`docs/content/usage/widgets/battery.md`)
Battery Widget
!!! Warning
The battery features are unavailable if the binary is compiled with the `battery` feature disabled or if there are no batteries on the system!The battery widget provides information about batteries on the system.
The battery widget can be enabled through either the --battery flag, the battery = true option in a config file, or specifying the widget in a custom layout.
Features
The following data is displayed for batteries:
- Charge percent
- Consumption rate
- Charging state
- Time to empty/charge, based on the current state
- Battery health percent
The battery widget also supports devices with multiple batteries, and you can switch between them using the keyboard or the mouse.
Key bindings
Note that key bindings are generally case-sensitive.
| Binding | Action |
|---|---|
| ++left++ ++h++ ++alt+h++ | Moves to the battery entry to the left of the current one |
| ++right++ ++l++ ++alt+l++ | Moves to the battery entry to the right of the current one |
Mouse bindings
| Binding | Action |
|---|---|
| ++lbutton++ | Selects a battery entry |
Content Usage Widgets Cpu Graph (`docs/content/usage/widgets/cpu-graph.md`)
CPU Widget
The CPU widget displays a visual representation of CPU usage over a time range.
Features
The CPU widget is composed of two parts: the graph and the legend:
- The graph displays the usage data for the currently selected entry as a percentage
- The legend displays all available entries that can be displayed on the graph along with their last recorded use percentage (except for the "All" option)
Users can scroll through the legend using either the keyboard or mouse to select which entry to display on the graph. The "All" option shows every entry
at the same time, though this may get a bit hard to follow if you have a large number of cores/threads.
One can also adjust the displayed time range through either the keyboard or mouse, with a range of 30s to 600s.
Key bindings
Note that key bindings are generally case-sensitive.
Graph
| Binding | Action |
|---|---|
| ++plus++ | Zoom in on chart (decrease time range) |
| ++minus++ | Zoom out on chart (increase time range) |
| ++equal++ | Reset zoom |
Legend
| Binding | Action |
|---|---|
| ++up++ , ++k++ | Move up within a widget |
| ++down++ , ++j++ | Move down within a widget |
| ++g+g++ , ++home++ | Jump to the first entry in the legend |
| ++G++ , ++end++ | Jump to the last entry in the legend |
Mouse bindings
Graph
| Binding | Action |
|---|---|
| ++"Scroll"++ | Scrolling up or down zooms in or out of the graph respectively |
Legend
| Binding | Action |
|---|---|
| ++"Scroll"++ | Scroll through options to display in the graph |
| ++lbutton++ | Selects a CPU thread/average to show in the graph |
Content Usage Widgets Disk Io Graph (`docs/content/usage/widgets/disk-io-graph.md`)
Disk I/O Graph Widget
The disk I/O graph widget shows read and write rates over time.
Features
The legend displays the current reads and writes per second in bytes for each mount/disk item. The y-axis
automatically scales based on shown read/write values. By default this is in a linear scale, but it can be
switched to a logarithmic scale through the config file.
The displayed time range can be adjusted through either the keyboard or mouse.
Key bindings
Note that key bindings are generally case-sensitive.
| Binding | Action |
|---|---|
| ++plus++ | Zoom in on chart (decrease time range) |
| ++minus++ | Zoom out on chart (increase time range) |
| ++equal++ | Reset zoom |
Mouse bindings
| Binding | Action |
|---|---|
| ++"Scroll"++ | Scrolling up or down zooms in or out of the graph respectively |
Content Usage Widgets Disk (`docs/content/usage/widgets/disk.md`)
Disk Widget
The disk widget provides a table of useful disk and partition information, like I/O per second and total usage.
Features
The disk widget provides the following information:
- Disk name
- Disk mount location
- Amount of space used
- Amount of space left
- Total amount of space
- Percentage of space used
- Read per second
- Write per second
Key bindings
Note that key bindings are generally case-sensitive.
| Binding | Action |
|---|---|
| ++up++ , ++k++ | Move up within a widget |
| ++down++ , ++j++ | Move down within a widget |
| ++g+g++ , ++home++ | Jump to the first entry in the table |
| ++G++ , ++end++ | Jump to the last entry in the table |
| ++d++ | Sort by disk, press again to reverse sorting order |
| ++m++ | Sort by mount, press again to reverse sorting order |
| ++u++ | Sort by amount used, press again to reverse sorting order |
| ++n++ | Sort by amount free, press again to reverse sorting order |
| ++t++ | Sort by total space available, press again to reverse sorting order |
| ++p++ | Sort by percentage used, press again to reverse sorting order |
| ++r++ | Sort by read rate, press again to reverse sorting order |
| ++w++ | Sort by write rate, press again to reverse sorting order |
Mouse bindings
| Binding | Action |
|---|---|
| ++lbutton++ | Selects an entry in the table |
Content Usage Widgets Memory Graph (`docs/content/usage/widgets/memory-graph.md`)
Memory Widget
The memory widget provides a visual representation of RAM and swap usage over time.
Features
The legend displays the current usage in terms of percentage and actual usage in binary units (KiB, MiB, GiB, etc.).
If the total RAM or swap available is 0, then it is automatically hidden from the legend and graph.
One can also adjust the displayed time range through either the keyboard or mouse, with a range of 30s to 600s.
This widget can also be configured to display Nvidia and AMD GPU memory usage (--disable_gpu on Linux/Windows to disable) or cache memory usage (--enable_cache_memory).
Key bindings
Note that key bindings are generally case-sensitive.
| Binding | Action |
|---|---|
| ++plus++ | Zoom in on chart (decrease time range) |
| ++minus++ | Zoom out on chart (increase time range) |
| ++equal++ | Reset zoom |
Mouse bindings
| Binding | Action |
|---|---|
| ++"Scroll"++ | Scrolling up or down zooms in or out of the graph respectively |
How are memory values determined?
Linux
Memory usage is calculated using the following formula based on values from /proc/meminfo (based on htop's implementation):
MemTotal - MemFree - Buffers - (Cached + SReclaimable - Shmem)You can find more info on /proc/meminfo and its fields here.
Windows
In Windows, we calculate swap by querying Get-Counter "\Paging File(*)\% Usage". This
is also what some libraries like psutil use. However, note there are also a few other valid methods of
representing "swap" in Windows (e.g. using GetPerformanceInfo), which all slightly don't
match.
Content Usage Widgets Network Graph (`docs/content/usage/widgets/network-graph.md`)
Network Widget
The network widget provides a visual representation of network input and output per second, as well as noting the total amount
received and transmitted.
Features
The legend displays the current reads and writes per second in bits, as well as the total amount read/written.
The y-axis automatically scales based on shown read/write values, and by default, is a linear scale based on base-10 units (e.x. kilobit, gigabit, etc.).
Through configuration, the read/write per second unit can be changed to bytes, while the y-axis can be changed to a
log scale and/or use base-2 units (e.x. kibibit, gibibit, etc.).
One can also adjust the displayed time range through either the keyboard or mouse, with a range of 30s to 600s.
Key bindings
Note that key bindings are generally case-sensitive.
| Binding | Action |
|---|---|
| ++plus++ | Zoom in on chart (decrease time range) |
| ++minus++ | Zoom out on chart (increase time range) |
| ++equal++ | Reset zoom |
Mouse bindings
| Binding | Action |
|---|---|
| ++"Scroll"++ | Scrolling up or down zooms in or out of the graph respectively |
Content Usage Widgets Process (`docs/content/usage/widgets/process.md`)
Process Widget
The process widget displays a table containing information regarding a running process, along with sorting,
searching, and process control features.
Features
The process widget has three main components:
- The main process table
- The search sub-widget (opened with ++ctrl+f++ or ++slash++)
- The sort menu sub-widget (opened with ++s++ or ++f6++)
By default, the main process table displays the following information for each process:
PID
Name of the process
CPU use percentage (note this is averaged out per available thread by default)
Memory use percentage
Disk reads per second
Disk writes per second
Total amount read from disk
Total amount written from disk
User
Process state
Process uptime
!!! info indent
textOn Windows, the I/O counters will report _all_ reads/writes, not just disk. See [here](https://docs.rs/sysinfo/latest/sysinfo/struct.Process.html#method.disk_usage) for more details.
With the feature flag (--disable_gpu on Linux/Windows to disable) and gpu process columns enabled in the configuration:
- GPU memory use percentage
- GPU core utilization percentage
See the processes configuration page on how to customize which columns
are shown.
Sorting
The table can be sorted by clicking on the table headers, which will either sort the table by that column, or if already
sorting by that column, reverse the sorting order.
Alternatively, one can sort using the sort menu sub-widget, which is brought up using ++s++ or ++f6++, and can be controlled by arrow keys or the mouse.
Grouping
Pressing ++tab++ in the table will group entries with the same name together. The PID column will be replaced with the number of entries in each group, and usage
is added together when displayed.
!!! Info
Note that the process state and user columns are disabled in this mode.!!! Info
Note that if tree mode is also active, processes cannot be grouped together due to the behaviour of the two modes
somewhat clashing. This also reflects with default modes like `group_processes`.Process termination
Pressing ++d+d++ or ++f9++ will allow you to terminate the currently selected process/process group. On Unix-like
operating systems, you are also able to control which specific signals to send (e.g. SIGKILL, SIGTERM).
<figcaption><sub>The process termination menu on Linux</sub></figcaption>If you're on Windows, or if the disable_advanced_kill flag is set in the options or command-line (only available on
Linux, macOS, and FreeBSD), then a simpler termination screen with just yes or no options will be shown.
<figcaption><sub>The process termination menu on Windows</sub></figcaption>Tree mode
Pressing ++t++ or ++f5++ in the table toggles tree mode in the process widget, displaying processes in regard to their parent-child process relationships.
A process in tree mode can also be "collapsed", hiding its children and any descendants, using the either the ++minus++,
++plus++, or ++left++ keys, or clicking on an entry. It can be expanded by using the ++minus++, ++plus++, or ++right++
keys, or by clicking on the entry again. The ++space++ key can also be used to toggle between the collapsed and expanded states.
!!! Info
Note that if tree mode is active, processes cannot be grouped together due to the behaviour of the two modes
somewhat clashing. This also reflects with default modes like `group_processes`.Full command
You can show the full command instead of just the process name by pressing ++P++.
Search
Pressing ++slash++ or ++ctrl+f++ will open up the search sub-widget. By default, just typing in something will search by the process name.
This search can be further enhanced by matching by case, matching the entire word, or by regex.
We are able to also search for multiple things/conditions.
And if our search uses a keyword, we need to use quotation marks around the term to properly search it.
Lastly, we can refine our search even further based on the other columns, like PID, CPU usage, etc., as well as grouping together conditions.
You can also paste search queries (e.g. ++shift+insert++, ++ctrl+shift+v++).
Keywords
Note all keywords are case-insensitive. To search for a process/command that collides with a keyword, surround the term with quotes (e.x. "cpu").
| Keywords | Example | Description |
|---|---|---|
btm |
Matches by process or command name; supports regex | |
pid |
pid=1044 |
Matches by PID; supports regex |
cpu cpu% |
cpu > 0.5 |
Matches the CPU column; supports comparison operators |
memb |
memb > 1000 b |
Matches the memory column in terms of bytes; supports comparison operators |
mem mem% |
mem < 0.5 |
Matches the memory column in terms of percent; supports comparison operators |
read r/s rps |
read = 1 mb |
Matches the read/s column in terms of bytes; supports comparison operators |
write w/s wps |
write >= 1 kb |
Matches the write/s column in terms of bytes; supports comparison operators |
tread t.read |
tread <= 1024 gb |
Matches the total read column in terms of bytes; supports comparison operators |
twrite t.write |
twrite > 1024 tb |
Matches the total write column in terms of bytes; supports comparison operators |
user |
user=root |
Matches by user; supports regex |
state |
state=running |
Matches by state; supports regex |
() |
(<COND 1> AND <COND 2>) OR <COND 3> |
Group together a condition |
gmem |
gmem > 1000 b |
Matches the gpu memory column in terms of bytes; supports comparison operators |
gmem% |
gmem% < 0.5 |
Matches the gpu memory column in terms of percent; supports comparison operators |
gpu% |
gpu% > 0 |
Matches the gpu usage column in terms of percent; supports comparison operators |
Comparison operators
| Keywords | Description |
|---|---|
= |
Checks if the values are equal |
!= |
Checks if the values are not equal |
> |
Checks if the left value is strictly greater than the right |
< |
Checks if the left value is strictly less than the right |
>= |
Checks if the left value is greater than or equal to the right |
<= |
Checks if the left value is less than or equal to the right |
Logical operators
Note all operators are case-insensitive, and the and operator takes precedence over the or operator.
| Keywords | Usage | Description |
|---|---|---|
and && <Space> |
<COND 1> and <COND 2> <COND 1> && <COND 2> <COND 1> <COND 2> |
Requires both conditions to be true to match |
or || |
<COND 1> or <COND 2> <COND 1> || <COND 2> |
Requires at least one condition to be true to match |
! |
!<COND> !(<COND 1> or <COND 2>) |
Inverts the following condition or group |
! is reserved as an operator, so it cannot appear bare as a value. To match a literal ! in a name or string field, quote it — e.g. "foo!" or user = "!". A bare ! with nothing parseable after it (such as user = ! or ! on its own) is rejected.
Units
All units are case-insensitive.
| Keywords | Description |
|---|---|
B |
Bytes |
KB |
Kilobytes |
MB |
Megabytes |
GB |
Gigabytes |
TB |
Terabytes |
KiB |
Kibibytes |
MiB |
Mebibytes |
GiB |
Gibibytes |
TiB |
Tebibytes |
Key bindings
Note that key bindings are generally case-sensitive.
Process table
| Binding | Action |
|---|---|
| ++up++ , ++k++ | Move up within a widget |
| ++down++ , ++j++ | Move down within a widget |
| ++g+g++ , ++home++ | Jump to the first entry in the table |
| ++G++ , ++end++ | Jump to the last entry in the table |
| ++d+d++ , ++f9++ | Send a kill signal to the selected process |
| ++c++ | Sort by CPU usage, press again to reverse sorting order |
| ++m++ | Sort by memory usage, press again to reverse sorting order |
| ++p++ | Sort by PID name, press again to reverse sorting order |
| ++n++ | Sort by process name, press again to reverse sorting order |
| ++tab++ | Toggle grouping processes with the same name |
| ++P++ | Toggle between showing the full command or just the process name |
| ++ctrl+f++ , ++slash++ | Toggle showing the search sub-widget |
| ++s++ , ++f6++, ++delete++ (++fn+delete++ on macOS) | Toggle showing the sort sub-widget |
| ++I++ | Invert the current sort |
| ++"%"++ | Toggle between values and percentages for memory usage |
| ++t++ , ++f5++ | Toggle tree mode |
| ++M++ | Sort by gpu memory usage, press again to reverse sorting order |
| ++C++ | Sort by gpu usage, press again to reverse sorting order |
| ++z++ | Toggle the hiding of kernel threads |
Sort sub-widget
| Binding | Action |
|---|---|
| ++up++ , ++k++ | Move up within a widget |
| ++down++ , ++j++ | Move down within a widget |
| ++g+g++ , ++home++ | Jump to the first entry in the table |
| ++G++ , ++end++ | Jump to the last entry in the table |
| ++esc++ | Close the sort sub-widget |
| ++enter++ | Sorts the corresponding process table |
Search sub-widget
| Binding | Action |
|---|---|
| ++left++ ++h++ ++alt+h++ | Moves the cursor left |
| ++right++ ++l++ ++alt+l++ | Moves the cursor right |
| ++esc++ | Close the search widget (retains the filter) |
| ++ctrl+a++ | Skip to the start of the search query |
| ++ctrl+e++ | Skip to the end of the search query |
| ++ctrl+u++ | Clear the current search query |
| ++ctrl+w++ | Delete a word behind the cursor |
| ++ctrl+h++ | Delete the character behind the cursor |
| ++backspace++ | Delete the character behind the cursor |
| ++delete++ (++fn+delete++ on macOS) | Delete the character at the cursor |
| ++alt+c++ , ++f1++ | Toggle matching case |
| ++alt+w++ , ++f2++ | Toggle matching the entire word |
| ++alt+r++ , ++f3++ | Toggle using regex |
Mouse bindings
Process table
| Binding | Action |
|---|---|
| ++"Scroll"++ | Selects a CPU thread/average to show in the graph |
| ++lbutton++ | Table header: Sorts/reverse sorts the table by the column Table entry: Selects an entry in the table, if in tree mode, collapses/expands the entry's children |
Sort sub-widget
| Binding | Action |
|---|---|
| ++lbutton++ | Selects an entry in the table |
Content Usage Widgets Temperature Graph (`docs/content/usage/widgets/temperature-graph.md`)
Temperature Graph Widget
The temperature graph widget provides temperature readings over time.
Features
Each detected sensor is drawn as its own line. The y-axis is in the configured temperature unit (Celsius by default;
see the --celsius/--fahrenheit/--kelvin arguments or flags.temperature_type config option).
By default the y-axis is bounded at 100°C (or the equivalent in the configured unit) and grows automatically.
An upper bound can also be set explicitly via the config file.
The displayed time range can be adjusted through either the keyboard or mouse.
Key bindings
Note that key bindings are generally case-sensitive.
| Binding | Action |
|---|---|
| ++plus++ | Zoom in on chart (decrease time range) |
| ++minus++ | Zoom out on chart (increase time range) |
| ++equal++ | Reset zoom |
Mouse bindings
| Binding | Action |
|---|---|
| ++"Scroll"++ | Scrolling up or down zooms in or out of the graph respectively |
Content Usage Widgets Temperature Table (`docs/content/usage/widgets/temperature-table.md`)
Temperature Widget
The temperature widget provides a table of temperature sensors and their current temperature.
Features
The temperature widget provides the sensor name as well as its current temperature.
This widget can also be configured to display Nvidia and AMD GPU temperatures (--disable_gpu on Linux/Windows to disable).
Key bindings
Note that key bindings are generally case-sensitive.
| Binding | Action |
|---|---|
| ++up++ , ++k++ | Move up within a widget |
| ++down++ , ++j++ | Move down within a widget |
| ++g+g++ , ++home++ | Jump to the first entry in the table |
| ++G++ , ++end++ | Jump to the last entry in the table |
| ++t++ | Sort by temperature, press again to reverse sorting order |
| ++s++ | Sort by sensor name, press again to reverse sorting order |
Mouse bindings
| Binding | Action |
|---|---|
| ++lbutton++ | Selects an entry in the table |
--- METRICS ---
- Files Extracted: 44
- Estimated Token Budget: ~45337 tokens
- Canonical Reference: https://codewiki.google/github.com/ClementTsang/bottom