Within the forests of New Caledonia grows Tmesipteris oblanceolata, an innocuous plant that easily escapes notice due to its small size. However, this fern possesses a remarkable secret: it contains the largest genome ever recorded with over 160 billion base pairs, more than 50 times the size of the human genome. Plus, it’s an octoploid species, reproducing with eight sets of chromosomes, in contrast to humans’ two.
Its massive genome isn’t the product of design or advantage, but of incidental complexity, a slow accretion of viral DNA and chromosome duplications. Inhabiting a stable, low-competition ecological niche, this fern faced little pressure to streamline its genetics, so it remains as-is despite the challenges posed by such size: slower reproduction and higher energy requirements.
Reading about this fern with a ridiculously large genome reminded me of the idea of managing software complexity discussed in Rich Hickey’s presentation, “Simple Made Easy” (I am sure you all had the same thought). Hickey distinguishes between simplicity (the absence of unnecessary interleaving or complexity) and ease (solutions that are immediately accessible or require minimal mental effort). Quick solutions seem ideal in the short term but overreliance on taking the path of least resistance can lead to accumulation of incidental complexity. Gradually, systems become less maintainable and harder to reason about, resulting in slower project velocity.
In nature, this fern exemplifies what can happen when complexity accrues unchecked. It survives due to its isolation, carrying the burden of an extraordinarily complex genome; a tolerance that most living organisms, and most software systems, cannot afford.
Incidental vs Intrinsic Complexity
In software, intrinsic complexity is the inherent difficulty of the domain: business rules, user requirements, or performance constraints. These challenges require thoughtful and novel solutions from engineers but even with strong engineering, they demand time and focus to learn and understand. Even the most well engineered software systems can seem daunting and confusing due to this.
On the other hand, incidental complexity arises from the optional choices made during implementation that make the codebase harder to work with, like layered abstractions, nests of conditionals, and excessive caches. Such complexity is often the byproduct of opting for the easy and more immediate solution.
Finding truly simple solutions is hard. They take time and may require revisiting core assumptions, data models and flows in the application. These solutions often lead to short-term velocity decreases in order to unlock longer term understandability and productivity.
Selective Pressure in Software
Just as selective pressure discourages excessive complexity among organisms through competition, software products compete against each other too. Products with limited competition or robust brand loyalty may withstand slow iteration or internal inefficiencies. However, most live in more competitive environments; customers will switch to a competitor’s product unless the software continually advances to offer new functionality at a high quality. Rival products that innovate and adapt quickly can erode your customer base. This is why it is important to stay focused on investing in the simple solutions, so your applications don’t get bogged down under their own weight.
However, the realities of software products don’t always offer the privilege of taking the time to find the truly simple solutions right away. Given deadlines and immediate customer needs, engineers (who are often aware of what the simple solution is or that it can be found) must decide to make reasonable trade-offs to balance other priorities.
For example, adopting the easy fix may be warranted to address urgent needs, customer issues or key deadlines. However, everyone must be aware of the cost paid in doing this. Increasing the system’s overall complexity, adding cognitive load and increasing the number of edge cases. Each easy fix adds incremental complexity and technical debt. This is akin to numerous examples in evolutionary biology where an organism accrues sets of mutations that enable short-term benefit but lead to disadvantage down the line like Darwin’s finches, for instance, whose beak sizes oscillate with the shifting pressures of drought and rain.
A decision not to pursue the simple solution requires the team to acknowledge the impact (which I discussed in a previous post) and decide if the team (and the product) can live with this lack of simplicity forever or must hard commit to a concrete follow up soon. Discerning which complexities are tolerable versus which require immediate work towards the simple solution is a crucial skill for sustaining development velocity and system health. The team must periodically reflect over how often they have opted for the easy path and if this is leading to systemic problems in maintainability and velocity. Without deliberate reflection regarding whether deeper, structurally simple solutions must be pursued, organizations risk developing a genome like our favorite fern’s: functional, yet increasingly burdensome.
Conclusion
Incidental complexity is inevitable in both natural organisms and engineered systems. Unlike our tiny fern, whose survival hinges on environmental isolation, software projects seldom enjoy the luxury of operating without external pressures. Vigilantly distinguishing between easy fixes and truly simple solutions is vital to ensure continued innovation, responsiveness, and longevity in a competitive landscape. Nature has billions years to figure out this balance, your software project doesn’t.

