The load never goes away in these graphs - the load is a constant sinusoid that's not actually shown on the graph. The blue line is queue depth.
You are right that it's not unloading. In general, you'd expect the response (green line) of a PID controller to a sinusoid load to be another sinusoid. In this case, because the maximum error is bounded on one side(the setpoint is 0, and queue length can never get below 0), it can only unload at a certain rate. It's typically the job of the Ki term to bring the long-term error towards zero. In this case, I think it's tuned small enough + the bounded asymmetric maximum error to result in it never unloading.
The one axis isn't instantaneous workload; it is queue length(work items not being handled by threads).
The PID controller is finding a reasonable number of workers that handle the peak bursts without allowing the queue to get too long, and without spamming and destroying threads unnecessarily.
The cost is that under peak load the queue does back up a little, but if the queue stayed long for too long, the PID should create new threads.
The spikes are queue length (which we want to control), not load. The load is not shown. Any queue length under 20, including spikes, is fine based on the author’s requirements.
The other line, which flattens out at 26 (see right y axis) is the number of workers.
Good question! At first I thought that maybe I wasn't waiting long enough after the load generator finished, but I just ran an experiment with a longer pause and I still don't see a scaling down after the traffic stops!
Perhaps my naive implementation of the PID controller isn't good enough, maybe:
> you'll probably want to put a maximum on your integral accumulator
Is that intended? Or I'm misinterpreting the graphs?