Key Considerations for Software System Design

June 25, 2026

This is the checklist I return to when I design a system or review an architecture. It is not a methodology. It is a set of considerations from a personal viewpoint.

1. Functional Architecture: Horizontal layers

Start with functions and capabilities of the system or platform. Who are the users or customers? Reference models provide a shared vocabulary and a map of the territory. Four categories cover most ground:

The application architecture has three parts worth separating:

Keeping these distinct stops a common failure: business logic hard-coded into configuration, or data assumptions buried in control flow, where nobody can find them when the rules change.

2. Second the non-functionals

The Twelve-Factor App is a good baseline for the build-and-run side of this.

You will not max out every one of these. The point is to make the trade-off on purpose. An unstated non-functional is a decision made by accident.

3. Align with the organization's strategy

If your organization has a technology or software vision, your design should pull in the same direction. A locally optimal architecture that fights the company's platform strategy is a future migration waiting to happen. This is not about compliance for its own sake. It is about not building the one system that has to be rewritten when the broader strategy lands.

4. Let teams move independently

The goal of a good decomposition is that a team can test and deploy its component or service with little or no coordination from other teams.

Two design choices make independence real:

5. Design modules to hide what changes

General guidance for modularity Parnas, from 1972: begin with a list of the difficult design decisions, or the decisions most likely to change independently. Then design each module to hide one of those decisions from the others. Modules are not chapters of a story. They are firewalls around the things you expect to revise.

A corollary I lean on: when two alternatives deliver roughly the same value, take the one that makes future change easier. Cheap optionality is worth buying.

A few more principles belong here:

6. Categorize your decisions

Not every design decision deserves the same care. Sort them along three axes, and the right amount of effort becomes obvious.

7. Go API-first and SaaS-style

Treat every service, including UI applications, as something reachable through an API. Going API-first forces clean contracts and makes the system composable. Design the API before the rest of the functionality. Ensure a SaaS posture is a property of the system when applicable: capabilities are exposed as services, the system is multi-tenant by design, and anything that can be a self-service API is one. A platform that needs its owners in the loop for every new user does not scale to many users.

8. Transition Architecture: Make execution part of the design

Decide the rollout strategy alongside the architecture.

9. Govern with light templates

Governance fails when it becomes paperwork and fails differently when it is absent. The middle path is a few standard templates and a process for using them.

Closing

Use this as a set of lenses to hold up to a design and spot what is missing. The non-functionals you did not name. The decision you treated as irreversible when it was not. The module boundary drawn around a story instead of around a thing that changes. The contract that quietly coupled two teams.

Good architecture is mostly the discipline of asking the boring questions before they become expensive ones.

← All posts

This is a personal blog. Views expressed here are my own and do not represent any employer, client, or organization.