DevOps

Why is global state such a problem?

Why is mutable global state considered so harmful in programming?

Asked on Stack Exchange,

Because it makes behaviour unpredictable from what you can see. Given the same inputs, a function that reads shared mutable state can behave differently depending on what some unrelated part of the program did earlier — which is also precisely what makes it hard to test.

The core objection

The accepted answer builds it carefully. If two components share a mutable global, then knowing the state of the system before a call is no longer enough to predict the result, because something else may have changed it in between. Predictability is not an aesthetic preference — it is the property that lets you reason about a piece of code by looking at it, and the property a test depends on to produce the same answer twice.

What follows from that

  • Bugs that can originate anywhere. Mutation from any point in the program means the cause of a wrong value can be arbitrarily far from where it surfaced.
  • Tests that need setup. Every test has to arrange the global state first, and has to restore it afterwards or contaminate the next one.
  • Hidden dependencies. Nothing in a function's signature reveals that it depends on the global, so the compiler cannot warn you and a reader has to go looking.

Why it gets worse over time

One answer made the point about maintenance rather than correctness. Because anything in the program may be using it, a global becomes progressively harder to remove — and any change to it potentially requires changes everywhere. Finding the callers is not the difficulty; the difficulty is that there is no boundary limiting how many there can be. It is a decision that becomes more expensive to reverse the longer it stands.

The distinction worth keeping

  • Mutable global state is the target of every objection above.
  • Global constants share none of these problems, because nothing can change them between one call and the next.
  • The practical rule the thread points at: if it is shared and it changes, pass it explicitly so the dependency is visible.