What This Actually Is Before You Start

A loss setup is simply a way to inject a known percentage of packet loss into a network path so you can test how your application behaves under failure conditions. Most people skip the basics and jump straight into a GUI tool that adds too many variables. You don't need that. The native approach on Linux is about three commands and ten minutes. Start by identifying your interface. Run ip addr and note the one with the IP you care about. If you're on a remote machine, do not run any of the tc commands yet unless you are comfortable recovering via IPMI or serial console. I spent two hours stuck in a data center because I flushed a default route while a loss qdisc was holding the door shut. The core command uses the tc utility with the netem qdisc. Here is the simplest functional version:

tc qdisc add dev eth0 root netem loss 5% That applies a 5 percent random loss to all outbound traffic on eth0. In practice it shows up quickly. I ran a continuous ping before and after the command and watched the sequence jump from a steady 1ms to packets missing every twenty or so seconds. The kernel handles the randomization using a Markov chain, which means losses tend to arrive in short bursts rather than perfectly spread out. That matters more than most guides admit. If you need more control, add a burst parameter. A single loss value without a burst gives you individual isolated packet drops. That is useful for testing retransmission behavior but it does not reflect real degraded links where loss arrives in clumps. Use this instead when you want realistic cellular or microwave degradation:

tc qdisc add dev eth0 root netem loss 5% 50% burst 20 The second number sets the correlation. Fifty percent correlation means the last drop is likely to be followed by another drop. Twenty is the burst size, which groups consecutive losses together. I tested this against a media streaming workload and saw the exact buffer underrun pattern I expected. Without the burst parameter the stream would have stalled far less often than it does on actual spotty cell networks. Adding latency at the same time is common, since loss rarely travels alone in real deployments. The combined command looks like this:

Get the Full Details

Stop loss setup guide for automated perpetual DEX trading | Mithril
Stop loss setup guide for automated perpetual DEX trading | Mithril

tc qdisc add dev eth0 root netem loss 3% delay 150ms 30ms burst 10 The delay value is the base latency in milliseconds. The second number is the jitter, which is the random variation around that base. Thirty milliseconds of jitter means actual latency will swing between about 120 and 180ms. This setup is enough to make a VoIP codec switch to a lower quality mode or cause a TCP connection to throttle its congestion window. I have used it to reproduce the exact slowdown I see when customers call about their video feeds on poor cellular backhaul. Applying loss to inbound traffic only requires a second qdisc on the egress side of the reverse path, or you can use the handle option to target specific flows with firewall marks. If your test setup uses two machines, apply the loss qdisc on the interface closest to the receiver for the most accurate measurement of what the application actually sees. I learned this the hard way when my numbers looked fine because the loss was applied upstream of a NAT device that was rewriting packet sizes and hiding the true impact.

To remove the rule, replace add with delete. The full command is: tc qdisc del dev eth0 root netem Run tc qdisc show dev eth0 anytime to verify what is currently active. This is important because tc does not warn you if you add a second qdisc to the same root handle. The second command fails silently unless you use replace, and older kernels sometimes behave unpredictably when multiple qdiscs compete for the same root. I lost an evening to a stale qdisc that survived a VPN tunnel teardown and kept injecting loss long after I thought it was gone.

For Windows environments you can use Nttcc or the older Iphlpapi-based loss tools, though they are less precise than Linux netem. macOS users should look at pfctl or install netem through Homebrew, but the behavior is not identical. If your product ships on Windows and you need reproducible loss, a Docker container on Linux with the traffic control commands inside it is the path of least resistance. I run all my loss-based integration tests this way now and cut test setup time from about twenty minutes to roughly four. There are limitations you should accept upfront. Netem operates at the kernel level, so it affects all traffic on that interface, including management traffic if you are testing a server you are connected to. It also does not simulate physical-layer errors like CRC corruption or signal fade. The loss it generates is purely packet-level. If you need bit-error simulation or true RF impairments, look at software-defined radio setups or hardware impairers. They cost more and take longer to configure, but they catch failures that packet-level loss testing misses entirely. Another blind spot is asymmetric loss. A single netem qdisc on one interface only affects traffic leaving that interface. Real-world loss is often directional, especially on cellular links where uplink and downlink experience very different error rates. To model that, you need separate rules on both ends or a dual-stack host with per-direction configuration. I once reproduced a bug that only appeared under asymmetric uplink loss, and it took me three days to set up the correct mirrored tc rules. A simpler setup would never have caught it.

0 LOSS SETUP FOR STOCK MARKET TRADERS | MOST DETAIL SESSION ON YOUTUBE - YouTube
0 LOSS SETUP FOR STOCK MARKET TRADERS | MOST DETAIL SESSION ON YOUTUBE - YouTube

Keep your test matrix focused. Running fifty different loss percentages across every supported client is a quick way to waste a week. Pick the boundary values your product is rated for, add a couple of failure points beyond those ratings, and document what breaks at each level. The useful output is not a pass or fail report. It is a list of which features degrade gracefully and which ones throw errors that your support team cannot explain. That distinction is what separates a usable test setup from one that just generates noise. If you need something faster for ad hoc checks, write a small shell script that wraps the add and delete commands. I keep one at ~/scripts/loss.sh with arguments for percentage, delay, jitter, and burst. It takes about six seconds to apply a realistic impairment profile and four seconds to clean up. That speed matters when you are running regression tests multiple times a day and the queue grows before you finish the previous round. Save your tc rules if you expect to reboot. A simple tc save to a file and a corresponding systemd service or rc.local entry will restore them on boot. Without that, every restart wipes your configuration and your next test starts from a clean baseline you did not intend. I learned this during a deployment where a cron job triggered a daily reboot and the missing qdisc caused a false green result that lasted three days before someone noticed the traffic pattern had changed.

One more practical note. If your application uses UDP and you need to confirm whether it handles loss correctly, pair the netem setup with a lightweight traffic generator like iperf3 or pktgen. Iperf3 with the -u flag and a duration of sixty seconds gives you a quick readout of reported loss, retransmits, and jitter. Compare that against your configured netem values. If the measured loss is more than a few percentage points off the configured value, check your interface speed and MTU settings, then verify that no other qdisc is sharing the root handle. Mismatched MTU is the most common cause of unexpected discrepancy. That is the practical setup. It is not elegant. It is not a perfect replica of every real-world failure mode. But it is fast, reversible, and reproducible, which is what you actually need when you are testing how a system handles loss.