October 21, 2025

The Modern Monolith 4/4: Operating the Monolith—Simplicity as Strategy

The operational story matters more than the architectural one. A well-structured monolith is straightforward to run, which means you spend time on features instead of infrastructure.

ArchitectureMonolithMicroservicesSoftware EngineeringOperations

The operational story matters more than the architectural one. You can design a beautiful system that's miserable to run, or you can design a simple system that mostly takes care of itself.

A well-structured monolith falls into the second category. The day-to-day operations are straightforward, which means you spend time on features instead of infrastructure.

Deployment Stays Boring

One application, one build, one deploy. You push to main, CI runs your tests, the build creates a container, and you deploy it. No orchestration across services. No waiting for dependency chains. No coordinating version compatibility.

When something goes wrong, you roll back one thing. The previous version is still there. You don't need to figure out which combination of service versions was working. You just go back to the last known good deploy.

This sounds basic, but basic is valuable. Deployment shouldn't be exciting. It should be routine.

Debugging Stays Local

When a request fails, you have a stack trace. It shows exactly where the error happened, what called it, and what the state was. You can search your logs for the request ID and see the entire flow in one place.

You can reproduce the issue locally. Clone the repo, check out the commit, run the app, make the same request. The error happens on your machine the same way it happened in production. You can set breakpoints. You can step through the code. You understand what went wrong.

Distributed tracing is powerful when you need it, but needing it means your system is harder to reason about. In a monolith, the request flow is visible in your editor.

Testing Stays Integrated

Your integration tests run the entire system. You start the application, make HTTP requests, verify the responses. If something would break in production, it breaks in your test suite.

You don't need to mock service boundaries. You don't need to maintain contract tests across repositories. You don't need to coordinate test environments where all the services are at the right versions. Your tests reflect reality because they run the real code.

This makes tests reliable. When they pass, you have confidence. When they fail, they're telling you about an actual problem, not a mismatch between mock behavior and real behavior.

Monitoring Stays Simple

One application means one set of metrics. You track request rate, error rate, and latency. You track database connection pool size and query performance. You track memory usage and CPU.

These metrics tell you what you need to know. If requests slow down, you know where to look. If errors spike, you see it immediately. You don't need to correlate metrics across services to figure out where the problem started.

Alerting is simpler too. When error rate crosses a threshold, you get paged. You don't need to set up complex alert conditions that check whether three different services are all degraded simultaneously.

Onboarding Stays Fast

A new engineer clones one repository. They run pnpm install, then pnpm dev. The application starts locally. They can see the whole system running on their machine.

They make a change. They see the effect immediately. They don't need to understand service topology before they can contribute. They don't need to configure local networking. They just edit code and refresh the page.

This matters more than people think. The time from "first day" to "first meaningful contribution" affects both productivity and morale. Monoliths make that time shorter.

Database Stays Consistent

Transactions work. When you need to update related data, you wrap it in a transaction. Either all the updates succeed or none of them do. You don't need to implement sagas or deal with eventual consistency.

Queries are fast. When you need data from multiple tables, you write a JOIN. The database handles it efficiently. You don't need to make multiple HTTP requests and stitch the data together in application code.

Schema migrations are straightforward. You write a migration, test it against a copy of production data, and run it during a maintenance window. You don't need to coordinate migrations across multiple databases while ensuring version compatibility.

The Infrastructure Advantage

You need one database, one web server, one background job processor. Maybe a cache and a message queue if your system needs them. That's your infrastructure.

Compare that to microservices: six databases, six web servers, six background job processors, a service mesh, distributed tracing infrastructure, and a system to manage secrets across all of them.

The simpler infrastructure means fewer moving parts. Fewer places where things can go wrong. Fewer systems to monitor, patch, and upgrade. Less time spent with your operations hat on.

What This Means for B2B

B2B companies succeed by solving customer problems reliably. Your architecture should support that goal, not compete with it.

Customers care about features and uptime. They don't care whether you use microservices or monoliths. They care that their workflows work and their data is safe.

A monolith gives you operational simplicity, which translates to reliability. Fewer components means fewer failure modes. Simpler deployments means fewer opportunities for mistakes. Local debugging means faster incident resolution.

This is a competitive advantage, even if it doesn't feel like one. Your competitors who chose microservices too early are spending engineering time on infrastructure. You're spending it on features that differentiate your product.

The Strategic Value of Boring

The technology choices that generate conference talks aren't always the ones that generate sustainable businesses. Boring technology has been proven. It has known failure modes. It has tooling and community knowledge.

Dan McKinley's essay "Choose Boring Technology" frames this perfectly: you get about three innovation tokens to spend. If you spend one on NodeJS, one on MongoDB, and one on a new service discovery system, you have none left for the actual problem your business is solving. A well-structured monolith running on PostgreSQL and Node.js is boring. You can hire engineers who know these tools. You can find answers on Stack Overflow. You're not betting the company on architectural experimentation.

Boring doesn't mean stagnant. You're still building new features, improving performance, and adapting to requirements. You're just not fighting your infrastructure while you do it.

When Simple Stops Working

Eventually, some systems do outgrow monoliths. If you're there, you know. Deploys queue up because too many teams are changing code. Specific components need different scaling characteristics. The organization is large enough that coordination cost exceeds operational cost.

If you built a modular monolith, you're prepared. The boundaries exist. Extracting services is refactoring, not rewriting. You migrate incrementally, learning as you go.

But for most B2B products serving thousands of customers, that day never comes. The monolith keeps working. You keep shipping features. Your customers keep getting value.

The Series in Perspective

This series started by redefining what a monolith is: a deployment decision, not a design pattern. Modern monoliths have structure, boundaries, and discipline. They're not the tangled codebases people fear.

We looked at why small teams struggle with microservices. The operational overhead exceeds the organizational benefits. The infrastructure costs more than the independence is worth.

We explored the modular monolith: structure without distribution. Clear boundaries enforced at dev time instead of runtime. The benefits of good architecture without the costs of distribution.

We walked through building one. Domain boundaries, folder structure, public APIs, enforcement tooling, database strategies. The practical steps from idea to working system.

We established when to split. Specific constraints like scaling needs, data residency, or independent teams. Not fears or fashion, but measurable problems that distribution solves.

And now we've covered operations. The day-to-day reality of running a system. The way that architectural choices compound into productivity gains or drains.

Try This

Look at how your team spent time this week. How much went to features versus infrastructure? If you're spending more than 20% of your time on deployment, monitoring, service coordination, or distributed debugging, your architecture might be working against you.

Sources

Enjoyed this article?

Check out more articles or connect with me