Why Self Contained Systems Beat Microservices and Monoliths in Most Projects

Why Self Contained Systems Beat Microservices and Monoliths in Most Projects

6 min readEstimated reading time: 6 minutes

Why Self Contained Systems Beat Microservices and Monoliths in Most Projects

Hey there, fellow code warriors! πŸš€ Remember when microservices were supposed to save us all from monolithic hell? Instead, they gave us distributed hell with fancy diagrams that look like subway maps designed by caffeinated architects. But what if I told you there's a better way that doesn't require a PhD in distributed systems theory?

Enter Self Contained Systems (SCS) - the architectural pattern that's been quietly solving real-world problems while the rest of us were busy debating whether our services were "micro" enough.

The Great Architecture Wars: A Brief History Lesson

Picture this: it's 2010, and everyone's building monoliths. Life was simple, deployments were straightforward, and debugging didn't require a distributed tracing PhD. Then Netflix came along with their microservices success story, and suddenly every startup with 10 users wanted to architect like they were streaming to 200 million subscribers.

But here's the plot twist - most teams aren't Netflix. They don't have thousands of engineers or need to scale to millions of concurrent users. Yet somehow, we convinced ourselves that splitting a simple e-commerce app into 47 microservices was "best practice."

2000s: Wild West

2000-2010: Monolith Era

Post-2010: Microservices Hype

2020s: SCS Reality Check

Simple Deployments

Easy Debugging

Distributed Complexity

Coordination Overhead

Balanced Approach

Team Autonomy

What Are Self Contained Systems? πŸ—οΈ

Self Contained Systems are like independent web applications that play nicely together at a party, but don't need constant supervision. Think of them as the architectural equivalent of a well-organized coworking space - everyone has their own office, but they share the same building.

Each SCS includes:

  • Its own UI (no shared frontend monoliths here!)
  • Business logic that makes sense as a unit
  • Data storage that belongs to that domain
  • Zero runtime dependencies on other systems

The magic isn't in the technology - it's in the boundaries. You don't need circuit breakers because your systems don't call each other synchronously. You don't need distributed tracing because there's nothing distributed to trace.

The Architecture Comparison Matrix

Let's break down the reality of different architectural approaches with some real data:

Aspect Monolith Self Contained Systems Microservices
Team Size 2-15 developers 3-8 per SCS 2-5 per service
Deployment Complexity Low Medium High
Coordination Overhead High (single codebase) Low Very High
Infrastructure Cost Low Medium High
Time to Market Fast (initially) Medium Slow (initially)
Debugging Difficulty Easy Medium Hard
Technology Diversity Limited High Very High

When Monoliths Actually Make Sense 🎯

Before we crown SCS as the universal solution, let's give monoliths their due credit. Amazon Prime Video recently made headlines by moving from microservices back to a monolith and cutting costs by 90%. That's not a typo - ninety percent!

Choose a monolith when:

  • Your team has fewer than 10 developers
  • You're building a proof of concept or MVP
  • Your application doesn't require independent scaling of components
  • You value development speed over everything else
// A well-structured monolith can be beautiful
class ECommerceApplication {
  private userService: UserService;
  private productService: ProductService;
  private orderService: OrderService;
  
  // Clear boundaries, single deployment
  constructor() {
    this.userService = new UserService();
    this.productService = new ProductService();
    this.orderService = new OrderService();
  }
}

The key is avoiding the "big ball of mud" anti-pattern. A modular monolith with clear domain boundaries can be incredibly effective.

The Microservices Reality Check πŸ˜…

Microservices promised us independent deployments, technology diversity, and infinite scalability. What they delivered was increased complexity, coordination costs, and distributed debugging nightmares.

Here's what nobody tells you about microservices:

The Hidden Costs

  • Network latency becomes your new enemy
  • Coordination overhead grows exponentially with team size
  • Infrastructure costs can be 3-5x higher than monoliths
  • Debugging requires distributed tracing tools that cost more than your coffee budget

The Distributed Monolith Trap

Many teams end up with what's called a "distributed monolith" - all the complexity of microservices with none of the benefits. Signs you've fallen into this trap:

  • Services must be deployed together
  • One service failure cascades to others
  • You share databases across services

"A distributed monolith is an application that's deployed like a microservice but is built like a monolith"

Use microservices only when:

  • You have millions of users requiring different scaling patterns
  • You have 100+ developers across multiple teams
  • You need to handle massive, varying loads (think Netflix-scale)
  • You have the operational maturity for complex distributed systems

Self Contained Systems: The Sweet Spot 🎯

Self Contained Systems shine when microservices are overkill but monoliths are too limiting. They're perfect for that 80% of projects that fall between "simple web app" and "Netflix-scale platform".

Key Characteristics of SCS

  1. Each system is autonomous - includes UI, logic, and data
  2. Communication is asynchronous - no chatty network calls
  3. Teams own entire vertical slices - from database to user interface
  4. Integration happens at the UI level - through links and embedding

SCS 3: Order Processing

SCS 2: Product Catalog

SCS 1: User Management

Links

Links

Events

Events

User UI

User Logic

User DB

Product UI

Product Logic

Product DB

Order UI

Order Logic

Order DB

Real-World Success Stories

Companies like Otto, Galeria Kaufhof, and KΓΌhne+Nagel have successfully implemented SCS architectures. These aren't startups experimenting with trendy tech - they're large enterprises that chose SCS for practical reasons.

Implementation Guide: Building Your First Self Contained System

Step 1: Identify Business Boundaries

Start with Domain-Driven Design principles. Each SCS should represent a complete business capability.

// Example: E-commerce SCS boundaries
interface UserManagementSCS {
  // Handles everything user-related
  registration: UserRegistration;
  authentication: UserAuth;
  profile: UserProfile;
  ui: UserInterface;
}

interface ProductCatalogSCS {
  // Manages product data and presentation
  search: ProductSearch;
  details: ProductDetails;
  inventory: InventoryManagement;
  ui: ProductInterface;
}

Step 2: Design for Asynchronous Communication

When SCS need to share data, use events rather than API calls.

// Event-driven communication
class OrderService {
  async processOrder(order: Order) {
    // Process the order
    const processedOrder = await this.processPayment(order);
    
    // Notify other systems asynchronously
    await this.eventBus.publish('order.completed', {
      orderId: processedOrder.id,
      userId: processedOrder.userId,
      items: processedOrder.items
    });
  }
}

Step 3: Implement UI Integration

SCS integrate at the UI level through several patterns:

  • Server-side includes for embedding components
  • Client-side composition using micro frontends
  • Simple linking between SCS interfaces

Step 4: Deployment Strategy

Each SCS can be deployed independently, but they're larger units than microservices. This reduces deployment complexity while maintaining team autonomy.

The Micro Frontend Connection 🌐

Speaking of UI integration, micro frontends complement SCS perfectly. Instead of a monolithic frontend talking to dozens of microservices, each SCS owns its complete user experience.

Common micro frontend patterns for SCS:

  • Route-based composition - different SCS handle different URL patterns
  • Component-based integration - embedding SCS components in shared layouts
  • Build-time composition - sharing components through npm packages

Decision Framework: Choosing the Right Architecture

Here's a practical decision tree based on real project constraints:

< 5 people

5-30 people

=> 30 people

Low

Medium-High

< 1M users

=> 1M users

High

Low

New Project

Team Size?

Monolith

Domain Complexity?

Scale Requirements?

Self Contained Systems

Operational Maturity?

Microservices

Fast development, simple ops

Team autonomy, manageable complexity

Maximum scalability, high operational cost

The 80/20 Rule

80% of projects would benefit from Self Contained Systems, 15% should stick with monoliths, and only 5% truly need microservices. Yet somehow, we've convinced ourselves that the 5% solution should be the default.

Performance and Cost Comparison

Let's look at some real numbers based on industry reports:

Metric Monolith SCS Microservices
Development Speed High (initially) Medium Low (initially)
Operational Overhead Low Medium High
Infrastructure Cost $1x $2-3x $4-6x
Team Coordination High Low Very High
Time to Debug Issues Minutes Hours Days
Deployment Frequency Weekly Daily Multiple times daily

Common Pitfalls and How to Avoid Them

Pitfall 1: Making SCS Too Small

Don't fall into the "nano-SCS" trap. Each system should be substantial enough to keep a small team busy.

Pitfall 2: Synchronous Communication Creep

Resist the urge to add "just one" synchronous API call between SCS. It's a slippery slope to distributed monolith territory.

Pitfall 3: Shared Database Anti-Pattern

Each SCS should own its data completely. Shared databases are the fastest way to couple your systems.

The Future of Software Architecture

The pendulum is swinging back toward simplicity and pragmatism. Companies are realizing that architecture should serve the business, not the other way around.

Self Contained Systems represent this pragmatic approach - they give you modularity without the operational overhead of full microservices. They provide team autonomy without the coordination nightmare of distributed systems.

Key Takeaways

  1. Most projects don't need microservices - they need modularity
  2. Self Contained Systems provide the best of both worlds - monolith simplicity with microservice benefits
  3. Team autonomy is more important than technical purity
  4. Architecture decisions should be based on team size and complexity, not trends
  5. Start simple and evolve - you can always break apart an SCS later if needed

Remember, there's no shame in choosing the "boring" solution that works. Your users care about features, not whether you're using the latest architectural pattern that's trending on tech Twitter.

"The best architecture is the one that allows your team to deliver value quickly and maintain it easily over time."

So next time someone suggests breaking your 10-user app into 20 microservices, take a deep breath, show them this article, and consider whether Self Contained Systems might be the hero your project actually needs. πŸ¦Έβ€β™‚οΈ


References

Want to dive deeper into Self Contained Systems or need help with your architecture decisions? Please share this article with your team and let me know your thoughts - hit the contact button below to get in touch! πŸš€

Share this article

Let's Work Together

I'm always interested in hearing about new projects and thoughts.