BrakeBear applies network bandwidth limits, latency, jitter, and packet loss to Docker containers using Linux traffic control (tc) and network namespaces.
- Bandwidth limiting: Upload and download rate limits
- Network emulation: Latency, jitter, and packet loss simulation
- Docker integration: Automatic container discovery and monitoring
- IPv6 & dual-stack support: Full support for IPv4, IPv6, and mixed networks
- Smart exclusions: Bypass traffic limits for specific networks, IPs, ports, or Docker networks
- Real-time application: Apply limits to running containers
- Clean removal: Automatically removes limits when containers stop
Create configuration (brakebear.yaml):
log_level: "info"
docker_containers:
- name: "my-container"
download_rate: 1mbps
upload_rate: 500kbps
latency: 50ms
jitter: 10ms
loss: 0.1%
exclusions:
private-networks: true # Excludes RFC1918 private networks and IPv6 ULA/Link-Local from traffic limitingFor more examples, see the example config file.
Run it using docker:
docker run --rm -it \
--privileged \
--network host \
--pid host \
--name brakebear \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v $(pwd)/brakebear.yaml:/etc/brakebear/brakebear.yaml:ro \
ghcr.io/ethpandaops/brakebear:masterNote: The
--privileged,--network host, and--pid hostflags are required for BrakeBear to access container network namespaces and apply traffic control rules.
Or build it from the source code:
-
Build BrakeBear:
make build
-
Run BrakeBear:
sudo ./brakebear run --config brakebear.yaml
download_rate: Ingress bandwidth limit (e.g.,1Mbps,500kbps)upload_rate: Egress bandwidth limit (e.g.,1Mbps,500kbps)
latency: Base latency (e.g.,50ms,100ms)jitter: Latency variation (e.g.,10ms,20ms)loss: Packet loss percentage (e.g.,0.1%,5%)
BrakeBear supports excluding specific networks from traffic control rules. By default, no exclusions are applied. The following exclusion types can also be combined:
Exclude RFC1918 private networks and IPv6 private ranges:
- IPv4:
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 - IPv6:
fc00::/7(ULA),fe80::/10(Link-Local)
exclusions:
private-networks: trueExclude specific IP ranges using CIDR notation (supports both IPv4 and IPv6):
exclusions:
cidr:
ranges:
# IPv4 ranges
- "192.168.1.0/24"
- "10.0.0.0/8"
- "203.0.113.0/24"
# IPv6 ranges
- "2001:db8::/32" # IPv6 documentation range
- "fc00::/7" # IPv6 ULA
- "2001:db8::1/128" # Specific IPv6 hostExclude traffic to specific hostnames (with automatic IPv4/IPv6 resolution):
exclusions:
dns:
names:
- "api.github.com" # Resolves to both IPv4 and IPv6
- "registry.npmjs.org" # Dual-stack hostname
- "ipv6.google.com" # IPv6-preferred hostname
check_interval: "10m" # How often to re-resolve DNS (optional, default: 5m)Exclude traffic to specific ports regardless of destination (applies to both IPv4 and IPv6):
exclusions:
ports:
tcp: ["80", "443", "8000-9000"] # TCP ports and ranges
udp: ["53", "5353", "546-547"] # UDP ports (includes DHCPv6)Exclude traffic on specific Docker networks (automatically discovers IPv4/IPv6 CIDR ranges):
exclusions:
docker-networks:
names: ["shared-network"] # Specific network namesExclude traffic on all Docker bridge networks using wildcard:
exclusions:
docker-networks:
names: ["*"] # All bridge networks (IPv4 and IPv6)Multiple exclusion types can be used together for comprehensive dual-stack support:
exclusions:
private-networks: true # IPv4 RFC1918 + IPv6 ULA/Link-Local
cidr:
ranges:
- "203.0.113.0/24" # IPv4 documentation range
- "2001:db8::/32" # IPv6 documentation range
dns:
names: ["dual-stack.example.com"] # Resolves to both IPv4 and IPv6
check_interval: "5m"
ports:
tcp: ["80", "443"]
udp: ["53", "546-547"] # DNS + DHCPv6
docker-networks:
names: ["bridge"]- Linux with
tc(traffic control) support - Docker
- Root privileges (for network namespace access)
BrakeBear uses Linux traffic control mechanisms:
- HTB (Hierarchical Token Bucket) for bandwidth shaping
- IFB (Intermediate Functional Block) interfaces for ingress limiting
- Netem for network emulation (latency, jitter, loss)
- Network namespaces to apply limits per container
To develop on macOS, you can use a OrbStack VM. To create the VM, run:
make orbstack-devTo clean up the VM, run:
make orbstack-dev-cleanTo connect to the VM, run:
ssh brakebear@orb# Using speedtest-cli
docker run --rm --name=demo -it gists/speedtest-cli
# Using wget
docker run --rm --name=demo -it alpine sh -c "apk update && apk add wget && exec wget -4 -O /dev/null https://speed.af.de/files/100MB.bin" # IPv4
docker run --rm --name=demo -it alpine sh -c "apk update && apk add wget && exec wget -6 -O /dev/null https://speed.af.de/files/100MB.bin" # IPv6
docker run --rm --name=demo -it alpine sh -c "apk update && apk add wget && exec wget -4 -O /dev/null https://speed.af.de/files/1GB.bin" # IPv4
docker run --rm --name=demo -it alpine sh -c "apk update && apk add wget && exec wget -6 -O /dev/null https://speed.af.de/files/1GB.bin" # IPv6
# Using iperf3
docker run --network=shared --rm --name=demo -it alpine sh -c "apk update && apk add wget iperf3 && exec iperf3 -c speed.af.de -p 5200 -P 10 -f m -4" # IPv4 Upload
docker run --network=shared --rm --name=demo -it alpine sh -c "apk update && apk add wget iperf3 && exec iperf3 -c speed.af.de -p 5200 -P 10 -f m -6" # IPv6 Upload
docker run --network=shared --rm --name=demo -it alpine sh -c "apk update && apk add wget iperf3 && exec iperf3 -c speed.af.de -p 5200 -P 10 -f m -4 -R" # IPv4 Download
docker run --network=shared --rm --name=demo -it alpine sh -c "apk update && apk add wget iperf3 && exec iperf3 -c speed.af.de -p 5200 -P 10 -f m -6 -R" # IPv6 Download
# Ping
docker run --rm --name=demo -it alpine sh -c "ping google.com" # IPv4
docker run --rm --name=demo -it alpine sh -c "ping -6 google.com" # IPv6This project is licensed under the GNU GPL-3.0.
