The term “complexity budget” is used to explain there’s a practical need for a cap in the amount of energy required to produce a design that is fit-for-purpose:

Any feature added to any system has to pass a basic test: If it adds complexity, is the benefit worth the cost? The more obscure or minor the benefit, the less complexity it’s worth. Sometimes this is referred to with the name “complexity budget”. A design should have a complexity budget to keep its overall complexity under control.

Ken Arnold, Generics Considered Harmful

The idea can also be used to to decide which technical aspects are to be prioritized for a given software development strategy.

It seems that focusing too much on some technical aspects and forgetting others is most likely to cause a lot of pain to any project. The question is: which aspects, if dealt with correctly, are more likely to contribute to the success of a given project?

To answer that question, consider the following two projects:

  1. Project is “awesome”, as it uses nice a programming language plus frameworks and tools. Design is “perfect”, methodologies are used extensively, etc. Continuous integration is somewhat broken, and it takes quite a long time to understand if a given change actually works and that it doesn’t break existing functionality. Due to unstable and slow integration points, builds frequently break due to timeouts and inconsistent behavior, and no work has ever been done to solve that problem.
  2. Project is not that “nice” as it uses an orthodox programming language, frameworks are somewhat outdated, tools work alright, but are not fancy at all. Code and overall design are not amazing, but they are not too hard to understand and maintain. Testing quality is high and continuous integration work flawlessly though, and any changes to the system can be guaranteed to work quickly (in the range of a few minutes) and safely.

If you had to pick one of those projects to work for, which one would it be? If you’re into actually delivering results, you’d probably pick project 2, as it provides the infrastructure to develop features in a sustainable way. If you’re into RDD and/or if you don’t really care about the actual solution you’re building, you’d probably lean towards project 1.

With that in mind, observe the following technical aspects dependencies graph:

dependencies

This basically means that focusing on continuous integration (as in: the ability to quickly make sure the system is ready for production) would force the other aspects to be consistently managed. On the other hand, it doesn’t seem to be the case that spending most of the project’s complexity budget into basic aspects (such as dealing with programming languages and playing with frameworks) and leaving the other aspects aside would create an efficient development model.

It’s troubling to see that so much attention in most projects is given to technical aspects that have limited influence on software quality, whereas aspects such as proper testing and continuous integration are taken for granted and not prioritized. Maybe that’s because the most immediate problems found in developing software are related to coding, leading to a strong focus on “instant gratification” topics, such as programming languages, frameworks, code design, etc. At the same time, it may be counter-intuitive to imagine that “good code” could be produced by focusing on the ability to have the system ready for production at any given point in time.

As far as technical concerns influence the solution quality, your best bet to get a project to succeed is to limit its complexity budget by making sure every single technical choice supports a mode of development that is oriented to quickly guarantee the system is always working. Stay away from the initial temptation to aimlessly play with tools, programming languages and frameworks; focus on continuous integration first, derive the other choices from that, and you won’t get it wrong.