Fundamentals 8 min read

Why Managing Complexity Is Futile: Understanding Complexity Transfer and Local Consequence

The article argues that complexity in software systems cannot be eliminated but only shifted, emphasizing the inevitability of leaks, the limits of local consequence, and the practical value of layering and eliminating duplication to make frequent changes easier and code more understandable.

Architect's Guide
Architect's Guide
Architect's Guide
Why Managing Complexity Is Futile: Understanding Complexity Transfer and Local Consequence

Complexity is an immutable property of software; it can only be transferred between well‑defined parts, making libraries appear simple for users while becoming more intricate for developers.

The author cites two common sources of leakage: runtime costs that cannot be hidden (e.g., SQL performance depends on data layout) and the need to expose low‑level details when debugging kernel or driver bugs.

Consequently, any failure either forces users to "open the hood" themselves or requires the library author to intervene, reinforcing the notion that complexity merely moves around.

Beyond runtime cost, the essay discusses "perceptual" complexity, where code feels like spaghetti due to poor locality. It references Kent Beck’s "Local Consequence" principle, which aims to keep the impact of a change confined to a small, understandable area.

Achieving perfect locality is impossible; trade‑offs arise when organizing code by pages, data ownership, business processes, language versions, market customizations, variable read/write groups, or responsibility domains.

Nevertheless, layering remains valuable: understanding the TCP/IP stack or Linux timers is rare, so shifting complexity to well‑known layers saves time in most cases.

The article also highlights that predicting change frequency is less critical than recognizing that many changes are frequent and should be made easy, even if we cannot foresee them perfectly.

For a deeper discussion see: https://www.jianshu.com/p/d127b8afc8cb

Eliminating duplication further localizes consequences. Successful examples include:

PyTorch generating backward passes from forward passes.

Vue recomputing getters after dependency changes.

React using a single render function with virtual‑DOM diffing.

Airtable’s CRUD forms sharing 90% code.

gRPC generating client and server stubs from a single RPC definition.

When duplication is identified, new frameworks or patterns can remove it, reducing overall complexity even if the effort is substantial.

Finally, the author stresses the importance of trying multiple approaches, as software architecture is a social science with limited long‑term progress; nevertheless, many opportunities for improvement remain.

software architecturecomplexitydesign principlescode organizationlocal consequence
Architect's Guide
Written by

Architect's Guide

Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.