Why your shower temperature oscillates
The scalding-then-freezing shower dance isn't you being bad at taps — it's a feedback loop fighting a time delay, and it has a name. We meet the PID controller behind thermostats, cruise control and showers, tune one live, and find out why a little lag turns sensible corrections into oscillation.
You know the dance. You step in, it's cold, you crank the tap toward hot. Nothing happens, so you crank it further. Then a wall of scalding water arrives, you recoil and yank it back toward cold, overshoot, and now it's freezing again. A few cycles of this and you either find the spot or give up and accept lukewarm. It feels like incompetence, but it isn't. You're a control system fighting a time delay, and the fact that you oscillate is a predictable, named phenomenon that engineers design around every day.
Showers, thermostats, cruise control, an oven, the autopilot holding a heading: under the skin they're all the same loop. Once you see the loop, the shower stops being annoying and starts being a little physics demo you stand in every morning.
You are the controller
Every feedback loop has the same four parts. A setpoint (the temperature you want), a measurement (what your skin reports), an error (the gap between them), and an actuator (the tap) that you move to shrink the error.
Here is the reference (desired temperature) and is the measured output. The whole game is driving to zero and keeping it there. The simplest strategy, and the one your hand reaches for instinctively, is proportional control: push the tap in proportion to how wrong things are. Big error, big correction; small error, gentle nudge. Correction , and is how aggressive you are.
That works beautifully when the system responds instantly. Showers don't.
The delay is the villain
Between turning the tap and feeling the change, there's a pipe full of water that has to flush through. That dead time is the whole problem. Your correction is based on a temperature that's already several seconds old, so a strong proportional response sends a big slug of hot water that you won't feel until it's too late to take it back. By the time it arrives you've often corrected again, stacking the changes. The result is overshoot, then over-correction, then oscillation.
Gain racing lag
Oscillation is what happens when your eagerness outruns your information. With no delay, you could use a huge , slam the error to zero and stop. Add delay and that same aggressive gain becomes a liability: every correction is a bet on stale data, and a big bet on stale data overshoots. Crank the gain past a critical point and the loop won't just overshoot once, it'll oscillate forever, each swing feeding the next. The cure is either to be gentler (lower ), to anticipate (the D term, below), or to genuinely wait out the lag between adjustments, which is the grown-up shower technique nobody tells you.
Tune one yourself
Rather than describe it, here's the loop to play with. It's a PID-controlled second-order system: drag the three gains and watch the step response settle, overshoot, or ring.
The three terms
That's the whole PID controller: present, past, and future error, added together.
- P, the present. Proportional to the current error. Does the bulk of the work, but on its own leaves a small permanent offset.
- I, the past. Integrates the error over time, so even a tiny lingering offset accumulates until the controller has pushed it out. This is what gets you exactly to temperature, not nearly.
- D, the future. Looks at the rate of change and reacts to where the error is heading. It's the anticipation that lets you damp a swing before it overshoots.
Why does plain proportional control fall short? Because at steady state the only thing producing any correction is the error itself, so the error can't actually reach zero: it settles at whatever small value keeps the tap where it needs to be. For a simple system the leftover offset is
You can shrink that by cranking , but we've just seen where that road leads: oscillation. The integral term is the honest fix.
Integral windup, the classic gotcha
The integral term has a sharp edge. If the error stays large for a while (say the tap is already fully open but the water just isn't hot enough yet), the integral keeps accumulating a correction the actuator can't deliver. When things finally catch up, that built-up demand has to unwind, and the system blows past the setpoint hugely before recovering. This is "integral windup", and it's behind a surprising number of real-world control disasters. The fix is to stop accumulating once the actuator saturates ("anti-windup"). If you've ever had an oven rocket past its target after a slow start, you've probably watched windup happen.
Too much D has its own failure: it's differentiating the measurement, and differentiation amplifies noise, so a jittery sensor and a big make the controller twitch at shadows. Tuning PID is the art of balancing these three against the system's lag, and there are recipes (Ziegler–Nichols is the famous one) for getting close before you fine-tune by hand.
A PLL is a PID in disguise
Here's the cross-field connection I can't resist. A phase-locked loop, the circuit that keeps your radio tuned and your CPU clock honest, is exactly this same loop with the temperature swapped for phase: it compares the phase of an incoming signal to its own oscillator, and a loop filter (a P plus an I, basically) drives the error to zero. Same equations, completely different hardware. Once you have the controller in your head you start seeing it everywhere — in circuits, in robotics, in your shower, arguably in the way a central bank chases inflation with a lag.
Which is the food-for-thought note I'll leave on. Humans are genuinely bad at controlling systems with long delays, because our instinct is proportional and impatient: we see no response, so we push harder, and the delayed reaction then overshoots. Showers, yes, but also slow-moving things like an economy or a climate, where the "tap" we turn today won't be felt for years. The shower is the harmless version of a mistake we make at much larger scales.
Recap
Your shower oscillates because you're running a proportional controller against a time delay, and gain racing lag is the recipe for ringing. The professional fix is PID: react to the present error, accumulate the past to kill the offset, and anticipate the future to damp the swing, all while watching out for windup and noise. Next time you're doing the cold-hot dance, try the engineer's move: make a small change and wait for the pipe to flush before judging it. You'll lock on in two moves instead of ten.
Reading further
- Åström & Murray, Feedback Systems: the modern standard, rigorous and free online, with PID treated properly. fbsbook.org
- Franklin, Powell & Emami-Naeini, Feedback Control of Dynamic Systems: the classic course textbook if you want the full control-theory treatment.
- Ziegler & Nichols (1942), Optimum Settings for Automatic Controllers: the original tuning recipe, still taught and still used. A nice piece of practical engineering history.
- Brett Beauregard, Improving the Beginner's PID: a wonderful blog series on the real-world gotchas (windup, derivative kick, sample time) from someone who wrote a widely-used PID library. brettbeauregard.com
Try it in the lab
All effects →PID Tuner
engineeringStep response of a PID-controlled 2nd-order plant — tune Kp, Ki, Kd and watch overshoot and settle.
controlfeedbackPLL Lock-In
engineeringPhase-locked loop tracking a chirped reference — P/PI loop filter, VCO frequency, lock-in visualisation.
controlpllBand Structure
physicsNearly-free electron E-k diagram with Brillouin zone gaps.
condensed mattersolid state
More from the blog
What JPEG throws away
A JPEG is often a tenth the size of the raw image and you can't see the difference. Where did ninety percent of the data go? We follow an 8×8 block through the discrete cosine transform and quantisation to find out: JPEG sorts a picture by spatial frequency, then quietly bins the fine detail your eyes barely register.
Backprop is just the chain rule
Training a neural network sounds mystical, but the engine underneath is one idea from first-year calculus: the chain rule, applied backwards through a computation graph and reusing its work. We trace a forward and backward pass through a tiny graph, see why we run it in reverse, and connect it to the downhill step that actually does the learning.
How to paint with noise
Image generators start from pure TV static and end with a photo. The trick that makes it possible is wonderfully sneaky: don't learn to paint, learn to remove a little noise, then run that backwards from static. We build the forward noising process step by step, see the signal-versus-noise schedule, and work out why predicting noise is such a clever thing to train.