We like efficiency. When I need to repair a shingle and clean out the gutters, I want to do this in a single trip to the roof. When I do laundry, I move two loads along in each trip to the basement. When my app needs its dependencies upgraded, I upgrade a bunch at once… right?
We like batching. Batching is more efficient doing ten at once is faster than doing one, one, two, one, one, etc. I don’t wash my socks as soon as I take them off, because lumping them in with the next load is free.
Is it more efficient to save the shingle repair until it’s time to clean out the gutters? Unclear.
In How Buildings Learn, Stewart Brand offers the following model of building maintenance costs:
It shows Preventive Maintenance as a series of small costs. Minor repairs are a series of bigger costs, and major repairs are much bigger than that. Every maintenance delayed escalates into a minor repair and then a major repair — costs increase nonlinearly with time delay.
If I wait until Spring to repair the shingle, will water leak into the attic and cause more damage? What if I don’t get around to cleaning the gutters this year? We’ll just clean out twice the leaves next year, that’s it! Oh nooooooo, now I have water damage and need major repairs. This costs way more than three trips to the roof.
When costs increase nonlinearly with delay or batch size, larger batches are not more efficient.
It’s like DevOps and CI/CD: more frequent deploys are safer. This happens because each deploy contains fewer changes. Each change might cause a problem, and each change is suspect when there’s a problem. 1 change, 1 problem? 1 suspect. 2 changes, 1 problems? 2 suspects. 17 changes, 3 problems? 51 suspects — yikes!
This is a nonlinear relationship. The changes interact, and so batching them up increases the cost of the batch by more than the cost of the change you’re adding. Batching is less efficient.
It’s like if your sock wanted to eat the other laundry, so the more things you put in with it, the more time you’d spend getting the load sorted out. (That doesn’t make sense, but it is kinda funny.)
Batch when incremental cost decreases with batch size.
Batch your laundry. The socks and shirts and washcloths get clean independent of each other. Caveat: this assumes you have enough clean socks to keep your feet warm in the meantime.
Don’t batch when time delay increases the risk.
This happens in home maintenance, and in deploys. Keeping features back delays adding value. Slow rollout of library upgrades leaves you open to published vulnerabilities. Water leaks or data leaks can result.
Do not batch for efficiency when costs increase nonlinearly with size!
Because changes interact, the cost of a deploy increases with each change by more than the cost of deploying that change individually. This is also true of library upgrades. When you upgrade one library, and there’s a problem, you have a decent idea of what caused it. Not a perfect idea, because there are all those transitive dependencies that upgraded (boo). Still, it’s better than upgrading several libraries and then hitting at least one problem. This is much harder.
Do upgrades immediately, not in batches. This keeps your app as secure as you can, and makes your job easier.
There’s nothing fun about upgrading libraries. It is a lot of work to take the ladder out of the garage and climb onto the roof. But it keeps your house from leaking water, or your code from leaking user credentials to attackers. If you don’t do it today in the sun, you’ll do it when your bedroom ceiling drips water on your sleeping face, or when you have to announce the breach to the press.
Do the easy boring job regularly, instead of the hard scary job in a panic.