DEV Community

Imran Siddique
Imran Siddique

Posted on Originally published at Medium on

Every Dependency Is a Promise Your System Has to Keep

Scaling starts with examining how many things must go right for a customer to succeed.


Illustration generated with AI.

A checkout request arrives. Before the customer sees confirmation, the system checks inventory, authorizes payment, fetches recommendations, updates loyalty points, and sends an email.

Each integration has a reasonable explanation. Together, they raise an architectural question: why should buying something depend on all of them working at the same time?

That question belongs near the beginning of a scaling discussion. It determines how much work we need to scale in the first place.

I think architecture reviews should give more attention to the conditions we attach to a successful customer outcome. Every synchronous dependency introduces another reason that outcome might be delayed or fail.

Adding capacity can help a system do more work. We should also examine how much of that work belongs on the critical path.

A useful unit of architectural complexity is the number of things that must go right together.

The critical path is a business decision

Consider the checkout example as a hypothetical design.

Inventory and payment affect whether the business can accept an order. Recommendations usually do not. An email can arrive after the order is recorded. Loyalty points may tolerate a short delay, depending on the product’s rules.

If these operations all block confirmation, the architecture has given them equal power to interrupt a purchase. That is a business decision, even if nobody explicitly made it.

Moving email off the critical path changes that decision. Customers can complete an order while the notification service is unavailable.

But the obligation to send the email still exists. It needs durable recording, retries, duplicate handling, and a way to detect messages that never arrive. Asynchronous processing introduces its own machinery.

The trade is worthwhile when separating those failure modes matters enough to justify that machinery. A queue earns its place through the independence it provides.

This is why counting services or boxes on a diagram tells us so little. A system with fewer components can still force unrelated operations to succeed together. A system with more components can isolate failures well, or simply distribute the same dependencies across a network.

The more useful measure is what happens to the customer when one component stops working.

Subtraction has a correctness floor

There is also a limit to subtraction.

Removing duplicate work can improve efficiency. Removing the check that prevents a duplicate charge changes the meaning of correctness. Both might reduce latency. Only one preserves the promise made to the customer.

Before simplifying a workflow, I would write down its non-negotiable properties in business language:

  • No duplicate charges. Retrying an order must not create a second charge.
  • Durable confirmation. A confirmed order must survive an application restart.
  • Customer isolation. One customer must never receive another customer’s data.

Those statements establish a floor beneath the optimization work. The team can change implementation, sequencing, and infrastructure while preserving the properties that make the service trustworthy.

Review the journey, then the components

This gives architecture reviews a more concrete starting point.

Take one important customer journey. Identify everything it waits for. For each dependency, explain why its result is necessary before success can be reported. Then examine what happens when it is slow, unavailable, or returns an ambiguous result.

Some dependencies will deserve stronger protection. Some can move later. Some may exist because an old feature or assumption was never retired.

The resulting work may be less visible than a platform migration. It can still produce a substantial architectural improvement: fewer opportunities for unrelated failures to interrupt the same customer action.

Make simplification visible

Leadership incentives matter here. New infrastructure has a launch date and an owner. Removing an unnecessary dependency is easier to overlook. If we want teams to simplify, we need to recognize outcomes such as fewer coordinated releases, fewer failure modes reaching customers, and less operational work per completed transaction.

The same reasoning applies when adding AI to a workflow. If a model becomes another blocking dependency, its latency and availability become part of the customer’s experience. Its place in the architecture should follow from the value of its contribution and the behavior required when that contribution is unavailable.

Before approving the next component, I would ask the team to show which customer promise requires it, what happens when it fails, and which existing responsibility it replaces. Those answers make the cost of the decision visible.

This is the thinking behind Scale by Subtraction, which I explore in my book, Architecting at Scale.

Top comments (0)