Przejdź do treści głównej
Architecture

Microservices vs Monolith: Decision Framework for 2025

When do microservices make sense, and when are they premature optimization? A practical guide based on experiences of teams that succeeded (and those that failed)

·15 min read
Team collaborating on software architecture design

Microservices are everywhere. Tech conferences are full of success stories. Recruiters hunt for distributed systems experience. Startups advertise "microservices-first" in job postings. But does that mean monoliths are bad?

Not necessarily. Martin Fowler, one of the leading thinkers in software architecture, noticed something interesting: "Almost all successful microservices stories started with a monolith that became too large and was split up". On the other hand, most systems built from scratch as microservices ended up in serious trouble.

01The Microservices Hype vs Reality

If you believe industry surveys, microservices are a resounding success. O'Reilly published a 2020 study showing that 92% of organizations are successful with microservices. Sounds impressive, right?

Let's look at these numbers closer:

  • 77% of organizations adopted microservices according to O'Reilly (2020)
  • 92% report success - but these are the ones that survived long enough to participate in the survey
  • 40% cite organizational culture as the biggest barrier
  • 56% struggle with complexity of distributed systems

The problem with these statistics? Classic survivor bias. Companies that burned millions on failed microservices migrations and reverted to monoliths don't brag about it publicly. They don't write case studies. They don't speak at conferences.

When microservices DON'T make sense:

Early-stage startup (0-10 people)

You don't know your domain model yet. Service boundaries will change weekly. That's a recipe for chaos.

No experience with distributed systems

Don't understand eventual consistency, circuit breakers, distributed tracing? Learn on a smaller project first.

Low traffic and simple requirements

If your app handles 1000 users per day, a monolith on a single server will be cheaper and simpler.

"Because that's what everyone does now"

Worst possible reason. Architecture should serve the business, not your resume.

Sam Newman on microservices

Sam Newman, author of "Monolith to Microservices", called microservices a "last resort". He talked to many teams that started breaking up monoliths into modular monoliths with the intention of later moving to microservices - only to discover that the modular monolith solved most of their problems.

02Monolith Strengths (Often Overlooked)

Solid foundation architecture and team planning

Monoliths got a bad reputation. But the truth is that most successful tech companies started with a monolith - and many still use it. Shopify, GitHub, Stack Overflow - all run on (large) monoliths.

Development Speed

In a monolith, adding new functionality is often a matter of hours. You don't need to define API contracts between services, sync versions, or manage backward compatibility. Refactoring? Ctrl+F through the whole project and you're done.

ACID Transactions

An e-commerce order requires updating inventory, processing payment, and scheduling shipping. In a monolith: one database transaction. In microservices: saga pattern, eventual consistency, compensating transactions. Which option sounds simpler?

Easier Debugging

Stack traces in monoliths show exactly where the problem is. In microservices, you need to trace requests through 7 services, check correlation IDs in logs, and pray that distributed tracing works. Debugging distributed systems is a separate skill.

Lower Operational Costs

One deployment, one monitoring stack, one database. In microservices: 20 services × (deployment pipeline + monitoring + logging + tracing + service mesh). Costs grow linearly with the number of services.

When a monolith is a good choice:

  • New product/startup - fast iteration more important than scalability
  • Small team (up to 10-15 people) - everyone knows the entire codebase anyway
  • CRUD-heavy applications - most logic is database reads/writes
  • Tightly coupled domains - if every change requires updating 5 modules, don't split them
  • Limited operational budget - 1 DevOps vs 5 DevOps is a huge cost difference

03Microservices Benefits (And Their Cost)

I'm not saying microservices are bad. They're a powerful tool - but like any powerful tool, they come with a price. The key question is: do the benefits outweigh the costs in your specific case?

1

Independent Scaling

Benefit:

Your payment service gets 10x more traffic than the rest? Scale only its instances. Save on servers.

Cost:

You need to build auto-scaling infrastructure, load balancing, service discovery. This requires Kubernetes or similar orchestrator - meaning a dedicated person/team to maintain it.

2

Technology Flexibility

Benefit:

Recommendation service in Python+TensorFlow, backend in Go, analytics in Rust. Each team picks the best tool for their problem.

Cost:

5 programming languages = 5x bigger hiring requirements, 5x more libraries to security audit, knowledge fragmentation in the team. In practice, most companies standardize on 1-2 stacks anyway.

3

Team Autonomy

Benefit:

Teams can deploy independently without coordinating with others. Faster time to market, fewer code conflicts.

Cost:

This only works in large organizations (50+ developers). In small teams, "autonomy" means chaos and code duplication. You also need a strong DevOps culture - each team must handle production operations.

4

Deployment Independence

Benefit:

Bug in payment module? Deploy only the payment fix, not the entire system. Reduces risk and blast radius.

Cost:

Changes requiring coordination between services (breaking API changes) become a nightmare. You need API versioning, backward compatibility, feature flags, canary deployments. This is not trivial overhead.

Distributed Systems Complexity - The Hidden Cost

The biggest cost of microservices isn't technical - it's cognitive. Distributed systems are fundamentally harder to understand than monoliths. You have to deal with:

  • • Network failures (always assume calls can fail)
  • • Eventual consistency (forget about immediate data consistency)
  • • Partial failures (part of the system works, part doesn't)
  • • Distributed transactions (saga pattern is not trivial)
  • • Debugging across service boundaries (where did that request go?)
  • • Data duplication and synchronization (which service is the source of truth?)

04Decision Framework

Team making architectural decisions during meeting

Instead of religious "monolith vs microservices" debates, let's use a practical decision framework based on measurable criteria.

1. Team Size Threshold

Amazon has the "two-pizza team" rule - a team should be small enough to feed with two pizzas (~8-10 people). This is a good indicator for organization size:

1-10 developers: Monolith (possibly modular monolith)
10-50 developers: Modular monolith or selective microservices (2-5 services)
50+ developers: Microservices make sense organizationally

2. System Complexity Indicators

Rate your system on the following criteria (0-10 points each):

  • Scaling differences - Do some modules need 10x more resources than others?
  • Different technology requirements - Does part of the system require specific tech (ML, real-time processing)?
  • Independent release cycles - Do different parts of the system need to be deployed at different paces?
  • Clear domain boundaries - Does your domain model have well-defined bounded contexts?
  • Multiple consumer types - Do you have different consumers (mobile, web, API partners)?

Scoring:
0-15 points: Monolith
15-30 points: Modular monolith
30-40 points: Selective microservices
40+ points: Full microservices architecture

3. Organizational Readiness

Microservices aren't just a technical decision - they're an organizational change. Check if you're ready:

DevOps culture - Teams can deploy and monitor their services in production
Automated testing - CI/CD with integration and contract tests
Monitoring infrastructure - Distributed tracing, centralized logging, metrics
On-call rotation - Teams are ready for 24/7 support of their services
Operational budget - 2-3x more infrastructure costs than monolith

If you didn't check all boxes - you're not ready for microservices.

Decision Matrix

CriterionMonolithModular MonolithMicroservices
Team size1-1010-3030+
Domain complexityLowMediumHigh
Scaling requirementsUniformMostly uniformHeterogeneous
Deployment frequencyWeekly/MonthlyDailyMultiple/day
DevOps maturityBasicIntermediateAdvanced
Ops budgetLowMediumHigh

05Hybrid Approach: Modular Monolith

Team planning modular system architecture

There's a third option that's rarely discussed, which Sam Newman calls "highly underrated" - the modular monolith. It's the sweet spot between monolith simplicity and microservices flexibility.

What is a modular monolith?

It's a single application divided into clearly separated modules with clean boundaries. Each module has its own domain, logic, and only communicates with others through well-defined interfaces. Modules are deployed together but could be extracted into separate services in the future.

Example structure:

src/
├── modules/
│   ├── authentication/
│   │   ├── domain/
│   │   ├── application/
│   │   ├── infrastructure/
│   │   └── api/
│   ├── orders/
│   │   ├── domain/
│   │   ├── application/
│   │   ├── infrastructure/
│   │   └── api/
│   ├── payments/
│   │   ├── domain/
│   │   ├── application/
│   │   ├── infrastructure/
│   │   └── api/
│   └── shipping/
│       ├── domain/
│       ├── application/
│       ├── infrastructure/
│       └── api/
└── shared/
    ├── common/
    └── kernel/

Modular monolith advantages

  • Simple deployments (single artifact)
  • ACID transactions still work
  • Easier debugging (stack traces)
  • Enforced modularity (clear boundaries)
  • Lower operational costs
  • Migration path to microservices (if needed)

When to consider modular monolith

  • Team of 10-30 people (too large for simple monolith)
  • Complex domain requiring separation of concerns
  • Not ready for full microservices (lacking DevOps maturity)
  • Want parallel team work without distributed systems
  • Preparing for future microservices migration

Implementing modular monolith

1.Define module boundaries - Using Domain-Driven Design, identify bounded contexts
2.Enforce boundaries - Use tools like ArchUnit (Java), NDepend (.NET) to validate dependencies
3.No direct DB access - Each module has its own schema, other modules query through API
4.Internal APIs - Communication between modules only through public interfaces
5.Separate team ownership - Each team is responsible for their module

06Migration Strategy (If Microservices Make Sense)

If you've decided microservices are the right choice (you passed the decision framework from previous sections), the next question is: how do you get there without destroying a working business?

Strangler Pattern - Proven Approach

As I mentioned in the legacy modernization article, the Strangler Pattern is the safest migration strategy. Instead of rewriting the entire system, you gradually "strangle" the old monolith, extracting one service at a time.

Step 1: Introduce API Gateway/Proxy for request routing
Step 2: Choose first service (low risk, high value)
Step 3: Build new service alongside monolith
Step 4: Gradually switch traffic (feature flags, canary)
Step 5: Remove old implementation from monolith
Step 6: Repeat for next services

Domain-Driven Design - Finding Service Boundaries

The biggest mistake in microservices is getting service boundaries wrong. How do you know where to draw the line? Domain-Driven Design provides tools:

  • Bounded Contexts - Business areas with their own language and data model

    Example: "Order" in payment context is different from "Order" in shipping context

  • Aggregates - Groups of objects that must always be consistent

    Order + OrderItems is an aggregate - keep them in one service

  • Context Mapping - How different contexts communicate

    Customer-Supplier, Partnership, Shared Kernel patterns

Data Decomposition - The Hard Part

Splitting code is 20% of the work. Splitting data is 80%. Strategies:

1. Database per Service (target state)

Each service has its own database. Full autonomy, but requires eventual consistency and saga patterns for transactions.

2. Schema per Service (transitional)

Shared database, separate schemas for each service. Easier migrations, but still coupling at DB level.

3. Dual Write Pattern (during migration)

Write to both old and new database simultaneously. Allows gradual switch of read path without risk.

Common Migration Pitfalls

  • Too fine-grained services (nano-services) - 50 services instead of 5, overhead kills productivity
  • Migration without good monitoring - distributed tracing first, then microservices
  • Big-bang migration - rewriting everything at once ends in disaster
  • Lack of API versioning - breaking changes block deployments
  • Shared database - kept all monolith drawbacks, added microservices drawbacks
  • Synchronous calls everywhere - one slow service blocks everything (use async/events)

07Case Study: E-commerce Platform Evolution

E-commerce platform architecture evolution - diagrams and planning

Here's a real story of architecture evolution for a mid-sized e-commerce platform (5M users, 50K orders/day). Names changed, but numbers are real.

Y1

Year 1-2: Monolith (5 developers)

Rails monolith with PostgreSQL. Everything in one repo: products, cart, payments, shipping, admin panel.

What worked:

  • • Fast feature development
  • • Simple deployments (Heroku)
  • • One developer understands whole system
  • • Costs: $500/month

First problems:

  • • Git conflicts with 5+ people
  • • Admin panel slows down customer-facing
  • • Deployment requires full restart
Y3

Year 3: Modular Monolith (15 developers)

Refactoring to modular structure with clear boundaries. 4 main modules: Catalog, Orders, Payments, Fulfillment.

Benefits:

  • • Teams can work in parallel
  • • Enforced separation of concerns
  • • Still simple deployments
  • • Costs: $1200/month

New challenges:

  • • Black Friday crash (DB bottleneck)
  • • Search module needs Elasticsearch
  • • Weekly deployment too slow
Y4

Year 4-5: Selective Microservices (30 developers)

Extracting only the most problematic areas. Not the whole system - only what actually needs scaling.

Extracted services (4):

  • 1. Search Service (Elasticsearch) - Heavy read load, needed separate scaling
  • 2. Payment Service (Node.js) - PCI compliance isolation, real-time webhooks
  • 3. Recommendation Engine (Python) - ML model, different tech stack
  • 4. Image Processing (Go) - CPU-intensive, async processing

Core monolith kept:

Orders, Catalog, Inventory, Shipping stayed in monolith - they were tightly coupled and didn't require separate scaling.

Y6

Year 6: Hybrid Architecture (today)

Kubernetes on Azure AKS for microservices, managed PostgreSQL for monolith, RabbitMQ for async communication.

Metrics:

  • • Deployments: 10-15x/day (microservices), 2x/week (monolith)
  • • Availability: 99.9% (SLA met)
  • • Response time: p95 < 300ms
  • • Team: 30 devs, 3 DevOps

Costs:

  • • Infrastructure: $8K/month
  • • Monitoring (DataDog): $1.5K/month
  • • DevOps team: 3 people
  • • Total: ~15x more than year 1

Lessons Learned

  • Not everything needs to be a microservice - Extract only what actually needs it
  • Modular monolith is a valid long-term solution - Don't treat it as a transitional state
  • Invest in observability BEFORE microservices - Distributed tracing saved us many times
  • Costs grow faster than you think - 15x infrastructure + people to maintain it
  • Start with monolith - Every attempt to start with microservices ended in refactoring

08Frequently Asked Questions

Are microservices always better than monoliths?

No. Microservices solve specific problems: scalability, deployment independence, team autonomy. If you don't have these problems - you don't need microservices. Martin Fowler says it plainly: most projects starting as microservices end up in serious trouble. Start with a monolith, migrate to microservices only when the business demands it.

How many services is "too many"?

If you have more services than developers - that's a problem. Amazon has the "two-pizza team" rule - a team should manage at most 2-3 services. If you see 50+ microservices in an organization with 20 developers, those are nano-services and overhead kills productivity. The sweet spot is 3-10 services in a medium-sized organization.

What about serverless? Is that the next step after microservices?

Serverless (Lambda, Azure Functions) is a good option for event-driven workloads and occasional tasks. But it doesn't replace microservices - it's a different category. Serverless has its drawbacks: cold starts, vendor lock-in, harder debugging, execution time limits. Use serverless for async processing, scheduled jobs, webhooks. Not for core business logic requiring low latency.

What's the difference between microservices and SOA?

SOA (Service-Oriented Architecture) is an older concept from the 2000s. Main differences: SOA used heavy standards (SOAP, ESB, WSDL), microservices prefer lightweight protocols (REST, gRPC). SOA had a central ESB bus (single point of failure), microservices are fully distributed. In practice, microservices are an evolution of SOA ideas with lessons learned from failed enterprise SOA implementations.

Can I have microservices without Kubernetes?

Yes, but life will be harder. Kubernetes solves problems of orchestration, service discovery, load balancing, auto-scaling. Alternatives: AWS ECS/Fargate, Azure Container Apps, Google Cloud Run, Nomad, docker-compose (dev only). For small deployments (2-5 services), you can use managed services like Azure Container Apps - they give you some k8s benefits without the complexity.

How to convince my manager we DON'T need microservices?

Show numbers. Microservices mean 2-3x more infrastructure costs, need for dedicated DevOps, longer onboarding time for new developers (distributed systems are harder), slower feature development initially. Ask: "What specific business problem are we solving with microservices?". If the answer is "because that's what everyone does" - that's not a good reason. Propose a modular monolith as a compromise - it gives 80% of the benefits at 20% of the cost.

Key Takeaways

  • Microservices aren't a silver bullet - they solve specific problems (scaling, team autonomy) but introduce distributed systems complexity
  • Monoliths are an excellent choice for small/medium teams and new products - allow fast iteration without operational overhead
  • Modular monoliths are often the best compromise - provide separation of concerns without microservices costs
  • Use the decision framework: team size, domain complexity, scaling needs, organizational readiness - not gut feeling
  • If going microservices - gradual migration through Strangler Pattern, not big-bang rewrite
  • Start with monolith - Martin Fowler and Sam Newman say the same: almost all successful microservices stories started with a monolith

Need Help with System Architecture?

I help companies choose the right architecture and safely migrate between patterns. Get in touch to discuss a strategy for your organization.

References

  1. [1] Microsoft Azure - Official Documentation -https://learn.microsoft.com/en-us/azure/
  2. [2] Microsoft Learn - Azure Training Center -https://learn.microsoft.com/en-us/training/azure/
  3. [3] Kubernetes - Official Documentation -https://kubernetes.io/docs/
  4. [4] CNCF Annual Survey 2023 - State of Kubernetes Adoption -https://www.cncf.io/reports/cncf-annual-survey-2023/
  5. [5] .NET - Official Microsoft Documentation -https://learn.microsoft.com/en-us/dotnet/
  6. [6] .NET Blog - Latest updates and best practices -https://devblogs.microsoft.com/dotnet/
  7. [7] Flexera State of the Cloud Report 2024 -https://www.flexera.com/blog/cloud/cloud-computing-trends-2024-state-of-the-cloud-report/
  8. [8] FinOps Foundation - Best Practices -https://www.finops.org/
  9. [9] Gartner - Cloud Computing Research -https://www.gartner.com/en/information-technology/insights/cloud-computing
  10. [10] AWS - Official Documentation -https://docs.aws.amazon.com/
  11. [11] Google Cloud - Official Documentation -https://cloud.google.com/docs
Microservices vs Monolith: Decision Framework for 2025 | Wojciechowski.app | Wojciechowski.app