# Bandwidth Usage Display For entitlements with a limited monthly data allowance, the panel shows how much VPN data the user has left. This page documents the rules that decide **which unit** the remaining amount is shown in (GB vs. MB) and **how it is rounded** (whole number vs. one decimal place). > Bandwidth usage is displayed when `browser.ipProtection.bandwidth.enabled` is set to `true`. The formatting logic lives in `formatRemainingBandwidth` in `browser/components/ipprotection/content/ipprotection-utils.mjs`. The `bandwidth-usage` custom element (`browser/components/ipprotection/content/bandwidth-usage.mjs`) consumes it to build the progress bar and numeric strings. Unit conversions rely on the `BANDWIDTH` constants in `browser/components/ipprotection/content/ipprotection-constants.mjs`. ## Units are binary Conversions use binary (power-of-two) multiples, even though the UI labels them `GB` and `MB`: - `BANDWIDTH.BYTES_IN_GB` is `2^30` (1 GiB). - `BANDWIDTH.BYTES_IN_MB` is `2^20` (1 MiB). All raw bandwidth values (`remaining`, `max`) are handled as `BigInt` byte counts sourced from the usage payload. ## Remaining data: GB vs. MB `formatRemainingBandwidth(remainingBytes)` returns `{ value, useGB }`. The unit is chosen from the remaining amount alone: - **1 GB or more remaining** → `useGB: true`. The value is shown in GB, rounded to **one decimal place** and formatted with `Intl.NumberFormat` (`maximumFractionDigits: 1`), so it is locale-aware and drops trailing zeros (`30`, not `30.0`; `12.5` stays `12.5`). - **Less than 1 GB remaining** → `useGB: false`. The value switches to MB and is shown as a **floored whole number** of MB (`Math.floor(remainingBytes / BYTES_IN_MB)`), with no decimals. The `useGB` flag selects the localized string, so the unit in the text always matches the unit of the value: | Context | `useGB: true` (GB) | `useGB: false` (MB) | | --- | --- | --- | | Progress bar description | `ip-protection-bandwidth-left-gb-1` | `ip-protection-bandwidth-left-mb-1` | | Numeric-only view | `ip-protection-bandwidth-left-this-month-gb` | `ip-protection-bandwidth-left-this-month-mb` | ### Examples - `12.5 GB` remaining → `"12.5"` GB. - `30 GB` remaining → `"30"` GB (no decimal, because the fractional part is zero). - `0.9 GB` remaining → `921` MB (floored: `floor(0.9 * 1024)`). ## The monthly limit is always in GB The maximum (`maxUsage`) shown alongside the remaining amount — and in the header, help text, "limit reached", and reset strings — is **always expressed in GB**, regardless of how much data is left. It is computed as `maxGB = max / BYTES_IN_GB` and passed straight through without rounding. The default monthly limit is `browser.ipProtection.bandwidth.maxInGb` (50 GB). This is why a user near the end of their allowance sees a mixed-unit string such as `500 MB of 50 GB left this month`: the remaining amount has dropped below 1 GB and switched to MB, but the limit stays in GB. When the allowance is exhausted (`remaining <= 0`), the numeric text is replaced by `ip-protection-bandwidth-hit-for-the-month`, which reports only the limit (in GB). ## Progress bar value The `` element measures **used** data, not remaining, and is always expressed in GB: - `max` is `maxGB`. - `value` is `bandwidthUsedGB` (`(max - remaining) / BYTES_IN_GB`) rounded to one decimal via `parseFloat(...toFixed(1))`. The separate `percent` attribute is **bucketed** rather than exact, so styling can react to thresholds without exposing precise usage. `bandwidthPercent` returns: - `90` when used is at or above 90%, - `75` when used is at or above 75% (but below 90%), - otherwise `Math.floor(percent)`.