JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

Quality of Service: Scheduling and Policing

A router with a full queue has to make a choice: who goes next, and who waits? This guide opens the box and shows the two simple machines inside — a scheduler that decides whose packet leaves first, and a policer that decides whose packets are allowed in at all.

What "quality of service" actually means

The first three guides in this rung kept circling one uncomfortable fact: the Internet promises nothing. Your VoIP call and a stranger's bulk file download pour into the same router queue, get treated identically, and take their chances together. That is best-effort service — the network tries its best and makes no guarantee about delay, loss, or jitter. Quality of service (QoS) is the umbrella name for every mechanism that lets a network treat some traffic better than other traffic, so that the packets that truly need low delay actually get it.

Here is the key shift in thinking. Best-effort treats all packets as equal strangers in one line. QoS says: not all packets are equal, and the network is allowed to play favourites. A voice packet that arrives 200 ms late is useless — the moment it was meant to be heard has passed. A packet of a file download that arrives 200 ms late is completely fine; nobody is waiting on that exact millisecond. So if a router must choose whose packet to send next, sending the voice packet first costs the download almost nothing and saves the call. QoS is just the machinery that lets a router make that choice on purpose instead of by accident.

The scheduler: who leaves the queue next

Every router output port has a buffer — a waiting room where packets sit when they arrive faster than the link can send them. The rule the router uses to pick the next packet out of that waiting room is its scheduling discipline, and the whole of QoS-by-scheduling lives in choosing that rule. The default is the dullest one: FIFO (first-in, first-out), a single line at a bank with one teller. Whoever arrived first leaves first. It is perfectly fair in the plainest sense, but it has no idea that a voice packet is more urgent than the bulk download ahead of it — so the urgent packet waits behind the patient one. That waiting is the queuing delay you met back in the foundations rung, and FIFO does nothing to spare the traffic that can least afford it.

The simplest fix is priority scheduling: sort packets into classes — say, a high-priority class for voice and a low-priority class for everything else — and always serve the high-priority queue first, only dipping into the low one when the high one is empty. Now the voice packet jumps the line every time, and your call stays crisp. But notice the danger that comes free with this power: if the high-priority class never runs dry, the low-priority traffic can wait forever. That is starvation, and it is the dark side of strict priority. Give voice absolute priority and a flood of voice can choke a download to a standstill. Pure priority is a sharp tool: brilliant for a small, well-behaved urgent class, dangerous if that class is not kept small.

Weighted fair queuing (WFQ) is the grown-up answer that captures the good of both. Give each class its own queue and its own weight — a guaranteed share of the link. A class with weight 3 gets roughly three times the throughput of a class with weight 1 whenever both have packets waiting. The scheduler rotates among the queues, giving each its promised fraction, so the voice class can be guaranteed, say, 30 percent of the link and never be starved, while the download class is guaranteed its share too and can never be starved either. And the elegant part: when a class has nothing to send, its share is loaned out to the others, so the link is never wasted. WFQ is fairness with a dial — you choose the weights, and nobody gets locked out.

Three packets waiting at one output link. V = voice (urgent), D = download.

FIFO          : D D V D D   -> sends D, D, V, ...   (V waits behind two D's)
PRIORITY      : V always first -> V, then D's        (but D can starve)
WFQ (V:D = 3:1): rotates by weight -> V V V D V V V D  (both guaranteed a share)

Same packets, three different rules for "who goes next" -- that choice IS QoS.
The same waiting packets under three scheduling disciplines. FIFO ignores urgency; strict priority can starve the download; weighted fair queuing guarantees each class a tunable share while loaning out any idle capacity.

The policer: who is allowed in

Scheduling decides the order of packets already in the queue. But there is a second, earlier question: should this packet even be admitted? A scheduler's promises only hold if each class stays within the rate it was promised — if the voice class is allowed to send three times its agreed rate, its guarantee is meaningless and it will hurt everyone else. So networks add a gatekeeper that measures each flow's rate and enforces a limit. Checking and enforcing that limit at the edge is traffic policing; reshaping a bursty flow into a smooth one before it enters the network is traffic shaping. Same goal — keep a flow inside its agreed envelope — but a policer punishes a violation on the spot, while a shaper gently delays packets until they conform.

The textbook way to picture a strict rate limit is the leaky bucket. Imagine a bucket with a small hole in the bottom. Arriving packets are water poured in at the top; the hole lets water out at a fixed, steady rate, no matter how violently you pour. If you pour faster than the hole can drain, the bucket fills, and once it overflows the extra water is simply spilled — those packets are dropped. The output is therefore perfectly smooth at the drain rate, however bursty the input was. It is a beautifully simple way to turn a spiky flow into a flat one. Its weakness is exactly its rigidity: it allows no burst at all, even when the network has spare room for one, which can be needlessly harsh on traffic that is naturally lumpy.

The cleverer cousin, used almost everywhere in practice, is the token bucket — and it flips the picture upside down. Now the bucket holds tokens, not packets. Tokens drip in at a steady rate r and pile up, but the bucket can hold at most b of them. To send a packet you must spend a token; no token, no send. The two parameters tell the whole story: r is the long-run average rate you are allowed, and b is how big a burst you are forgiven. If a flow stays quiet for a while, tokens accumulate up to b, and then it may send a sudden burst of up to b packets at once — the network rewards good behaviour by letting you cash in saved-up credit. That single idea, average rate plus a burst allowance, matches how real traffic actually behaves far better than the leaky bucket's flat trickle.

Putting the two machines together

Scheduling and policing are two halves of one design, and they only work as a pair. The policer is the bouncer at the door: it measures each flow with a token bucket and enforces the deal — stay under your rate r with bursts no bigger than b, or your excess packets get dropped or marked. The scheduler is the host inside, deciding the order of everyone who got past the door, using priority or WFQ to give each admitted class the share it was promised. The policer makes the scheduler's promises keepable; the scheduler turns admitted traffic into the experience each class needs. One without the other is half a system.

  1. A packet arrives at the router and is classified into a traffic class — for example, voice versus bulk data — by reading a marking in its header.
  2. The policer checks that class's token bucket: if a token is available the packet is admitted; if not, the packet is dropped or marked as out-of-profile.
  3. Admitted packets join their class's own queue, waiting their turn to leave the output link.
  4. The scheduler picks the next packet to send — strict priority for an urgent class, or WFQ to give each class its weighted share — and the chosen packet departs.

Why this is harder than it looks

Everything so far describes one router. The honest catch is that a packet on its way across the Internet passes through many routers run by many different companies, and a guarantee is only as strong as its weakest hop. If every router on the path schedules and polices your voice traffic carefully but one in the middle treats it as plain best-effort, your call still suffers there. QoS that actually delivers a guarantee therefore needs every router along the path to cooperate and honour the same agreement — which is far easier to demand inside one company's network than across the open Internet where no one is in charge.

There is also a subtle interaction with the buffers themselves. Earlier in the ladder you met bufferbloat — the trap of making router buffers too big, so packets pile up and sit for hundreds of milliseconds, wrecking exactly the low-delay traffic QoS is supposed to protect. A huge FIFO buffer does not help real-time media; it hurts it, by adding delay even when nothing is technically lost. Good QoS is therefore as much about keeping the right queues short as about choosing who goes first. Smart, per-class queues with sensible limits beat one giant shared buffer every time.

So we have the building blocks: classes, schedulers, policers, buckets. The remaining question is how to wire them into a whole-network architecture — do you reserve resources for each individual flow in advance, or just stamp each packet with a class and let routers handle classes rather than flows? Those are the two great answers, IntServ and DiffServ, and the surprising reason the real Internet mostly skips both and stays plain best-effort. That is the story of the final guide in this rung.