Skip to content

Terminal UI (TUI)

Bandwidth Manager ships with a fully interactive terminal interface for real-time monitoring. No browser, no Grafana — just open a terminal and run bandwidth top.

Launching

bash
bandwidth top [--interval <seconds>]
OptionDefaultDescription
--interval2Poll interval in seconds (minimum 0.5)

The TUI connects to the running daemon. If the daemon isn't running, it will offer to start it:

$ bandwidth top
✘ Daemon not running. Start it now? [Y/n]: y
✔ Daemon started — connecting…

Keyboard Shortcuts

Mnemonics

Most shortcuts mirror tools you already know: j/k from Vim, g/G from less, q from everything.

KeyAction
Move selection up/down in the interface list
j kVim-style: move selection down/up
gJump to top of interface list
GJump to bottom of interface list

Panel Focus

KeyAction
hFocus left panel (interfaces)
lFocus right panel (graph)

Filtering & Sorting

KeyAction
TabOpen the filter/search bar
sCycle sort order: namerxtxlimit %

Filter syntax inside the search bar:

eth          → filter by interface name containing "eth"
>50mbps      → show only interfaces exceeding 50 Mbps
!docker      → exclude entries containing "docker"

Press Esc to clear the filter.

Time Window

KeyPeriod
11 minute
55 minutes
t15 minutes
d1 day

The graph and stats panel update to reflect the selected window. A longer window smooths spikes; a shorter one reveals bursts.

Global

KeyAction
qQuit (or Ctrl+C)
?Show the help overlay

Layout

The TUI is divided into four sections:

┌── 1. Header ──────────────────────────────────────────────────────┐
│  Bandwidth Manager · live · 2s interval · 2026-06-30 09:18 UTC   │
├── 2. Speed Bar ───────────────────────────────────────────────────┤
│  ██████████████████████████████████████░░░░░░░░░░░░░░  312 Mbps  │
├──────────────────────────────┬────────────────────────────────────┤
│  3. Left Panel (35%)         │  4. Right Panel (65%)              │
│  ┌─ Interfaces ────────────┐ │  ┌─ web-app ────────────────────┐ │
│  │ ● eth0     142 Mbps     │ │  │ ╭── RX ───╮                 │ │
│  │ ● docker0   98 Mbps     │ │  │ │███████░░│ 8.2 Mbps        │ │
│  │ ● wg0       52 Mbps     │ │  │ ╰─────────╯                 │ │
│  │   …                     │ │  │ ╭── TX ───╮                 │ │
│  └─────────────────────────┘ │  │ │███░░░░░░│ 2.1 Mbps        │ │
│                              │  │ ╰─────────╯                 │ │
│                              │  │ Avg:      31.4 Mbps          │ │
│                              │  │ 95%ile:   45.2 Mbps          │ │
│                              │  │ Peak:     49.8 Mbps          │ │
│                              │  │ Total:    142.3 GB            │ │
│                              │  └──────────────────────────────┘ │
├──────────────────────────────┴────────────────────────────────────┤
│  5. Bottom Bar                                                     │
│  q:Quit  s:Sort  tab:Filter  1/5/t/d:Period  ↑↓:Nav  ←→:Panels   │
└────────────────────────────────────────────────────────────────────┘

1. Header

Shows the application name, current mode (live or paused), poll interval, and local time. If the daemon connection drops, the mode changes to reconnecting… in yellow.

2. Speed Bar

A horizontal bar representing total bandwidth across all interfaces. The bar fills proportionally to the highest limit configured. Colors follow the speed-based scheme so you can spot saturation at a glance.

3. Left Panel — Interface List (35%)

Lists every managed interface with its current total throughput. The selected interface is highlighted with a marker. Each entry shows:

  • Interface name
  • Current combined RX+TX throughput
  • Status indicator: green dot (under limit), yellow (approaching), red (at limit)

The list scrolls when there are more interfaces than fit on screen.

4. Right Panel — Graph + Stats (65%)

Displays detailed information for the selected interface, split into two sub-panels:

Graph (top half): A real-time ASCII/braille chart of inbound and outbound traffic over the selected time window.

Stats (bottom half): Numerical summaries computed from the visible data.

5. Bottom Bar

A condensed reminder of all active shortcuts. The currently focused panel's shortcuts are brighter; inactive ones dim.


Graph Details

The graph uses braille characters (Unicode U+2800U+28FF) to render high-density time-series data. Each braille cell encodes 2×4 dots, providing 8 data points per character — far denser than block-character charts.

Color Legend

ColorMeaningVisual
GreenRX (inbound)⣿⣿⣿⣿⣿⣿⣿⣀⣀
RedTX (outbound)⣿⣿⣿⣀⣀⣀⣀⣀⣀
OrangeOverlap (RX+TX)⣿⣿⣿⣿⣿⣿⣿⣿⣿

When RX and TX values overlap at the same time point, the merged cell renders in orange to indicate both directions are active. This is common on symmetric connections or during request-response cycles.

Reading the Graph

 ╭── RX ───╮
 │⣿⣿⣿⣿⣿⣀⣀⣀⣀⣀│ 12.3 Mbps
 ╰─────────╯
 ╭── TX ───╮
 │⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿│ 24.1 Mbps  ← notice: more filled cells
 ╰─────────╯
  • Left edge = oldest data point in the time window
  • Right edge = most recent sample
  • Dense fill () = higher throughput at that moment
  • Sparse fill () = lower throughput
  • Empty () = zero or near-zero

Graph Controls

While the right panel is focused ( or l):

KeyAction
Scroll graph history (if paused)
SpacePause/resume live updates

When paused, a ⏸ PAUSED indicator appears in the header, and you can scroll back through historical data up to the daemon's in-memory buffer (typically 24 hours).


Stats Panel

The stats panel shows four key metrics for the selected interface across the active time window:

Average (Avg)

The arithmetic mean of all samples in the window — smoothed but may hide short bursts.

Avg: 31.4 Mbps

95th Percentile (95%ile)

95% of all samples fall below this value. This is the most useful metric for capacity planning — it filters out rare spikes while capturing sustained load.

95%ile: 45.2 Mbps

Why 95th percentile?

ISPs and cloud providers often bill on 95th percentile. If your container bursts to 500 Mbps for 2 minutes but sits at 50 Mbps the rest of the hour, the 95th percentile will read ~52 Mbps — far more representative than the average.

Peak

The single highest sample in the window. Useful for identifying burst events but not for setting limits (you'd over-provision).

Peak: 49.8 Mbps

Total Transferred

Cumulative bytes transferred (RX + TX) over the window. Displayed in human-readable units (KB → MB → GB → TB).

Total: 142.3 GB

Color Coding

Interface list entries and graph segments are color-coded by current throughput. The thresholds are configurable via bandwidth configure set tui.thresholds.<level> <mbps>.

ColorRangeMeaning
Green< 10 MbpsLight traffic, well within limits
Yellow10–100 MbpsModerate traffic, normal operation
Orange100–500 MbpsHeavy traffic, approaching capacity
Red> 500 MbpsSaturated, likely dropping packets

These colors apply to:

  • Interface list entries in the left panel
  • Individual bars/cells in the graph
  • The aggregate speed bar (uses the highest interface's color)

Color-blind accessibility

If the default palette is hard to distinguish, set tui.color_scheme: deuteranopia or tui.color_scheme: monochrome in your config. The monochrome scheme uses character density instead of hue.


Mouse Support

The TUI has full mouse support. No configuration needed — it works if your terminal supports it (most do).

ActionEffect
ClickSelect an interface in the left panel
ScrollScroll the interface list or graph history
Click buttonsActivate bottom-bar shortcuts
DragNot used (no action)

Mouse events are handled through standard SGR extended mouse mode. If you prefer keyboard-only, mouse input doesn't interfere.

Disabling mouse

Set tui.mouse: false in your config if your terminal multiplexer (tmux, screen) has conflicting mouse bindings.


Terminal Requirements

The TUI uses advanced terminal features and works best in modern terminal emulators.

TerminalTrue ColorBrailleMouseNotes
KittyNative image support too
WezTermCross-platform
iTerm2 (macOS)Enable "Use Unicode version 9+ widths"
Windows TerminalWorks out of the box
AlacrittyLightweight, fast
foot (Wayland)Minimal, Wayland-native

Partial Support

TerminalIssueWorkaround
tmuxTrue color requires set -g default-terminal "tmux-256color" and set -ga terminal-overrides ",*:Tc"Add to tmux.conf
GNOME TerminalBraille may render with gapsSwitch to a braille-friendly font like Iosevka or JuliaMono
PuTTYNo braille supportUse tui.graph_style: blocks in config
macOS Terminal.appNo true colorUpgrade to iTerm2 or Kitty

Fonts

The braille graph requires a font with good Unicode Braille Patterns coverage (U+2800U+28FF). Most modern monospace fonts work:

  • Iosevka (excellent braille rendering)
  • JuliaMono (designed for scientific/terminal use)
  • JetBrains Mono (good coverage, slight gaps on some sizes)
  • Cascadia Code (works, but braille dots can be small)

Fallback Mode

If your terminal doesn't support braille or true color, Bandwidth Manager detects this and falls back:

# Fallback graph (block characters, 256 colors)
│ RX: ███████▌░░░░░░░░░░ 8.2 Mbps
│ TX: ███░░░░░░░░░░░░░░░ 2.1 Mbps

Set tui.graph_style: blocks to force this mode permanently. It uses fewer data points but works everywhere.


Troubleshooting the TUI

"The graph looks like random dots" Your font doesn't render braille characters properly. Install Iosevka or JuliaMono, or set tui.graph_style: blocks.

"Colors are all white/gray" Your terminal doesn't support true color. Set tui.color_mode: 256 to use 256-color mode, or tui.color_mode: 16 for basic ANSI.

"The TUI is flickering" Reduce the poll interval: bandwidth top --interval 5. Some terminals struggle to repaint faster than 2 FPS.

"Mouse clicks do nothing" Ensure your terminal has mouse reporting enabled. In tmux, add set -g mouse on to your config.

"The bottom bar is cut off" Your terminal window is too small. Resize to at least 80×24 characters. Below that, the TUI switches to a minimal mode.