Thinking Top-Down in a Complex World
Posted on February 26, 2026 • 7 min read • 1,364 wordsTop-down thinking is no longer optional: from declarative languages to modern DevOps, this article explores the mental model required to face complexity.

When we observe how we design complex systems today — DevOps infrastructures, distributed platforms, modern software, or even educational pathways — we almost always find the same intellectual tension. On one side, there is a progressive and incremental approach, which starts from the basics and moves toward something more elaborate. On the other, there is an outcome-oriented approach, which begins by defining a goal, then works backward to determine what is needed to achieve it.
These two ways of thinking are not opposed. They respond to different constraints and have coexisted for a long time. Yet as complexity increases, we can clearly observe reasoning shifting toward a goal-oriented approach. Modern DevOps is one of the fields where this shift is especially visible.
Bottom-up reasoning consists of starting from the simplest elements and assembling them progressively. In infrastructure, this historically meant installing servers, configuring operating systems, deploying services, and only at the very end making an application run. In programming, we first learn variables, then functions, then modules, before truly understanding the overall system. In school, we accumulate fundamental knowledge for years without always clearly seeing what it is for.
This approach has undeniable strengths. It helps build solid foundations, a precise understanding of primitives, and a certain intellectual robustness. It is well suited to simple or relatively stable systems, where interactions remain limited and predictable.
But as complexity increases, its limits become visible. The overall meaning becomes blurred, prioritization grows difficult, and motivation fades. We know how to do things, but we no longer clearly know why we are doing them. The system works, but it becomes difficult to explain, evolve, or adapt to a new objective.
By contrast, top-down reasoning begins by defining a desired final state. The initial focus is not on the means, but on the expected result, on the objectives. In DevOps, this takes the form of a simple but structuring question: what service must work, and with what guarantees?
Once that objective is established, we gradually identify the necessary dependencies required to make it possible. Technical choices stop being arbitrary. They become the logical consequences of the stated goal. Prioritization becomes natural, because anything that does not directly contribute to the goal can be questioned.
This mode of reasoning requires a certain conceptual maturity. It assumes the ability to formulate a clear objective, to accept that the path toward it may evolve, and to think in terms of dependencies, rather than fixed sequences of actions.
These two approaches can be understood as two different readings of the same conceptual object: a dependency graph. Each node represents a building block — a service, a skill, a component — and each edge expresses a dependency relationship.
Bottom-up reasoning traverses this graph from the leaves upward toward increasingly higher levels. Goal-oriented reasoning, on the other hand, starts from a final node and explores only the dependencies necessary to make it possible. These are not two different worlds, but two complementary paths through the same graph.
This model is everywhere in modern CI/CD pipelines, build tools, and orchestration platforms. It is the true conceptual foundation of contemporary DevOps.
This goal-oriented way of thinking is not limited to DevOps. It is deeply embedded in certain programming languages and formal systems, which have long embodied this fundamental separation between what and how.
In these approaches, the developer does not describe a sequence of actions to execute. Instead, they describe a set of facts, rules, or constraints, and then formulate a question or goal. The system then takes care of deriving a solution that satisfies those constraints. We no longer program a path — we declare an intention.
Prolog is the most emblematic example of this way of thinking. In Prolog, we never say how to reach a result. We simply describe what is true, and then ask a question.
needs(service, database).
needs(service, network).
needs(database, storage).
?- needs(service, X).There is no explicit algorithm here, and no execution order.
There are only dependency relationships. When the question is asked, the logic engine explores the implicit graph formed by these relationships and deduces what is required.
The reasoning is exactly the same as the one used by modern DevOps systems:
“Here is the goal. Tell me what must be true for it to hold.”
Prolog is not an isolated case. SQL, Datalog, and other declarative languages rely on the same fundamental idea. When we write an SQL query, we describe the expected result without ever specifying how the database should traverse its indexes or optimize its execution plan.
The engine takes care of solving the problem.
This logic is everywhere, but often invisible. It always relies on the same principle:
the intention is explicit, the path is implicit.
Modern DevOps tools are not always seen as languages, yet they operate according to exactly the same principles. Terraform, Kubernetes, Nix, or even Ansible ask the user to describe a desired state. Once that state is defined, an internal engine takes care of resolving dependencies, ordering actions, and converging the real system toward the target.
The difference from traditional imperative scripts is fundamental. The system does not store a sequence of orders, but an objective to maintain over time.
Kubernetes, for example, defines a target state, continuously observes the actual state, and applies reconciliation loops to correct deviations.
Infrastructure then becomes a living graph, maintained in coherence.
In this context, acceptance tests and monitoring take on a new meaning. Acceptance tests are no longer just one-time checks before deployment. They become the formal expression of the system’s invariants, directly derived from business objectives.
Monitoring then makes it possible to continuously observe whether the real graph still respects these invariants. It is no longer simply about watching isolated metrics, but about verifying that the global state of the system remains aligned with the original intent.
Traditional education relies heavily on a bottom-up approach, and this choice is not accidental. School must address the greatest number, form citizens before specialists, and keep open the widest possible range of future paths. An overly goal-oriented approach too early on could lock in immature choices and exclude certain profiles.
The problem, then, is not the existence of bottom-up thinking, but the lack of perspective. Knowledge is taught without being connected to possible purposes. Yet it would be possible to preserve a generalist education while still making explicit the skill graphs, the potential outcomes, and the meaning of learning.
The point is not to replace the current approach, but to enrich it with a goal-oriented reading. Exactly as in DevOps, where shared primitives take on their full meaning once they are connected to a final service.
Bottom-up reasoning remains essential. It provides the foundations, general culture, and technical robustness. But on its own, it is no longer enough to master complex, distributed, and evolving systems.
Modern DevOps, declarative languages, resolution engines, and contemporary engineering all converge on the same idea:
start with the goal, reason in dependency graphs, and let the mechanisms adapt in order to achieve the objective.
Knowing how to navigate between these two modes of thought — building solid foundations while keeping a goal-oriented vision — is probably one of the most decisive skills of the modern engineer.
Prolog and logic programming An excellent entry point for understanding declarative programming and deductive reasoning. Prolog illustrates in a very pure way the separation between intention (what must be true) and the resolution mechanism.
Terraform – Declarative Infrastructure as Code A clear introduction to Terraform and to the way modern infrastructure is described as a target state, leaving the engine to resolve dependencies and ordering.