Linux QoS Management with HTB Queuing Discipline
This article provides an overview of how the Linux kernel regulates
network traffic using the Hierarchical Token Bucket (HTB) queuing
discipline (qdisc). It explains the fundamental mechanics of the Traffic
Control (tc) subsystem, details the relationship between
classes, tokens, and filters, and explores how HTB enforces guaranteed
bandwidth, manages bursts, and enables dynamic bandwidth sharing across
a structured hierarchy.
The Linux Traffic Control Architecture
Linux manages Quality of Service (QoS) through its Traffic Control
(tc) subsystem. This framework sits between the network
protocol stack and the network interface card (NIC). The subsystem is
built on three core components:
- Queuing Disciplines (qdiscs): Algorithms that schedule, delay, or drop outbound packets.
- Classes: Logical partitions within a classful qdisc that define distinct traffic tiers and bandwidth allocations.
- Filters (Classifiers): Rules (such as
u32or firewall mark matches) that inspect packet headers and route traffic into specific classes.
HTB is a classful qdisc, meaning it allows administrators to create complex parent-child tree structures to control bandwidth allocation across different services, users, or protocols.
The Token Bucket Mechanism
At the heart of HTB is the token bucket algorithm. Bandwidth allocation is modeled by a virtual bucket that continuously collects tokens at a specified byte rate:
- Token Generation: The system adds tokens to a class bucket at a constant rate corresponding to the configured bandwidth.
- Packet Transmission: When a packet arrives, the scheduler checks if the bucket contains enough tokens to match the packet's size in bytes.
- Queueing vs. Transmission: If sufficient tokens exist, the tokens are deducted and the packet transmits immediately. If insufficient tokens exist, the packet waits in a queue until enough tokens accumulate, smoothing bursts into a sustained rate.
Class Hierarchy and Bandwidth Allocation Parameters
HTB organizes traffic into a tree where internal nodes distribute capacity and leaf nodes contain actual packet queues. Each class is configured with two primary bandwidth metrics:
rate(Guaranteed Bandwidth): The minimum bandwidth guaranteed to the class at all times, even under full network saturation.ceil(Ceiling Bandwidth): The absolute maximum bandwidth the class is permitted to consume if excess capacity is available.
Dynamic Bandwidth Sharing and Borrowing
The primary advantage of HTB over older shapers is its ability to
loan unused bandwidth. If a class does not fully utilize its guaranteed
rate, its surplus tokens become available to sibling
classes within the same parent node.
When a leaf class experiences heavy traffic exceeding its
rate, it requests tokens from its parent. The parent
redistributes the idle bandwidth to the requesting child, allowing it to
burst up to its configured ceil. Once the idle sibling
requires its guaranteed bandwidth again, the borrowing class is
throttled back down to its base rate.
Packet Classification and Priority
To manage how excess capacity is divided among competing classes, HTB
uses a priority system (prio parameter):
- Classification: Network filters match traffic based on IP addresses, ports, or DSCP/ToS bits and assign each packet to a specific leaf class.
- Prioritization During Congestion: When multiple classes compete to borrow spare bandwidth, HTB allocates tokens to the class with the lowest numerical priority value first. High-priority traffic (such as VoIP or SSH) obtains available borrowing capacity before bulk transfers (such as HTTP or backups).
Through this combination of token rate limits, strict tree hierarchies, and priority-driven borrowing, HTB allows Linux to enforce precise rate limits while maximizing link utilization.