- 07 Dec, 2025 *
Here’s something I’ve come to believe about software systems:
The farther apart two subsystems are, the simpler the communication between them should be.
So: let’s say a function passes lots of parameters to another function, calls it 150 times, uses subtle pagination logic with it, or defines complicated data types to govern its interactions with it. This sort of thing is, other things equal, more acceptable if the other function is a directly imported helper than if it requires an API call to a different machine, crosses major abstraction boundaries in the system, or moves between the back and the front ends.
Why believe this?
- Calls be…
- 07 Dec, 2025 *
Here’s something I’ve come to believe about software systems:
The farther apart two subsystems are, the simpler the communication between them should be.
So: let’s say a function passes lots of parameters to another function, calls it 150 times, uses subtle pagination logic with it, or defines complicated data types to govern its interactions with it. This sort of thing is, other things equal, more acceptable if the other function is a directly imported helper than if it requires an API call to a different machine, crosses major abstraction boundaries in the system, or moves between the back and the front ends.
Why believe this?
- Calls between more distant subsystems are likely to be more expensive (for any relevant cost metric). Having fewer, simpler ones keeps costs down, other things equal.
- It’s vastly more difficult to debug communication problems between more remote parts of the system. You might need to work with laggy API calls, through further subsystems (especially authentication), or across team boundaries. Keeping these communications simple reduces the number and cost of these debugging sessions.
- It’s vastly more difficult to test communication between more remote parts of the system.
- The farther apart subsystems are, the more likely they are to be operating with different ontologies. A good way to communicate across ontological differences is to keep things simple.
You can think of this as the Lighthouse Principle. The interactions between lighthouse-keepers and their tools, wicks, manuals, and so on can and should be fine-grained and frequent. Communication with assistants, weather reporters, and suppliers should be coarser-grained and less frequent. Communication with ships must, in general, be much coarser-grained.
This is a special case of the principle to keep complexity local whenever possible. This isn’t always possible, but we underrate how much can be done to achieve this.