If you apply small, but relatively frequent stress to a muscle, then over time it will adapt and grow stronger. We don’t frequently talk about it in the context of software development, but I believe it holds here too. By frequently applying small amounts of stress to our software and processes, we can greatly improve them over time.
If you look at the practices that exist today, you’ll find plenty that follow this principle. When doing continuous deployment, we deploy automatically on a frequent basis, often even on every commit to master. Each deployment applies a little bit of stress. And sometimes… things will break! But that danger is what helps us make our process more resilient. Would you rather deploy a huge change once a year, with the risk of a massive downtime that's hard to recover from? Or, do you deploy small changes, many times per day, with each potential issue helping you learn more about your deployment process? I know which one I prefer.
Of course, at first, switching to this flow can be pretty scary, and probably for a good reason. There are many things that can go wrong if you aren’t used to deploying that frequently. If you only workout once a year, you may get hurt if you’re careless. However, once you commit to moving towards more frequent deploys, you’ll learn to tackle these issues one by one. Note that you don’t have to deploy on every commit from day one, you could just deploy once per workday or per week initially. And, of course, depending on your context, there might be constraints which prevent you from reaching the “deploy-every-commit” state, but the principle still holds and it’s still valuable to deploy as frequently as you can afford.
I see another application of the principle of “software as a muscle” in services that automatically update your dependencies, like Dependabot or Depfu. These services watch your dependencies for new releases and then automatically make a pull request with an attached changelog. As a result, we end up with frequent and smaller dependency updates, instead of the semi-regular “Let’s update all the libraries and see what breaks”. Again, there are more frequent smaller stresses, and something may break occasionally, but this helps us improve over time. Our software stays up-to-date and will be more enjoyable to work with, given the more up-to-date dependencies.
Similarly, I see the idea at play in the Chaos Monkey tool built by Netflix. Quoting their README file:
Chaos Monkey randomly terminates virtual machine instances and containers that run inside of your production environment. Exposing engineers to failures more frequently incentivizes them to build resilient services.
Finally, I believe it’s also one of the principles that makes Test-Driven Development valuable. By adding tests to our code, we apply a bit of stress to it, which verifies that the code behaves as we expect it to. When we apply changes to the code in the future, those tests again will verify whether we are not breaking anything.
If you see any other places in software were this applies, please let me know! I’d love to hear from you.