Everything in Between Is Noise

There are four things a software engineer needs to know:

  • Engineering – smashing things until it works
  • Science – studying, observing, measuring, taking notes
  • Market – the buyer, the resource, the cost, the revenue
  • Architecture

Here, I’m going to talk about the fourth one, architecture. But what is it exactly?

Ask a few engineers and you’ll get a few answers. Some think about code structure and dependencies. Some picture servers, databases, and APIs talking to each other. Others look at how systems line up with business goals.

IEEE says it’s “the fundamental organization of a system embodied in its components, their relationships, and the principles guiding its design and evolution.”

Martin Fowler says it’s “decisions that are hard to change later.” This is my favorite definition by the way.

Both point to the same thing: impact over time. Architecture is about shaping what stays flexible and what can’t move easily. And it’s not always abstract — a low-level detail can carry architectural weight if it changes how the whole system behaves.

Software lives between two shifting ends: requirements and resources. Engineering builds the bridge. Architecture figures out how to keep rebuilding it as both sides move. Everything in-between is noise.

Over time, a few lessons tend to repeat themselves.

Low-level choices are what actually interface with the resource. Interfaces, data formats, or threading models — they set the performance, cost, and cohesion. In novel distributed systems, this is even more significant because what we often see as “low level” cannot be abstracted away there — things like eventual consistency or consensus.

When we ask “Will we need this?”, it’s worth also asking “Will we not need this?”. That second question is important because it forces us to think about future extensibility. This decides whether we can grow easily on top of what we have or end up rebuilding everything and halting progress. It also nullifies the risk where the first question leads to oversimplification and introduces a waterbed effect — where complexity is pushed down in one place and rises somewhere else.

Requirement before implementation. Strategy before requirement. Vision before strategy. Often, we engineers are presented with primitives for implementation details, and these occupy our minds for most of the day until they slowly start becoming our source of truth instead of the higher purpose. Keep the vision in your mind.

“Compartmentalize, but don’t infantilize.” Often, as architects, we want to build some kind of secure containment so that things don’t break. However, we should not take away agency from engineers. If we take agency, not only does it cloud their sense of vision, but it also takes away their motivation. We should instead enable them to move fast by providing safety nets and helpers. You can see this reflected in inversion of control, containerization, the rise of static types, explicit and type-safe error handling, and portable computation — patterns that let components act freely but in harmony with their surrounding system.

Look for paradigm changes. Focus on the rewards, not the obstacles. If there’s a new paradigm in town, get a feel for it and extract what is good. Look at what we’re doing wrong and what they’re doing right — and vice versa. There’s a reason FP and Rust gained such a strong, almost cult-like following.

And this last one might be the hardest: never say something “can’t be changed” because the code says so. That’s a taboo for architecture. If a business change feels impossible, it’s the structure that needs to adapt. Architecture exists to make change easier and safer.

In the end, architecture isn’t about authority or elegance.

It’s about keeping the system — and the people who build it — free to move when it matters most.