Infrastructure grows through local decisions. A job needs a queue, a status page needs a data store, an internal tool needs its own deployment path. Each choice may be sound in isolation. The maintenance cost appears later, in the connections between them.
Count responsibilities, not products
A moving part is anything that has to be configured, observed, updated, recovered, or explained. Two services from one vendor are still two operational responsibilities. A single executable with three independent state stores may contain more moving parts than its process list suggests.
Write down those responsibilities before choosing what to remove. This makes hidden costs visible: duplicate credentials, overlapping health checks, separate backup paths, and one-off release steps.
Look for duplicated intent
The safest simplifications often remove two mechanisms that are trying to guarantee the same outcome. Perhaps a retry loop exists both in a client and a scheduled wrapper. Perhaps configuration is generated, copied, and then patched in place. Consolidating the intent is usually less risky than replacing the entire system.
Simplification should reduce the number of things that must be true at once.
Delete in small, observable steps
Remove one dependency or path, then watch the behavior that justified it. Keep a clear reversal path until the new shape has been exercised under normal work. This turns deletion into a measured change instead of an act of faith.
A simpler system is not one with the fewest possible components. It is one where each remaining component has a clear responsibility, a visible failure mode, and a reason that still holds.