QoS en Linux: HTB + SFQ paso a paso
Traffic shaping with HTB (Hierarchical Token Bucket) en Linux es el mecanismo por el cual el kernel del sistema operativo controla cuánto ancho de banda puede usar cada tipo de tráfico en una interfaz de red. A través del subsistema tc (traffic control), HTB permite definir jerarquías de clases con ancho de banda garantizado y límites máximos, mientras que SFQ distribuye equitativamente el tráfico dentro de cada clase.
En 30 segundos
- HTB (Hierarchical Token Bucket) es una qdisc classful que organiza el ancho de banda en jerarquías con garantías mínimas (
rate) y límites máximos (ceil) - SFQ (Stochastic Fairness Queuing) es una qdisc classless que evita que un solo flujo monopolice el ancho de banda disponible dentro de una clase
- La combinación HTB + SFQ es el estándar para QoS en servidores Linux: HTB define cuánto, SFQ decide quién primero dentro de ese cuánto
- Los comandos
tc qdisc,tc classytc filtercomponen la jerarquía completa de control de tráfico - Las reglas de
tcno persisten al reiniciar; necesitás un script de inicio para aplicarlas automáticamente
¿Qué es QoS y por qué importa para tu servidor?
QoS (Quality of Service) es el conjunto de mecanismos que permiten controlar cómo se reparte el ancho de banda entre diferentes tipos de tráfico. Sin QoS, el kernel usa pfifo_fast por defecto: una cola simple que despacha paquetes sin distinción de importancia.
Ponele que tenés un servidor con backups nocturnos corriendo vía rsync mientras hay usuarios conectados por VPN. Sin control de tráfico, el backup puede saturar los 100 Mbps disponibles y dejar la VPN inutilizable. Eso no es un caso extremo; es lo que pasa siempre sin QoS configurado.
Los casos de uso más comunes: priorizar tráfico VoIP o videollamadas sobre descargas de archivos, limitar el ancho de banda de procesos de backup para no afectar producción, y garantizar que servicios críticos siempre tengan capacidad aunque el resto de la red esté congestionada.
La arquitectura de control de tráfico en Linux: qdiscs, clases y filtros
Cada interfaz de red tiene una qdisc raíz. Por defecto es pfifo_fast, una cola de tres bandas de prioridad sin clases ni jerarquía. Para hacer QoS real, reemplazás esa qdisc con una classful como HTB.
La arquitectura tiene tres componentes:
- Qdiscs: la disciplina de colas que decide en qué orden salen los paquetes. Hay classless (SFQ, fq_codel) que no tienen subdivisiones internas, y classful (HTB, CBQ) que sí
- Clases: subdivisiones del ancho de banda dentro de una qdisc classful. Cada clase tiene su propio
rateyceil, y puede tener clases hijas - Filtros: reglas que clasifican el tráfico entrante y lo asignan a una clase. Pueden basarse en IP, puerto, marca de paquete (iptables MARK), o protocolo
El flujo es: paquete llega → filtro lo clasifica → va a la clase correspondiente → la qdisc de esa clase decide cuándo sale. Si no encaja en ningún filtro, va a la clase default que hayas configurado. Ya lo cubrimos antes en tus pipelines de CI/CD.
HTB: cómo funciona el token bucket jerárquico
HTB modela el ancho de banda con la analogía del cubo de tokens. Cada clase tiene un cubo que se recarga a una tasa determinada (rate). Para enviar un paquete necesitás tokens; si el cubo está vacío, el paquete espera. Si el cubo se llena, los tokens sobrantes se descartan hasta un máximo (burst).
Cada clase tiene tres parámetros clave:
- rate: ancho de banda garantizado. La clase siempre puede usar esto, aunque el padre esté al límite
- ceil: máximo al que puede llegar la clase pidiendo prestado de clases hermanas con capacidad ociosa
- burst: tamaño máximo de ráfaga antes de que el rate limiting entre en efecto
El sistema de préstamo es lo más interesante de HTB. Si la clase de VoIP está usando 5 Mbps de sus 20 garantizados, los 15 Mbps restantes están disponibles para que otras clases los pidan prestado (hasta su propio ceil). Cuando el tráfico VoIP aumenta y necesita más, recupera esa capacidad con prioridad según el valor prio configurado.
¿Y cuándo deja de prestar? Cuando la clase con rate asignado necesita sus tokens. El préstamo es oportunista: funciona mientras hay capacidad ociosa.
SFQ: distribución equitativa dentro de cada clase
SFQ es una qdisc classless. No tiene subclases ni jerarquía; su trabajo es distribuir el ancho de banda de forma equitativa entre los flujos que compiten dentro de su contexto.
Funciona con hash de flujos: toma el par (IP origen, IP destino, puerto) y lo asigna a un bucket. Cada bucket obtiene turnos equitativos para transmitir. Si un solo cliente intenta usar todo el ancho de banda con 50 conexiones simultáneas, SFQ le da el mismo turno que a un cliente con una sola conexión (más o menos, dependiendo de las colisiones de hash).
El parámetro perturb re-hashea los flujos cada N segundos para evitar que alguien explote colisiones deliberadas para acaparar un bucket. El valor recomendado según la documentación oficial de tc-sfq es 10 segundos.
Usás SFQ debajo de una clase HTB para garantizar fairness interna. HTB decide cuánto ancho de banda tiene esa clase; SFQ decide quién dentro de esa clase lo obtiene primero. Para más detalles técnicos, mirá nuestro artículo sobre hreflang para sitios internacionales.
Cómo configurar HTB + SFQ paso a paso
El ejemplo que documenta el artículo técnico de referencia publicado en mayo de 2026 usa una interfaz eth0 con 100 Mbps totales divididos en tres clases: VoIP/video (alta prioridad), tráfico normal, y bulk/background.
Primero, reemplazás la qdisc raíz con HTB y definís la clase padre:
tc qdisc add dev eth0 root handle 1: htb default 30
tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbitEl default 30 significa que todo tráfico sin clasificar va a la clase 1:30 (bulk). Después creás las tres clases hijas:
# VoIP y video: 20 Mbps garantizados, puede subir hasta 100 Mbps
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 20mbit ceil 100mbit prio 1
# Tráfico normal: 70 Mbps garantizados
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 70mbit ceil 100mbit prio 2
# Bulk/background: 10 Mbps garantizados, techo de 30 Mbps
tc class add dev eth0 parent 1:1 classid 1:30 htb rate 10mbit ceil 30mbit prio 3Ahora agregás SFQ debajo de cada clase para fairness interna:
tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10
tc qdisc add dev eth0 parent 1:30 handle 30: sfq perturb 10Finalmente, los filtros que clasifican el tráfico. Para enviar VoIP (puerto 5060) a la clase prioritaria:
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip dport 5060 0xffff flowid 1:10Para verificar lo que quedó configurado: tc qdisc show dev eth0, tc class show dev eth0, y tc filter show dev eth0.
Comparativa de parámetros HTB vs SFQ
| Parámetro | HTB | SFQ | Para qué sirve |
|---|---|---|---|
rate | Sí | No | Ancho de banda garantizado mínimo |
ceil | Sí | No | Ancho de banda máximo (con préstamo) |
burst | Sí | No | Tamaño de ráfaga antes de rate limiting |
prio | Sí | No | Prioridad de préstamo entre clases hermanas |
perturb | No | Sí | Segundos entre re-hasheos de flujos |
limit | No | Sí | Máximo de paquetes en cola por bucket |
flows | No | Sí | Número de buckets para hash de flujos |
| Tipo de qdisc | Classful | Classless | HTB tiene subclases; SFQ no |
Errores comunes al configurar QoS en Linux
Confundir rate con ceil
rate es lo que la clase siempre puede usar, sin importar lo que hagan las demás. ceil es el techo al que puede llegar si hay capacidad prestada disponible. Si configurás rate 10mbit ceil 10mbit en una clase bulk, esa clase nunca va a poder usar más de 10 Mbps aunque el resto de la red esté ociosa. Para procesos de backup, eso puede ser lo que querés (sí, en serio). Para tráfico normal, probablemente no.
Pensar que SFQ tiene clases
SFQ es classless. No podés hacer tc class add ... parent sfq_handle; ese comando va a fallar. SFQ va siempre como hoja de la jerarquía, debajo de una clase HTB. Si intentás construir una jerarquía con SFQ como padre, no funciona.
Las reglas de tc desaparecen al reiniciar
Esto se lleva a confusión permanente. tc configura el kernel en tiempo de ejecución; no hay archivo de configuración que persista. Si reiniciás el servidor, volvés a pfifo_fast. La solución es meter los comandos en un script y ejecutarlo desde /etc/rc.local, un servicio systemd, o mediante NetworkManager dispatcher scripts si usás RHEL/CentOS.
Asignar ceil igual al total a todas las clases
Si todas las clases tienen ceil 100mbit con un total de 100 Mbps, y todas están activas al mismo tiempo, el sistema va a sobrecomprometerse. HTB maneja esto con el sistema de préstamo, pero en picos de tráfico el resultado puede ser impredecible. Pensá bien los ceils según el comportamiento real del tráfico, no como “máximo posible”. Sobre eso hablamos en cuando despliegas aplicaciones web.
No testear con tráfico real
Configurar los comandos y asumir que funciona es un error. Usá iperf3 para generar tráfico sintético a diferentes clases y verificar con tc -s class show dev eth0 que las estadísticas de bytes y paquetes coinciden con lo esperado. El campo Sent en la salida te dice cuánto tráfico pasó por cada clase.
Monitoreo y debugging de tu configuración QoS
Para ver el estado de las qdiscs: tc -s qdisc show dev eth0. El flag -s muestra estadísticas de paquetes y bytes procesados por cada qdisc.
Para ver las clases con métricas: tc -s class show dev eth0. En la salida buscá los campos rate (tasa actual) y backlog (paquetes esperando en cola). Si el backlog crece constantemente en alguna clase, esa clase está sub-provisionada para el tráfico que recibe.
Para ver los filtros activos: tc filter show dev eth0. Esto te muestra qué reglas de clasificación están aplicadas y a qué flowid apuntan.
Cuando algo no funciona como esperás, tcpdump -i eth0 -n port 5060 te permite verificar si el tráfico VoIP está llegando a la interfaz. Si el tráfico llega pero no se clasifica bien, revisá los filtros con tc filter show y verificá que el protocolo y puerto en el filtro coincidan con el tráfico real.
Preguntas Frecuentes
¿Cómo puedo limitar el ancho de banda en mi servidor Linux?
Con tc y HTB podés definir clases con rate y ceil para controlar cuánto ancho de banda puede usar cada tipo de tráfico. El comando básico es tc qdisc add dev eth0 root handle 1: htb default 10 seguido de clases con tc class add. Para persistir la configuración al reiniciar, necesitás un script systemd o dispatcher de NetworkManager. Relacionado: en servicios AWS sin servidor.
¿Cuál es la diferencia entre HTB y SFQ en el control de tráfico?
HTB es classful: define jerarquías de clases con ancho de banda garantizado mínimo (rate) y máximo (ceil). SFQ es classless: no tiene subclases y su función es distribuir equitativamente el ancho de banda entre los flujos que compiten dentro de su contexto. Se usan juntos: HTB define cuánto, SFQ decide quién dentro de ese cuánto.
¿Cómo priorizo tráfico VoIP sobre descargas en Linux?
Creás una clase HTB con prio 1 y un rate garantizado para VoIP (puerto 5060 típicamente), y otra clase con prio 3 para descargas con un ceil más bajo. Un filtro u32 que matchea el puerto destino 5060 envía ese tráfico a la clase prioritaria. Cuando hay congestión, HTB asigna primero a la clase con menor valor de prio.
¿Qué son los qdisc y cómo se relacionan con la calidad de servicio?
Qdisc (queuing discipline) es la política que determina en qué orden el kernel envía los paquetes cuando una interfaz de red está ocupada. El qdisc default de Linux (pfifo_fast) no hace QoS real. Para QoS, reemplazás ese qdisc con HTB que permite definir clases con garantías de ancho de banda y prioridades.
¿Cómo verifico que mi configuración de tc está funcionando?
tc -s class show dev eth0 muestra las estadísticas de bytes y paquetes por clase. Si el campo Sent aumenta cuando generás tráfico a esa clase con iperf3, la clasificación está funcionando. Si todo el tráfico va a la clase default, revisá los filtros con tc filter show dev eth0 para verificar que las reglas de clasificación estén aplicadas.
Conclusión
HTB + SFQ es el setup de QoS más práctico para servidores Linux. HTB maneja la jerarquía y las garantías de ancho de banda; SFQ previene que un solo flujo monopolice lo que tiene disponible una clase. La combinación resuelve dos problemas distintos y se compone bien.
Lo que más gente ignora es el sistema de préstamo de HTB: configurar bien rate versus ceil es lo que hace que una clase pueda usar capacidad ociosa de otra sin sacrificar las garantías. Si querés un servidor de producción donde los backups no maten las conexiones de usuarios, o donde VoIP sea siempre usable aunque alguien esté descargando archivos grandes, este modelo de configuración es el punto de partida. Si tu infraestructura está en un VPS, los mismos comandos aplican; donweb.com permite acceso root completo para configurar tc en sus VPS sin restricciones.
Eso sí: acordate de persistir las reglas. Todo lo que configuraste con tc desaparece al reiniciar.






