// Available for hire

Hire me
// 05 — writing

Notes from the build

Technical deep-dives, architectural post-mortems, and reflections on the craft of software engineering.

arrow_back Back to archive
MAY 12, 2024 ARCHITECTURE

Why I stopped reaching for microservices

Technical architecture visualization

For the last decade, we've been told that microservices are the eventual destination for every successful application. We decouple, we containerize, and we orchestrate. But for most teams, this overhead is a tax on velocity that never pays dividends.

The cognitive load of managing fifty repositories, disparate CI/CD pipelines, and tracing requests across a network boundary is immense. Often, the "scaling" problem we think we're solving is actually a "modularization" problem within a single codebase.

// config.yaml code
services:
  monolith:
    image: internal/core-app:latest
    replicas: 3
    deploy:
      mode: replicated
      resources:
        limits:
          cpus: '0.50'
          memory: 512M

The Modular Monolith

Instead of physical decoupling, I've returned to the Modular Monolith. By enforcing strict internal boundaries using language-specific features (like Go packages or Rust modules) and a shared database, we keep the deployment simplicity of a single unit while maintaining the organizational benefits of microservices.

The goal isn't just to write code faster; it's to maintain it longer with fewer sleepless nights debugging network timeouts between services that could have just been a local function call.