The ticket came in on a Monday: "phone calls break up whenever someone uploads backups". The link graph showed a serene 40% average utilization, and the manager asked — quite reasonably — what the 100 Mbps he paid for was doing. Here's the catch: averages are measured in minutes, congestion happens in milliseconds. One 30 ms burst that fills the egress queue is enough to make a voice packet miss its appointment. That's where QoS comes in, and let's get one thing straight up front: QoS doesn't add a single bit to your link. It's triage.
QoS doesn't manufacture bandwidth
Think of a hospital emergency room. Triage doesn't build operating rooms or hire doctors: it decides who goes first when there isn't enough for everyone. QoS is exactly that for a network interface: when more packets arrive than the wire can carry, somebody has to wait in the queue — or get dropped — and QoS picks who takes the hit. Nothing more, and nothing less.
Two uncomfortable truths follow. One: without congestion, QoS does nothing. With an empty queue, the packet marked as gold and the packet marked as coal leave equally fast; your elegant policy is pure decoration. Two: if the link is congested around the clock, QoS is anesthesia, not a cure — voice will sound pristine while everything else starves, and the real fix is more bandwidth. QoS earns its keep in the middle ground: links that have plenty on average but suffer microbursts. Which is exactly where 90% of real networks live.
DSCP: the sticker on the packet's forehead
To discriminate with any sense, you first have to label. The IPv4 header carries a byte that was born as "Type of Service" and is now the DiffServ field: its top 6 bits are the DSCP (Differentiated Services Code Point) and the remaining 2 are ECN, which is a different movie. Six bits give you 64 possible values, but in practice four of them pay the rent:
| Class | DSCP | Binary | ToS byte | Use it for |
|---|---|---|---|---|
| EF | 46 | 101110 | 0xB8 | RTP voice: small, sacred, delay-sensitive |
| AF41 | 34 | 100010 | 0x88 | interactive video (video calls, telepresence) |
| CS0 | 0 | 000000 | 0x00 | best effort: web, mail, almost everything |
| CS1 | 8 | 001000 | 0x20 | scavenger: backups, updates, the expendable stuff |
EF (Expedited Forwarding) is for traffic that would rather die than arrive late: voice. AF41 gives interactive video a bandwidth guarantee without the voice-grade VIP pass. CS0 is the ordinary citizen. And CS1 — the scavenger class — is the most underrated item in the catalog: mark your backups and OS updates with it and they can hog the entire link at 3 AM, yet yield every last bit the moment somebody else needs it. Sometimes the best QoS isn't promoting voice: it's demoting the backup.
To see the marking live, a tcpdump is all you need: the ToS byte shows up on every packet.
$ sudo tcpdump -n -v -c1 udp portrange 16384-32767
IP (tos 0xb8, ttl 63, id 4211, offset 0, proto UDP (17), length 200)
10.1.20.14.16402 > 10.1.9.7.16388: UDP, length 172 That tos 0xb8 is EF wearing a different haircut: 46 shifted two bits left (46 × 4 = 184 = 0xB8). All the conversions between DSCP, ToS, binary and class names — with the 21 standard classes — live in the DSCP / QoS calculator.
The boundary: trust or remark
Anyone can slap on a sticker. If your policy says "EF goes first", nothing stops a PC with a "gaming-optimized" network driver from marking its packets EF and cutting in line ahead of your phones. That's why every serious network defines a trust boundary: at the access port you decide whether to believe incoming marks or rewrite them. Corporate IP phone? Trusted. User laptop? Thanks for playing: everything to CS0, and if it carries known voice or video traffic, you re-mark it yourself with an ACL. From the edge inward nobody classifies again: the mark is trusted, period — deep inspection in the core is expensive; misplaced trust is far more so.
And here's the part people forget: the mark alone is decoration. The dirty work is done by queues. A proper switch or router sorts each packet by DSCP into a different queue: EF into the priority queue (served ahead of everything, with a policer on top so voice can never eat the whole link), AF41 into a queue with guaranteed bandwidth, CS0 into the common pool, CS1 gets the crumbs. The mark is the diagnosis; the queue is the treatment.
The bucket of tokens: how "how much may pass" gets measured
Marking and queuing sort the line; you still need the doorman who measures the flow. Nearly every platform uses the same mechanism: the token bucket. It works like an arcade: transmitting 1 bit costs 1 token. Tokens drip into the bucket at a constant rate — the CIR, your committed rate — and the bucket has a maximum size, Bc. When the bucket is full, new tokens spill over and are lost: there is no infinite savings account. Packet arrives and tokens are there? It sails through. No tokens? That's where the doorman's personality comes in — more on that in a moment.
With round, verified numbers: CIR of 1 Mbps and Bc of 8,000 bits. The refill interval is Tc = Bc ÷ CIR = 8,000 ÷ 1,000,000 = 8 ms, which means 125 refills per second of 8,000 bits each — multiply them and you get exactly the CIR back. And since the bucket never holds more than Bc, the maximum instantaneous burst is Bc: 8,000 bits, about 1,000 bytes in one go.
The bucket is what makes real life bearable: traffic is never flat, and Bc defines how much burst you forgive without breaking the average. Now — what happens when traffic arrives and the tokens are gone? Two philosophies:
- Policing — the scissors. Excess is dropped or re-marked to a worse class, on the spot. No queue, no added delay, no memory. Brutal but cheap.
- Shaping — the funnel. Excess is queued and waits for tokens. Nothing is lost (while the queue holds), but the price is delay: the burst comes out ironed flat at the CIR.
Same burst, different fates: 20,000 bits arrive at once with a full bucket. The policer lets 8,000 through (the tokens on hand) and cuts 12,000. The shaper passes the same 8,000 immediately and queues the other 12,000, which drain over the next 12 ms (12,000 ÷ 1,000,000). Everything arrives — just later.
When to use which? Police what you receive: at the inbound edge, so no customer or branch exceeds its contract. Shape what you send toward a slower link or a contracted CIR: better to let your own queue decide what waits — with your priorities — than to let the far-side policer chop blindly. TCP, on top of that, handles delay far better than loss: every policer drop means a retransmission and a window collapse. You can play with the parameters — CIR, Bc, Tc, and whether your burst fits — in the token bucket calculator.
Jitter buffer: buying order with latency
Even with perfect marking and shaping, the network never delivers on a clock. Voice needs one: a codec with a 20 ms ptime emits one packet every 20 ms sharp — 50 per second — and the listener needs them played back on exactly that beat. The variation between arrivals is jitter, and the remedy is the jitter buffer: a waiting room that holds freshly arrived packets a moment and hands them to the codec on a metronome. The trick is that this order is bought with latency — every millisecond of buffer is one more millisecond of delay in the conversation. The practical sizing rule: 2 × the measured jitter. Let's run the full budget:
- You measure the actual jitter toward the PBX: 20 ms. The call uses a ptime of 20 ms (one voice packet every 20 ms).
- Buffer = 2 × jitter = 2 × 20 = 40 ms. In depth: 40 ÷ 20 = 2 packets sitting in the waiting room.
- Mouth-to-ear budget: network 50 ms + buffer 40 ms + codec 15 ms + packetization (ptime) 20 ms = 125 ms.
- ITU-T G.114 puts the comfort limit at 150 ms one-way: 125 ≤ 150 → a fluid conversation, with 25 ms to spare.
- Cross-check: if jitter climbs to 40 ms, the buffer grows to 80 ms and the total to 165 ms — over the limit, and the walkie-talkie effect kicks in, with both parties talking over each other. Jitter charges you twice: it scrambles arrivals and inflates the buffer.
That's the deep reason to mark voice EF and give it a priority queue: it's not about the megabits (a call weighs almost nothing), it's about keeping jitter down so the buffer can stay small. Size the buffer and the mouth-to-ear budget with the jitter buffer calculator, and get the real per-call bandwidth — headers and all — from the VoIP calculator.
Video: reserve by percentile, not by average
Video is the elephant in the QoS room: a single camera can outweigh your entire phone system. Its bitrate depends on resolution, frame rate, codec and quality (bits per pixel), and the big lever is the codec: at comparable quality, H.265 asks for roughly half of what H.264 does. A 1080p30 stream at 0.1 bpp works out to 1920 × 1080 × 30 × 0.1 ≈ 6.2 Mbps in H.264 and ≈ 3.1 Mbps in H.265. Estimate yours — with your resolutions and quality targets — in the video bitrate calculator.
The detail that breaks networks: that figure is an average, and modern video is variable-rate. Static scene, barely anything; someone walks past the camera or an I-frame lands, and the bitrate jumps to 2 or 3 times the average for a few hundred milliseconds. If you sized the AF41 queue from the average, every spike arrives precisely when the guarantee runs out — and the video pixelates exactly at the interesting moment. Reserve by percentile (the p95 of the measured bitrate, not the datasheet), and let shaping absorb whatever pokes above it.
The short recipe
Serious QoS is four moves: confirm the congestion is real (in milliseconds, not 5-minute averages), mark at the edge and remark whatever you don't control, give each class a queue with a real guarantee, and smooth your egress before someone else's policer chops it. Start today: check with tcpdump whether your voice leaves the building marked EF — it takes a minute, and the answer is usually half the diagnosis.