Hexagonal Architecture

An examination of hexagonal architecture: which parts of its structure the domain’s knowledge mandates, and which parts it invents.

Hexagonal architecture — Ports and Adapters — puts an application core at the centre and surrounds it with ports and adapters. A port is an interface the core defines; an adapter is the mechanism that fits it — HTTP, a message queue, a database, a payment rail. The core does not know the adapters; the adapters know the ports. Cockburn’s stated goals are that the application can run with no user interface and no database, for testing, and that mechanisms can be swapped [1].

Cockburn is explicit that the hexagon is a drawing convention — the shape is “not a hexagon because the number six is important,” but to leave room to draw the ports around the edge; and what a port is “is largely a matter of taste” [1]. So the question is not whether it admits to being a design. It does, openly. The question is which parts of it embody the domain’s knowledge and which parts it invents.

This page applies the same test used for onion architecture, clean architecture, and layered architecture: does the domain’s change-driver structure mandate the cut?

1 At a glance

Underlying principle Succeeds when Fails when
Hexagonal treats the core and the integration mechanisms as two disjoint change-driver sets, with a port between them. The core’s change drivers are disjoint from the adapters’. A change driver reaches across the port — a persisted entity’s field, whose state and mapping carry the same assignment. The port then splits one class.

2 The claim

The core holds the application’s rules. The ports are the interfaces it defines for what it needs. The adapters are the mechanisms that implement the ports: a web controller on one side, a repository on the other. Dependency direction is the point: the core does not import an adapter; the adapter imports the port.

3 Hexagonal’s axis is core versus mechanism

Hexagonal’s axis is a structural split: core domain versus integration mechanism. It is not a frequency ordering or a policy ordering; it is a claim that the core’s elements and the mechanism’s elements are two kinds.

Cockburn’s justification is engineering: test the core without a database or a user interface, and swap mechanisms without touching the core. Those are goals, not domain knowledge. IVP groups by which change activates an element. Core-versus-mechanism is a proxy for that: the core’s change drivers differ from the adapters’ when the domain separates them, and only then [2]. So the axis can coincide with the partition. It does not determine it.

4 The ports are not in the domain’s analysis

No business analysis or functional analysis organises knowledge as a core with ports and adapters. Analysis names rules, entities, processes, events, and decisions. Cockburn derives the inside from the outside and places the ports from the use-case context; but a use-case set names operations, not ports. The port — the interface, and the indirection it carries — appears when a designer lays out code; it is an encoding. Absence from the analysis is evidence, not the test; the test is coincidence with the partition.

5 The core is not independent of the mechanism

Hexagonal’s strongest claim is that the core is independent of the mechanisms. That is a claim about the direction of reference. Hexagonal exists to isolate change, so the coupling at issue here is change coupling.

Under the framework’s reading, if recording a new domain fact is taken as one change driver covering the field, the column, and the wire field, then a persisted entity’s state and its mapping carry the same change-driver assignment. Hexagonal puts the entity type in the core and its mapping in an adapter. The port boundary therefore runs through one Γ-equivalence class. It separates the entity type from its mapping and splits that class — a Unit Completeness failure. It is exactly the failure the core-is-independent claim is meant to prevent. The core is not quiescent: under the framework’s reading, it is coupled to the very mechanism the port was meant to hold away.

6 What hexagonal embodies, and what it invents

Two parts are worth separating.

  • The dependency direction — the core owns the port, the adapter implements it — is a claim about direction, not about the cut. Dependency inversion changes placement only; it adds, removes, and transmutes no change driver. Direction is domain-determined only where the domain itself orders the elements: where one element’s requirement is chosen to satisfy another’s. Where it aligns, the rule adds no structure; where it does not, it asserts a direction the domain does not have.
  • The ports and adapters are a claim about the cut. The port, the adapter, and the core/mechanism boundary are not in the analysis; they are concepts the designer adds.

A representation is unavoidable; what is not unavoidable is inventing a concept — a named kind, boundary, or category — that the knowledge does not contain. A port is such an invention exactly when it does not coincide with a change-driver class. If the boundary groups elements with different change-driver assignments, it invents a unity; if it splits elements with the same assignment, it invents a division. Only a boundary that coincides with a Γ-equivalence class is not an invention, and then it is a redundant name for a real class.

By IVP’s foundational claim, the change-driver partition is the domain’s only organising knowledge [2]. Faithfulness admits no concept that does not correspond to a Γ-equivalence class; any structure beyond the partition is deviation, and deviation is the accidentality.

7 The split is not the style

The proof is in the artifacts. Grouping by change driver yields the partition; an engineer who embeds the domain faithfully, and who has never heard of hexagonal, arrives at the partition. She may isolate the core from the mechanism because that is a natural impulse, but the port-and-adapter scheme, and the inversion it carries, are a taught pattern.

Non-spontaneity is evidence, not proof, that a structure is a convention and not knowledge. Hexagonal fails wherever the port straddles a Γ-equivalence class — the persisted entity, for example. The encoding is the designer’s, the partition is the domain’s.

8 The IVP account

IVP groups elements by change-driver assignment: elements with the same assignment belong together. A module is pure when all its elements share one change-driver assignment set [2]. Judged by that standard, the core/mechanism cut is correct where no class straddles it and no two non-equivalent elements are grouped.

For a persisted entity, it is not correct; off the partition, the decomposition is wrong under the change-driver criterion.

9 When hexagonal is beneficial, and when it is harmful

The theory is not maintenance-only. Each concern the system must respect — logical structure, security, deployment, platform, a latency budget — is, once modelled as knowledge governed by change drivers, a partitioning rule over the same element set. IVP is one such principle, and not the only one: grouping by the full change-driver set (Γ-equivalence) is the common refinement of the concerns’ rules, correct under every one at once [3]. The claim is a re-description, not a proof that no other kind of principle exists. So hexagonal answers to one decomposition, not one per concern.

Hexagonal does no harm only where its port boundary coincides with that decomposition. Where it does not, every change crosses a boundary the domain did not set: a class split across the boundary scatters one change, and a boundary that groups non-equivalent elements couples what the domain keeps apart.

Two caveats bound the claim. The cost model is separate, and it models maintenance cost: the partition minimises total maintenance cost under the coefficient condition the model states, unconditional only in the pure, disjoint change-driver case [4]; whether the metric matches real economic cost is empirical. And the theory does not discover the rule: identifying the domain conditions and building the partition is a separate domain-analysis task [3]. A concern left out of the model is a requirements gap, not a cohesion judgement.

Beneficial, here, means only that hexagonal does no harm: its port boundary coincides with the change-driver decomposition. It still adds no decomposition of its own. Outside the band, hexagonal is harmful wherever its boundary does not coincide with the partition.

10 Beyond placement: faithful embodiment

The theory separates three properties: placement — the right knowledge in the right modules — which is what cohesion measures; faithful embodiment — each piece realised as it requires; and dependency parsimony — the dependencies are the ones the purpose requires. The three are independent [3].

Correctness is the second alone. A system satisfies an obligation exactly when every knowledge piece the obligation constrains is correctly embodied by some element; placement does not enter. So cohesion governs the cost of achieving and maintaining correctness — the scope to read and the radius to change — not whether it holds. A module can be placed exactly right and still compute a rule with the wrong formula.

Hexagonal can clear placement and fail this. Nothing in a port checks whether the code realises the knowledge it carries, and the port diagram looks the same.

Hexagonal is fully sound only when it clears every bar: its boundary coincides with the change-driver decomposition, and the code realises the domain’s knowledge faithfully. Alignment without embodiment is a system placed correctly and still wrong about its domain.

11 Summary

  • Hexagonal architecture puts a core behind ports and adapters, with the core owning the interfaces and the adapters implementing them. Its stated axis is core versus mechanism.
  • IVP groups by change driver, not by core versus mechanism. The axis is a proxy; dependency inversion changes placement only.
  • The ports and adapters appear in no analysis artifact; a use-case set names operations, not ports.
  • The core is not independent of the mechanism: under the framework’s reading, a persisted entity’s state and mapping carry the same change-driver assignment, so the port boundary splits one class (a Unit Completeness failure).
  • Where the boundary coincides with the partition, hexagonal adds nothing; where it does not, it invents structure the domain did not mandate.
  • The strongest defensible claim: hexagonal’s ports and adapters are invented concepts except where they coincide with the partition. Its decomposition value is the partition, which one can obtain without it.
  • Hexagonal does no harm only where its boundary coincides with the change-driver decomposition; it is harmful where it does not. Placement is not faithful embodiment.
  • IVP is one modularising principle among those the system’s concerns induce; Γ-equivalence is the common refinement of them. The theory is a re-description, not a proof that no other kind of principle exists.

Compare onion architecture, clean architecture, and layered architecture.

Back to the verdict ledger.


The formal development. The definitions, theorems, and proofs behind this page are published in:

All published papers

References

[1]
A. Cockburn, “Hexagonal architecture.” https://alistair.cockburn.us/hexagonal-architecture/, 2005.
[2]
Y. Loth, “The independent variation principle.” Zenodo, Jun. 2026. doi: 10.5281/zenodo.20794332.
[3]
Y. Loth, “On the nature of cohesion: Cohesion as correctness relative to a partitioning rule.” Zenodo, Jul. 2026. doi: 10.5281/zenodo.21703193.
[4]
Y. Loth, “Why minimizing change propagation minimizes maintenance cost.” Zenodo, Jul. 2026. doi: 10.5281/zenodo.21362542.