The Dilemma Every Architect Faces
How do we build systems that are cohesive enough to be understandable and decoupled enough to evolve independently?
On one side: the monolith — initial simplicity that becomes a nightmare.
On the other: microservices — flexibility that can become operational complexity.
What if there was a mental framework that balanced these forces? There is. And it comes from an unexpected place: a 1967 philosophy book.
Arthur Koestler and the Concept of Holon
In 1967, Hungarian-British philosopher Arthur Koestler published "The Ghost in the Machine". Frustrated with simplistic dichotomies, he coined a new term: holon.
Etymology
Holon = an entity that is simultaneously a complete WHOLE and a PART of something larger.
The Fundamental Duality
"Every holon has two tendencies: an integrative tendency to function as part of a larger whole, and a self-assertive tendency to preserve its individual autonomy."
— Arthur Koestler
Koestler called this the "Janus effect" — like the Roman god with two faces. Every holon looks simultaneously inward (its integrity) and outward (the larger system).
Holons in Nature
Your body is a perfect holarchy:
ORGANISM
└── ORGAN (heart)
└── TISSUE (cardiac muscle)
└── CELL
└── ORGANELLE
Each level is:
When this balance breaks? Cancer — cells that maintain autonomy but lose integration.
The Problem with Traditional Architectures
Poorly Structured Monolith
Components are just parts — no real autonomy:
Suppressed the self-assertive tendency.
Poorly Implemented Microservices
Dozens of services with synchronous HTTP forming a "distributed monolith":
Nominal autonomy, chaotic integration.
Self-Contained Systems: Holonomy in Practice
German company INNOQ formalized the concept of Self-Contained Systems (SCS).
Characteristics
The Golden Rule
Other SCS should not be accessed synchronously within the request/response cycle.
If you need data from another SCS → have a local copy updated via events.
SCS vs Microservices: An Honest Comparison
What is NOT a difference
❌ "SCS uses async, microservices uses sync"
Wrong. Modern microservices use Kafka, RabbitMQ, event-driven architecture.
The real differences
Anatomy of a Software Holon
┌─────────────────────────────────────────────┐
│ HOLON: Orders │
├─────────────────────────────────────────────┤
│ PUBLIC INTERFACE │
│ • REST/GraphQL API │
│ • Published events (Kafka) │
│ • Consumed events │
├─────────────────────────────────────────────┤
│ DOMAIN LOGIC │
│ • Business rules │
│ • Workflows/Sagas │
├─────────────────────────────────────────────┤
│ PERSISTENCE │
│ • Own database │
│ • Replicas of external data │
├─────────────────────────────────────────────┤
│ SELF-REGULATION │
│ • Health checks │
│ • Circuit breakers │
│ • Metrics │
└─────────────────────────────────────────────┘
The Dependency Rule
// ❌ WRONG
import { InventoryService } from '../inventory';
// ✅ CORRECT
await eventBus.publish({
type: 'OrderCreated',
payload: order
});
Holons don't import other holons directly.
Challenges of Asynchronous Communication
1. Event Ordering
Sent: [A, B, C]
Received: [A, C, B] 😱
Solution: Kafka guarantees order per partition.
2. Duplication (at-least-once)
if (await alreadyProcessed(event.id)) return;
await process(event);
await markAsProcessed(event.id);
3. Eventual Consistency
Accept it as reality. UI shows "processing..." when needed.
4. Distributed Debugging
Correlation ID in all logs + Jaeger/Zipkin.
When to Use (and When Not)
✅ Use when:
❌ Avoid when:
Evolution Path
Modular Monolith
↓
Separate schemas
↓
Introduce messaging
↓
Complete Holonomic System
Evolve when the pain justifies it, not before.
Conclusion
Holonomy isn't a silver bullet. It's a mental framework.
What Koestler taught us: resilient systems maintain balance between being a whole and being a part.
Monoliths, microservices, SCS — all can work. Wisdom lies in choosing right for the context.
References
"The whole is more than the sum of its parts, but the parts are more than fragments of the whole."
Liked it? Leave a ❤️ and share with anyone facing architecture decisions!
Want to discuss? Comment below 👇
More...
How do we build systems that are cohesive enough to be understandable and decoupled enough to evolve independently?
On one side: the monolith — initial simplicity that becomes a nightmare.
On the other: microservices — flexibility that can become operational complexity.
What if there was a mental framework that balanced these forces? There is. And it comes from an unexpected place: a 1967 philosophy book.
Arthur Koestler and the Concept of Holon
In 1967, Hungarian-British philosopher Arthur Koestler published "The Ghost in the Machine". Frustrated with simplistic dichotomies, he coined a new term: holon.
Etymology
- holos (Greek): "whole", "entire"
- suffix -on: connotes "particle" (like proton, neutron)
Holon = an entity that is simultaneously a complete WHOLE and a PART of something larger.
The Fundamental Duality
"Every holon has two tendencies: an integrative tendency to function as part of a larger whole, and a self-assertive tendency to preserve its individual autonomy."
— Arthur Koestler
Koestler called this the "Janus effect" — like the Roman god with two faces. Every holon looks simultaneously inward (its integrity) and outward (the larger system).
Holons in Nature
Your body is a perfect holarchy:
ORGANISM
└── ORGAN (heart)
└── TISSUE (cardiac muscle)
└── CELL
└── ORGANELLE
Each level is:
- Autonomous: functions on its own
- Integrated: contributes to the whole
When this balance breaks? Cancer — cells that maintain autonomy but lose integration.
The Problem with Traditional Architectures
Poorly Structured Monolith
Components are just parts — no real autonomy:
- Can't test in isolation
- Can't deploy independently
- Failure propagates everywhere
Suppressed the self-assertive tendency.
Poorly Implemented Microservices
Dozens of services with synchronous HTTP forming a "distributed monolith":
- Chained synchronous calls
- One failure brings down all
- Complexity without benefit
Nominal autonomy, chaotic integration.
Self-Contained Systems: Holonomy in Practice
German company INNOQ formalized the concept of Self-Contained Systems (SCS).
Characteristics
| Autonomous | Complete web application |
| Vertical Slice | UI + logic + own data |
| No sync in request/response | Doesn't call other SCS synchronously |
| Single team | One team per SCS |
The Golden Rule
Other SCS should not be accessed synchronously within the request/response cycle.
If you need data from another SCS → have a local copy updated via events.
SCS vs Microservices: An Honest Comparison
What is NOT a difference
❌ "SCS uses async, microservices uses sync"
Wrong. Modern microservices use Kafka, RabbitMQ, event-driven architecture.
The real differences
| Quantity | 5-25 | 50-500+ |
| UI | Mandatory | Optional |
| Granularity | Business domain | More granular |
| Sync in request | Prohibited | Allowed |
Anatomy of a Software Holon
┌─────────────────────────────────────────────┐
│ HOLON: Orders │
├─────────────────────────────────────────────┤
│ PUBLIC INTERFACE │
│ • REST/GraphQL API │
│ • Published events (Kafka) │
│ • Consumed events │
├─────────────────────────────────────────────┤
│ DOMAIN LOGIC │
│ • Business rules │
│ • Workflows/Sagas │
├─────────────────────────────────────────────┤
│ PERSISTENCE │
│ • Own database │
│ • Replicas of external data │
├─────────────────────────────────────────────┤
│ SELF-REGULATION │
│ • Health checks │
│ • Circuit breakers │
│ • Metrics │
└─────────────────────────────────────────────┘
The Dependency Rule
// ❌ WRONG
import { InventoryService } from '../inventory';
// ✅ CORRECT
await eventBus.publish({
type: 'OrderCreated',
payload: order
});
Holons don't import other holons directly.
Challenges of Asynchronous Communication
1. Event Ordering
Sent: [A, B, C]
Received: [A, C, B] 😱
Solution: Kafka guarantees order per partition.
2. Duplication (at-least-once)
if (await alreadyProcessed(event.id)) return;
await process(event);
await markAsProcessed(event.id);
3. Eventual Consistency
Accept it as reality. UI shows "processing..." when needed.
4. Distributed Debugging
Correlation ID in all logs + Jaeger/Zipkin.
When to Use (and When Not)
✅ Use when:
- Multiple distinct domains
- Teams need independence
- High availability is critical
- Differentiated scale per domain
❌ Avoid when:
- Small system, single team
- MVP or proof of concept
- Strong consistency is required
- No experience with distributed systems
Evolution Path
Modular Monolith
↓
Separate schemas
↓
Introduce messaging
↓
Complete Holonomic System
Evolve when the pain justifies it, not before.
Conclusion
Holonomy isn't a silver bullet. It's a mental framework.
What Koestler taught us: resilient systems maintain balance between being a whole and being a part.
Monoliths, microservices, SCS — all can work. Wisdom lies in choosing right for the context.
References
- Koestler, Arthur. "The Ghost in the Machine" (1967)
- SCS Architecture
- Microservices.io - Saga Pattern
- Apache Kafka
"The whole is more than the sum of its parts, but the parts are more than fragments of the whole."
Liked it? Leave a ❤️ and share with anyone facing architecture decisions!
Want to discuss? Comment below 👇
More...