TCP congestion control and currency exchange rates both overshoot their long-run equilibria because fast variables (exchange rates, congestion window) adjust instantly while slow variables (price levels, bandwidth discovery) lag by multiple timescales. The overshoot is not noise — it's mathematically required by the coupling between fast and slow dynamics.
This mechanism was independently derived twice: Rudiger Dornbusch described it for currency markets in 1976; Van Jacobson discovered it for TCP flow control in 1988. Neither cited the other. The mathematics of mismatched timescales forced identical conclusions from different domains.
The Core Mechanism
Here's the setup that produces overshooting in any system: you have a fast variable and a slow variable, they're coupled, and the fast one has to do all the adjusting because the slow one physically can't jump.
In Dornbusch's model:
- Fast variable: the exchange rate (adjusts instantly in financial markets)
- Slow variable: the domestic price level (sticky — firms change menus slowly)
- Coupling: uncovered interest parity (UIP) ties expected depreciation to interest rate differentials
In TCP CUBIC:
- Fast variable: the congestion window (
cwnd, adjusted every ACK) - Slow variable: the congestion signal (packet loss or ECN, observable only after a full RTT)
- Coupling: the network's bottleneck buffer connects sending rate to loss events
When a shock hits — a monetary expansion, a new flow joining the network — the fast variable has to move further than its long-run target to compensate for the slow variable's inability to respond. This isn't a bug. It's the only mathematically consistent solution.
Why Overshooting Is Necessary
This is the part most people miss. The overshoot isn't noise or irrationality. It's required by the system's own equilibrium conditions.
In Dornbusch: after a money supply increase, prices need to rise proportionally in the long run (monetary neutrality). But prices are sticky in the short run. The exchange rate has to depreciate more than the long-run level so that the expected future appreciation creates a return differential that makes investors willing to hold domestic assets at the new interest rate. If it didn't overshoot, UIP would be violated and arbitrage would force it there anyway.
In TCP: after a bandwidth increase, cwnd should grow to fill the new bandwidth-delay product (BDP). But the sender can't observe available bandwidth directly — it only learns about congestion after packets are dropped, one RTT later. So cwnd grows past the optimal point, triggers a loss, and cuts back. The overshoot is how TCP discovers the boundary.
Both systems can be written as a pair of differential equations:
Fast: dx/dt = -a(x - x̄(y)) # x adjusts toward target that depends on y
Slow: dy/dt = -b(y - ȳ(x)) # y adjusts toward target that depends on x
where a >> b
The eigenvalues of this system always include one with a positive real part for the fast variable when you impose the boundary condition that the system must converge. That positive eigenvalue is the overshoot. The amplitude of oscillation scales with a/b — the ratio of adjustment speeds.
Side-by-Side
| Property | Dornbusch (Exchange Rates) | TCP CUBIC |
|---|---|---|
| Fast variable | Exchange rate | Congestion window (cwnd) |
| Slow variable | Price level | Congestion signal (loss/ECN) |
| Adjustment ratio | ~instant vs months | ~per-ACK vs per-RTT |
| Overshoot trigger | Monetary policy shock | Bandwidth change / new flow |
| Convergence target | Purchasing power parity | Bandwidth-delay product |
| Feedback mechanism | Interest rate arbitrage | Packet loss detection |
| Damping | Expectations anchoring | Multiplicative decrease |
| Time to converge | Months to years | Tens of RTTs |
The structural parallel is exact. Both have a saddlepath that the system must jump onto — Dornbusch calls it the "stable arm," TCP people call it the "steady state trajectory." Miss the saddlepath in either direction and the system diverges: hyperinflation or congestion collapse.
The CUBIC Shape
TCP CUBIC's congestion window function is literally a cubic polynomial in time since the last loss event:
W(t) = C(t - K)^3 + W_max
where K = (W_max * β / C)^(1/3)
β = multiplicative decrease factor (0.7)
C = scaling constant
This is a designed damped oscillator. After a loss event, cwnd cuts to β * W_max, then climbs back along the cubic curve, slowly approaching W_max from below, then cautiously probing above it. The cubic shape ensures the window spends more time near W_max (where bandwidth utilization is high) and less time far from it.
Compare this to the exchange rate path after a monetary shock in Dornbusch: an instant jump past equilibrium, then exponential convergence back. Different functional form, same qualitative dynamics — overshoot followed by asymptotic approach from the wrong side.
The key parameter in both cases is the ratio of how fast you adjust to how fast you learn. TCP's RTT is roughly analogous to the "price stickiness" parameter in Dornbusch. Higher RTT means more overshoot, just as stickier prices mean more exchange rate volatility. This is testable and verified — TCP CUBIC on satellite links (600ms RTT) oscillates far more than on datacenter links (0.2ms RTT).
BBR: Rational Expectations for Networks
Here's where the analogy gets sharp.
Dornbusch's overshooting goes away under one condition: if the price level could jump instantly. More precisely, if agents had perfect foresight about the full path of adjustment, you could construct equilibria without overshooting. This is the rational expectations critique — if you have a good enough model of the system, you don't need to overshoot to discover equilibrium. You can just calculate it.
Google's BBR congestion control algorithm does exactly this for TCP. Instead of probing for bandwidth by increasing cwnd until packets drop, BBR explicitly estimates two quantities:
BtlBw = max delivered rate over recent window
RTprop = min RTT over recent window
BDP = BtlBw * RTprop
Then it sets cwnd to a small multiple of BDP. No probing. No loss-driven feedback. No overshoot.
BBR is the rational expectations agent of congestion control. It builds an internal model of the network's capacity and targets it directly, rather than relying on the slow, binary feedback of packet loss. The parallel to Dornbusch is clean: model-based stabilization eliminates overshooting by replacing slow feedback with direct estimation.
| Approach | Dornbusch Framework | TCP Framework |
|---|---|---|
| Slow feedback, overshoot | Sticky prices + UIP | Loss-based (CUBIC, Reno) |
| Model-based, no overshoot | Rational expectations / flexible prices | BBR (estimate BDP directly) |
| Hybrid | Inflation targeting (anchor expectations) | CUBIC + ECN (faster feedback) |
The hybrid row matters. Central banks learned that you can reduce overshooting without eliminating price stickiness — just anchor expectations with a credible inflation target. Similarly, ECN (Explicit Congestion Notification) doesn't eliminate RTT delay, but it gives the sender earlier, richer feedback than waiting for a packet drop. Both are "cheaper feedback" solutions that reduce overshoot without requiring a full model.
Where It Breaks Down
The analogy is structurally precise but operationally different in ways that matter.
Feedback type. TCP gets binary feedback: a packet was dropped, or it wasn't. (ECN adds a bit — "congestion experienced" — but it's still discrete.) Exchange rates respond to continuous, noisy, endogenous signals — interest rates, trade flows, sentiment — that are themselves functions of the exchange rate. TCP's feedback loop is clean. Forex is a hall of mirrors.
Agent structure. TCP is a single algorithm running on a single sender, making deterministic decisions. The exchange rate emerges from millions of decentralized agents with heterogeneous beliefs, time horizons, and risk preferences. Dornbusch assumes they all have rational expectations — a heroic simplification. TCP doesn't need that assumption because there's only one "agent" and its behavior is specified in code.
Controllability. Van Jacobson could sit down and redesign TCP's congestion control algorithm. Nobody can redesign how exchange rates work. TCP is an engineered system; forex is an emergent one. This is why BBR could actually be deployed — you can ship a new kernel module. You can't ship new monetary economics to every market participant.
Discrete vs. continuous. TCP operates in discrete time steps (per-ACK or per-RTT). Dornbusch's model is continuous-time. This matters at the edges — TCP can have limit-cycle oscillations that continuous models can't produce. The sawtooth pattern of TCP Reno (linear increase, multiplicative decrease) has no continuous-time Dornbusch equivalent; it's a relaxation oscillation, not a damped one.
Loss asymmetry. In TCP, overshooting too far causes packet loss, which is expensive (retransmission, timeout, throughput collapse). Undershooting just leaves bandwidth on the table. This asymmetry shapes the algorithm toward caution after loss events (multiplicative decrease is aggressive, additive increase is gentle). In Dornbusch, overshooting and undershooting the exchange rate are roughly symmetric in their welfare costs. The resulting dynamics are qualitatively different — TCP has the distinctive sawtooth, exchange rates have smoother mean-reversion.
What Generalizes
Strip away the domain specifics and you get a principle that applies anywhere you have coupled fast-slow dynamics:
When a fast variable is coupled to a slow variable, and only the fast variable can adjust on short timescales, the fast variable must overshoot its long-run equilibrium. The overshoot amplitude is proportional to the speed mismatch. You can eliminate the overshoot by either speeding up the slow variable (faster feedback) or giving the fast variable a model of where the slow variable is heading (model-based control).
This shows up everywhere:
- Thermostat control: temperature overshoots setpoint because the heating element has thermal lag. PID controllers add derivative and integral terms — essentially modeling the lag.
- Inventory management: order quantities overshoot stable demand because supply chain lead times are slow. The bullwhip effect is Dornbusch overshooting for supply chains.
- Neural learning rates: SGD with high learning rates overshoots the loss minimum because gradient computation is a noisy, delayed signal. Learning rate schedulers and Adam's momentum are model-based damping.
The solution is always the same: build a better model of the slow variable, or find a way to get feedback faster. Dornbusch and Jacobson arrived at the same problem from opposite ends of the university. The math didn't care.
The Takeaway
If you're designing a system with coupled feedback loops operating at different speeds, overshooting is not a pathology to be debugged — it's a mathematical inevitability. Your options are:
- Accept it and design for graceful oscillation (CUBIC's cubic polynomial)
- Speed up the slow loop (ECN, inflation targeting)
- Model the slow variable directly (BBR, rational expectations)
Option 3 is the most powerful but requires that your model of the slow variable is actually accurate. BBR works because network capacity is relatively stable and measurable. Rational expectations "works" in Dornbusch's model because he assumed it does. In practice, modeling slow variables is hard, and a bad model is worse than honest overshooting.
The engineers and the economists arrived at the same tradeoff independently. That's how you know the tradeoff is real.