We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Distribu-ready with the Modular Monolith - Layla Porter - NDC Oslo 2024
Learn how to build a modular monolith that's ready for future distribution. Discover key principles, module design, architecture enforcement & migration strategies for maintainable apps.
-
A modular monolith is a monolithic application divided into distinct modules while maintaining a single executable, offering improved maintainability and scalability
-
Key principles of modular architecture:
- Loose coupling between modules
- High cohesion within modules
- Modules should be self-contained and independently deployable
- Clear boundaries and encapsulation between modules
- Communication through contracts/interfaces
-
Module design guidelines:
- Use internal access modifiers by default
- Keep module APIs public but implementation details private
- Modules should only reference contracts, not other modules directly
- Web API acts as the “glue” binding modules together
- Each module should have its own data store
-
Three main approaches to enforce architecture:
- Code review and pair programming
- Compile-time checks through project references
- Automated architecture tests
-
Benefits of modular monolith approach:
- Easier local development and debugging
- Simpler deployment compared to microservices
- Ability to incrementally extract modules into separate services
- Lower operational complexity
- Better suited for most applications vs immediate microservices
-
Consider the “KitKat pattern”:
- Each module is like a KitKat finger - encapsulated but part of the whole
- Modules can be “broken off” into separate services when needed
- Start with larger modules and decompose only when necessary
-
Common pitfalls to avoid:
- Distributed monolith (complexity without benefits)
- Premature distribution of services
- Sharing databases between modules
- Tight coupling between modules
-
Migration strategy:
- Start with data separation
- Use messaging/events for inter-module communication
- Extract high-volume components as “satellites” first
- Only distribute components that truly need independent scaling