ratatop: the network box, and why your ISP lies with units Maneshwar, a developer building git-lrc, a Micro AI code reviewer, has implemented the network box for a btop-style system monitor in Rust using ratatui. The feature displays both bits and bytes per second to avoid ISP unit confusion, uses three-significant-figure formatting to prevent layout shifts, and mirrors the upload graph for a unified visual. The project is open source on GitHub. Hello, I'm Maneshwar. I'm building git-lrc, a Micro AI code reviewer that runs on every commit. It is free and source-available on Github. Star git-lrc to help devs discover the project. Do give it a try and share your feedback. Day four of building a btop-style system monitor in Rust with ratatui https://ratatui.rs . CPU, memory, disks are done. Today the network box lands, which means three of btop's four boxes are up. Three things in there took actual thought. The unit situation, the shared scale, and the fact that the upload graph is upside down on purpose. Look at that first row again. ▼ 566 Byte/s 4.42 Kibps Same number. Twice. Different units. btop does this deliberately, and once you notice why, you cannot unsee it. Your ISP sells you bandwidth in bits per second. 100 Mbps, 300 Mbps, whatever the sticker says. Your download manager, your browser, and every file transfer you have ever watched report progress in bytes per second. The factor between them is 8. So the "100 Mbps" plan you pay for tops out around 12.5 MB/s in the progress bar, and every few months someone concludes their internet is broken when it is in fact working exactly as sold. btop refuses to pick a side. It shows both, so you can compare against your plan and against your download at the same time without doing mental arithmetic. The conversion in code is unremarkable, which is the point: php fn format bits bytes per sec: f64 - String { const UNITS: &str; 4 = "bps", "Kibps", "Mibps", "Gibps" ; let value, unit = scale bytes per sec 8.0, 1024.0, UNITS.len ; let decimals = decimals value, unit ; format " {value:.decimals$} {} ", UNITS unit } Note Kibps and not Kbps . Dividing by 1024 gives you kibibits; dividing by 1000 gives you kilobits. btop uses 1024, so the label has to say so. Getting this wrong is a 2.4% error that nobody would ever notice and that would still be wrong. Small thing I got wrong and had to fix. My first version formatted rates with a fixed two decimals. Perfectly reasonable, and it produced this: ▼ Top: 4.42 Kibps ▼ Top: 43.80 Kibps ▼ Top: 438.00 Kibps The number changes width as traffic grows, so the whole column shuffles sideways every time the value crosses a power of ten. In a display that redraws twice a second, that is genuinely distracting. The fix is the same three-significant-figure rule the memory box already used: php fn decimals value: f64, unit: usize - usize { if unit == 0 || value = 100.0 { 0 } else if value = 10.0 { 1 } else { 2 } } 4.42 , 43.8 , 438 . Always three digits. Always the same width. This is the second time in this project I have written that exact function, which is usually a sign it should be shared. For now it lives in both places because the memory box counts bytes and this one counts bits, and I would rather have two small honest copies than one abstraction that takes four parameters to explain itself. The two graphs on the left are download on top and upload underneath, and the bottom one is mirrored: it hangs from its top edge and grows downward. flowchart TD subgraph BOX " " D "download graph