Codebases are Pets, Not Cattle

If you have been around in Software Engineering for the last 5 years, then you have been part of the wider DevOps revolution and all the things that came with it. It is also likely you have heard one of the most famous aphorisms in the DevOps culture: that you should treat your services like cattle, not pets.

I live in Northern Ireland, so I know a few farmers here and there. In fact, I helped John (a family friend) milk his cows at his farm in mid-Ulster a few times back in 2015 and 2017. I had so much fun doing it and I learned a lot about the process, and it helped me understand the DevOps cattle and pets metaphor in very real terms.

For all the purposes of maintaining the cattle on his farm, milk farmers like John treat their cows in batches, with no special relationship to any single one of them. They have tooling and processes in place for cleaning them, vaccinating them, milking them and breeding them, and those involve a big chunk of them at the same time. No cow gets special attention or treatment -- unless they are sick or pregnant -- but even then there is some sort of emotional detachment.

Think about pets now. We name them, play with them, take them on walks or holidays, feature them in our insta and, if you are like me, you probably speak to them as if they were a 5-year-old who speaks your language. My wife and I have such a strong bond with our cat Pua, that we brought her from Chile in the middle of a global pandemic when we moved to the UK.

Back to DevOps world. The metaphor means that in scaled software organizations with a bunch of microservices running there is no time to give each process the special "care" and "attention" they need. You don't deploy them manually, and if they fail you certainly do not restart them manually, and if they need maintenance you do not run the scripts and tasks needed manually. There is no time for that when you have too many services. All those things should be done automatically. Those running processes should be disposable, easily restartable and stateless, among many other things.

But, I'm afraid that this very much-needed shift in managing services has just somehow transpired to managing codebases when it should not be that way. You see, a service is a running process or workload in a server. A codebase is source code in the form of readable plain text. They are very different things.

Codebases need care. They are pets, not cattle. They need all the attention and care you can give them. You have to name them properly, care for them individually, fix them if they are broken, cure them if they are rotting, and upgrade them if they are outdated. You need to design them properly, document them well, write their lines clearly, and structure them simply. Codebases are like that high-maintenance girlfriend, and you should be that loving and caring partner to them. The compiled runtime product that comes from a codebase -- the running process -- is a whole different story: it should be disposable.

Of course, some of the tasks related to a codebase's maintenance can still be automated, but the love and tender care they need is there nonetheless. I still love my cat even though I automate her feeding twice a day with the exact amount of food she needs with this amazing automatic cat feeder that I recommend everyone who has a cat to get. Codebases are like that too. Although we automate their build, testing and deployment, and maybe some routines in development, every single one of them needs a slightly different CI pipeline, test suite, dependable configuration or Makefile targets.

I think the industry has missed this important distinction, and good things and practices like incremental refactoring, good application of software design principles, robust testing suites, flawless development experience and strategic upgrading paths are at risk of being disregarded even more than they are today. They are slowly being replaced by inflexible templated approaches and blueprints or all-invasive frameworks that try to abstract away the tedious parts or make up for the lack of design. V2 or v3 rollouts of the same service or thing are frequent in this kind of environment, because now the codebase is seen as cattle, and something quite disposable. Sooner or later an explosion of codebases is added, on top of an explosion of services. Is easy to automate managing services and workloads -- thank you K8S -- but you cannot really manage or grow codebases automatically -- at least not today. So, a growing number of codebases is a real scaling problem you don't want to have.

Source code is the biggest asset of a software company -- no matter how much low-code advocates rant about the contrary. We should treat our code how it deserves: with the special care of a pet, and not with the disregard for cattle. Clean code scales; you just need to invest the time and care to produce it.

Did you find this article valuable?

Support Matías Navarro-Carter by becoming a sponsor. Any amount is appreciated!