Home / Alt manpages / tc-fq(8)

  • tc-fq(8)
  • Admin command
  • linux

Tune Linux FQ Pacing Safely with tc

The Linux FQ qdisc splits traffic into flows and can honour the pacing an application or TCP stack asks for. This guide adds FQ to one interface with tc, turns on a shallow ECN marking threshold, and checks the live queue statistics. Examples use tc from Ubuntu's iproute2 6.1.0-1ubuntu6.4 package.

Allow about 10 minutes if you already know which interface you are testing. You need a shell, the iproute2 package, and elevated privileges for the change itself. This replaces the root qdisc, so test on a disposable host or a maintenance window: a root qdisc swap can affect traffic immediately.

1. Identify the interface and current qdisc

Pick the interface carrying the traffic you want to observe. Replace IFACE below with a real name such as eth0 or ens3. Neither command changes network state.

ip -brief link
tc qdisc show dev IFACE
  • Read the existing output first. A line such as qdisc fq_codel or qdisc mq is not interchangeable with FQ.
  • Save it somewhere outside this guide if you would need to restore a more complicated setup exactly.
  • FQ is classless. There are no child classes to configure, and it is aimed mainly at locally generated traffic; for forwarded traffic it falls back to a packet hash rather than a socket-owned flow.

2. Add FQ with a conservative test setting

Run this as root, or prefix it with sudo. ce_threshold asks FQ to mark packets with ECN Congestion Experienced once queueing passes 4 milliseconds, which suits congestion-control schemes such as DCTCP that deliberately lean on shallow ECN marking. It is not a general substitute for measuring your own workload.

sudo tc qdisc add dev IFACE root fq ce_threshold 4ms
  • Success prints nothing.
  • RTNETLINK answers: File exists means the interface already has a root qdisc. Do not keep retrying: inspect it, then decide whether replacing it is safe.
  • Operation not permitted means the command was not elevated, or your account lacks the capability to change network configuration.

Everything you did not name keeps its FQ default: a 10,000-packet overall limit and 100 packets per flow, a 1,024-bucket hash table, an orphan mask capping unowned traffic at 1,024 allocated flows, and pacing enabled. These are queueing controls, not bandwidth guarantees.

3. Verify the active parameters and counters

Ask tc for both statistics and detailed parameters:

sudo tc -s -d qdisc show dev IFACE

Expect a line similar to this, though your handle, interface name, packet counters and MTU-derived byte values will differ:

qdisc fq 8001: dev IFACE root refcnt 2 limit 10000p flow_limit 100p buckets 1024 orphan_mask 1023 quantum 3028b initial_quantum 15140b ce_threshold 4.0ms

Look for qdisc fq, root, limit, flow_limit and ce_threshold. The default quantum is twice the interface MTU, and a new flow starts with credit for ten MTUs so TCP's initial window is not delayed, which is why the byte values track your MTU.

Tip

The statistics cover sent bytes and packets, drops, backlog, flow counts, throttling and ECN marks, all cumulative for the life of this qdisc. A zero ce_mark does not prove traffic never queued for 4 milliseconds, only that nothing has been marked yet.

4. Adjust limits only for a measured reason

You can set a hard total queue limit, a per-flow limit, and a maximum rate per flow. This example limits each flow to 50 packets and caps a flow at 100 Mbit/s:

sudo tc qdisc replace dev IFACE root fq flow_limit 50 maxrate 100mbit
  • Only use replace when swapping the root qdisc is acceptable.
  • Reaching the total limit drops new packets. Lowering a limit can drop packets immediately so the queue meets the new value, and a small per-flow limit can drop bursts even while the total queue sits mostly empty.
  • maxrate is a per-flow ceiling, not a link-wide allocation. Application requests through SO_MAX_PACING_RATE are ignored once they ask for more than this ceiling. Without maxrate, FQ defaults to unlimited, subject to whatever pacing the application or TCP supplies.

5. Undo the test change

Warning

Deleting the root qdisc changes live packet scheduling and may briefly disrupt traffic. Run this only when you intend to remove the qdisc, and use the output you saved in step 1 if you need to recreate the previous configuration.

sudo tc qdisc del dev IFACE root
tc qdisc show dev IFACE

After deletion, the kernel or your network manager may install another default qdisc. If a service manages the interface, make the persistent change there too; this command alone is not a permanent configuration record.

Done means

  • Correct interface identified and its existing root qdisc inspected.
  • tc -s -d qdisc show dev IFACE reports qdisc fq with the settings you intended.
  • You know the queue and flow limits can drop packets once reached.
  • Counters checked after representative traffic, including ce_mark if ECN marking was part of the test.
  • Qdisc left in place deliberately or removed with the right privileged command.