Amazon Prime Video’s engineering team made headlines in 2023 when they reversed course on their microservices architecture for their video quality monitoring system. The result? A 90% reduction in infrastructure costs and improved scalability. This wasn’t an isolated incident - according to recent research published in Electronics journal, companies like Istio, Segment, and InVision have all made similar architectural pivots, driven by factors including cost, complexity, and performance concerns.

The software architecture landscape is shifting. While 89% of organisations adopted microservices as of 2024, many are discovering that the one-size-fits-all approach doesn’t exist. The choice between monolithic, modular monolith, microservices, and serverless architectures has become more nuanced than ever.

This guide breaks down each architectural pattern, examines real-world case studies, and provides a framework for making the right choice for your specific situation. Whether you’re building your first application or reconsidering an existing system, understanding these patterns could be the difference between shipping fast and getting stuck in architectural complexity.

Understanding the architectural spectrum

Think of software architecture like choosing how to organise your house. You could have everything in one big room (monolith), separate rooms with clear purposes (modular monolith), completely separate buildings (microservices), or rent space only when you need it (serverless). Each choice affects how easy it is to live in, maintain, and expand.

Architectural patterns range from single deployments to distributed systems, each with distinct complexity and scalability characteristics

The architectural decision you make today will influence your team’s productivity for years. As AWS notes, “Both monolithic and microservices applications experience code conflict, bugs, and unsuccessful updates. However, a monolithic application carries a more significant risk when developers release new updates, as the entire application presents a single point of failure.”

Monolithic architecture: the foundation that still works

Despite years of microservices hype, monolithic architecture remains a smart choice for many applications. Netflix started with a monolith, and only moved to microservices when their massive scale demanded it. The lesson? Don’t fix what isn’t broken.

A monolithic application is like a Swiss Army knife - everything you need in one tool. All your features, business logic, and data handling live in the same codebase. This approach has some serious advantages, especially when you’re getting started.

When monoliths excel

  • Rapid prototyping and MVP development: Single codebase means faster initial development and easier debugging
  • Small to medium teams: Reduced coordination overhead when everyone works on the same codebase
  • Limited complexity applications: Systems with well-defined boundaries and stable requirements
  • Cost-sensitive projects: Lower infrastructure and operational overhead compared to distributed systems

The key insight from Amazon Prime Video’s experience is that monoliths aren’t inherently inferior  - they’re optimised for different constraints. As their engineering team discovered, “the cost of all the building blocks was too high to accept the solution at a large scale” in their distributed system, leading them back to a consolidated approach.

Monolithic limitations to consider

Monoliths face genuine challenges as applications grow. Scaling becomes particularly difficult because “scaling a monolithic application requires scaling the entire application even if only certain components experience increased load.” This inefficiency becomes more pronounced with larger user bases and varied usage patterns.

Technology lock-in presents another constraint. Once you’ve built a monolith in a particular technology stack, changing frameworks or languages requires significant effort. This can slow adoption of new technologies that might benefit specific parts of your application.

Modular monoliths: the middle ground gaining momentum

In 2025, modular monoliths are having a moment. Many teams are choosing this approach for new projects - it’s like getting the best of both worlds. You keep the simplicity of a monolith but organise your code like you would with microservices.

Chris Richardson, who literally wrote the book on microservices, puts it well: instead of organising your code by technical layers (web stuff, business stuff, database stuff), organise it around what your business actually does (customer management, order processing, inventory).

The modular monolith advantage

Modular monoliths structure applications around business domains rather than technical layers. Instead of organising code into web, service, and data layers, you organise around customer management, order processing, and inventory systems. This domain-oriented approach provides several benefits:

  • Team autonomy: Different teams can work on different modules with minimal coordination
  • Clear boundaries: Business logic is encapsulated within domain modules
  • Evolution path: Individual modules can later become microservices if needed
  • Single deployment: Maintains operational simplicity whilst improving code organisation

The pattern works particularly well during the growth phase of applications. “Implementing a modular monolith pays off early in the project. The team doesn’t have to maintain complex infrastructure, and individual processes are simpler.”

Modular monolith implementation considerations

Success with modular monoliths requires architectural discipline. “Encapsulate each domain module’s implementation details, which includes its database schema, behind a stable, facade-style API in order to reduce loose design-time coupling between modules and improve testability.”

The critical challenge is maintaining module boundaries over time. There’s “one drawback to this positive story. Maintenance gets expensive if the application grows without clear boundaries between modules or if the team doesn’t follow architectural discipline.”

Microservices: when distribution makes sense

Microservices architecture structures applications as collections of loosely coupled services. Each service handles a specific business function and can be developed, deployed, and scaled independently. According to Statista, approximately 89% of organisations adopted microservices as of 2024, making it the most widely adopted architectural approach.

The appeal is understandable. Microservices promise independent team productivity, technology diversity, and fine-grained scalability. However, recent trends suggest the initial enthusiasm is being tempered by real-world complexity.

Microservices shine in specific scenarios

Microservices architecture provides genuine advantages when your organisation meets certain criteria:

  • Large, experienced teams: Multiple teams can work independently without coordination bottlenecks
  • Complex domains: Different parts of the system have fundamentally different scaling and performance requirements
  • Polyglot technology needs: Different services benefit from different programming languages or frameworks
  • Independent deployment requirements: Teams need to release features without coordinating with other teams

Netflix’s success with microservices illustrates the pattern at scale. “Today, Netflix has more than a thousand microservices that manage and support separate parts of the platform, whilst its engineers deploy code frequently, sometimes thousands of times each day.”

The microservices complexity trap

Here’s the thing about microservices: they’re like having a team of specialists instead of one generalist. Great when you need expertise, but the coordination overhead can be brutal. Teams often underestimate how much extra work comes with distributed systems.

Network calls add real delays. Even a simple request between services takes at least 24ms just for the network round trip. When you have multiple services talking to each other, these delays stack up quickly compared to everything running in the same process.

Then there’s data consistency. In a monolith, your database keeps everything in sync automatically. With microservices, keeping data consistent across different services requires complex coordination patterns that can be tricky to get right.

Serverless architecture: event-driven scalability

Serverless architecture is like having an on-demand workforce. Instead of keeping a full-time team (servers running 24/7), you call in specialists (functions) exactly when you need them. By 2025, this model is becoming standard even in large companies using AWS Lambda, Azure Functions, and Google Cloud Functions.

Your application becomes a collection of small functions that wake up when something happens - a user uploads a photo, a payment comes through, or data needs processing. Each function is completely independent and you only pay when it’s actually doing work.

Serverless advantages

  • Automatic scaling: Functions scale from zero to thousands of concurrent executions without configuration
  • Pay-per-use pricing: Costs align directly with actual usage rather than provisioned capacity
  • Reduced operational overhead: No servers to manage, patch, or monitor
  • Event-driven architecture: Natural fit for applications that respond to external triggers

Amazon Prime Video’s initial implementation used serverless components for rapid prototyping. “The main advantage of this approach is that it allows for rapid iteration, enabling teams to build prototypes within days or weeks.”

Serverless limitations

Serverless architecture faces constraints that become apparent at scale. Cold starts introduce latency when functions haven’t been executed recently. Vendor lock-in can be more pronounced than with other patterns, as serverless implementations often depend heavily on cloud provider-specific services.

“Going serverless has its own trade-offs (like cold starts, statelessness, and possible vendor lock-in), so it often complements rather than replaces traditional services.”

Making the right architectural choice

Choosing the right architecture requires evaluating multiple factors specific to your situation. The decision framework should consider team size, application complexity, scalability requirements, and operational capabilities.

Decision framework for choosing architectural patterns based on team structure, application complexity, and scalability needs

Team structure drives architecture choice

Here’s a key insight: your software architecture will end up mirroring how your teams communicate. This isn’t theory - it’s called Conway’s Law, and it happens whether you plan for it or not.

  • Small teams (1–8 developers): Monoliths work brilliantly because everyone can talk to everyone else easily
  • Medium teams (8–25 developers): Modular monoliths let you create team boundaries without the complexity overhead
  • Large teams (25+ developers): Microservices can actually help by letting teams work independently

Amazon CTO Werner Vogels emphasises this principle: “If there are a set of services that always contribute to the response, have the exact same scaling and performance requirements, same security vectors, and most importantly, are managed by a single team, it is a worthwhile effort to see if combining them simplifies your architecture.”

Application complexity assessment

Application complexity should drive architectural decisions more than technology trends. Consider these factors:

  • Domain complexity: How many distinct business capabilities does your application handle?
  • Data relationships: Are your data entities tightly coupled or naturally isolated?
  • Scaling patterns: Do different parts of your application have different performance requirements?
  • Change frequency: How often do different parts of your application change?

“Small to medium-sized projects benefit from monolithic architectures due to simplicity and lower overhead. Large-scale applications requiring frequent updates and scalability perform better with microservices.”

Scalability requirements evaluation

Understanding your scalability needs helps determine which architectural pattern fits best:

  • Predictable growth: Monoliths can handle significant scale with horizontal scaling
  • Uneven scaling needs: Microservices allow independent scaling of different components
  • Event-driven workloads: Serverless provides automatic scaling for unpredictable traffic
  • Global distribution: Microservices or serverless support regional deployments

When to evolve: the warning signs that signal change

The question isn’t whether to evolve your architecture - it’s when. Here are the concrete signals that indicate it’s time to move from monolith to modular monolith, and eventually to microservices.

Monolith to modular monolith triggers

Watch for these specific signs that your monolith is ready for modularisation:

  • Deploy conflicts increase: Teams are stepping on each other’s deployments more than once per week
  • Bug correlation emerges: Changes in one area unexpectedly break unrelated features more than 20% of the time
  • Team size hits 8–12 people: Coordination meetings consume more than 30% of development time
  • Build times exceed 10 minutes: Developers lose focus during the feedback cycle
  • Code review bottlenecks: Pull requests sit for more than 24 hours because nobody understands all the affected areas

The modular monolith sweet spot usually kicks in when you have 2–4 distinct business domains and teams are naturally gravitating toward working on specific areas of the codebase.

Modular monolith to microservices triggers

Microservices become justified when you hit these measurable constraints:

  • Independent scaling needs: One module consistently requires 3x more resources than others, driving up costs
  • Team independence blocked: Teams want to deploy daily but are forced to coordinate weekly releases
  • Technology constraints: Different modules would benefit from different tech stacks (e.g., AI workloads need Python, core API works best in Go)
  • Regulatory isolation required: Compliance mandates that certain data or processing must be completely separated
  • Geographic distribution needed: You need services running in different regions with different latency requirements

Netflix’s migration illustrates this perfectly: they moved to microservices not because it was trendy, but because their monolith literally couldn’t handle the scale they needed to reach.

Serverless: when your workload comes in waves

Serverless makes sense in specific situations that many teams overlook. Think of it as the architectural equivalent of hiring temporary workers instead of full-time employees - perfect for certain types of work, terrible for others.

Perfect serverless scenarios

  • Event processing: User uploads a photo, webhook arrives from a payment processor, or a file drops into a storage bucket
  • Scheduled tasks: Nightly data processing, weekly report generation, or monthly billing runs
  • API endpoints with sporadic traffic: Admin functions used a few times per day, or integration endpoints that spike unpredictably
  • Data transformation: Converting files between formats, resizing images, or processing uploaded documents
  • Integration glue: Connecting different systems that need to talk occasionally, like syncing data between your app and external services

When serverless becomes expensive or problematic

  • Steady traffic: If your function runs continuously, you’re paying more than a dedicated server
  • Large data processing: Functions have memory and execution time limits that don’t suit heavy computational work
  • Real-time requirements: Cold starts (the delay when a function wakes up) can add 100–1000ms latency
  • Complex state management: Functions can’t remember anything between executions, making stateful operations tricky

A good rule of thumb: if your workload runs more than 30% of the time, serverless probably costs more than traditional hosting. If it runs less than 10% of the time, serverless is usually a win.

Amazon Prime Video’s original approach actually makes sense when viewed this way - their video quality monitoring was event-driven (new videos being uploaded), making serverless seem logical. But when they hit scale, the “events” became so frequent that it was essentially continuous processing, making a dedicated service more cost-effective.

Migration patterns and evolution strategies

Architectural decisions aren’t permanent. “There are few one-way doors. My rule of thumb has been that with every order of magnitude of growth you should revisit your architecture, and determine whether it can still support the next order level of growth.”

Most successful applications follow a predictable evolution path: monolith → modular monolith → selective microservices extraction. The key is recognising when you’ve hit the limits of your current approach.

Measuring your evolution readiness

Track these metrics to know when it’s time to evolve:

  • Development velocity: Time from code commit to production deployment
  • Team coordination overhead: Hours per week spent in cross-team meetings
  • Deployment frequency: How often you can safely release changes
  • Mean time to resolution: How long it takes to fix bugs or performance issues
  • Code review cycle time: Time from pull request to merge

When these metrics start trending in the wrong direction for 2–3 months running, that’s your signal to consider architectural changes.

The gradual migration approach

When moving from monoliths to microservices, smart teams use what’s called the “strangler fig pattern” - like the plant that gradually grows around and eventually replaces a tree. You build new features as separate services whilst keeping the old stuff running. Over time, you slowly replace the old parts.

This beats the alternative of trying to rewrite everything at once, which usually ends in disaster. As teams grow and codebases get unwieldy, this gradual approach lets you evolve without breaking everything.

When to extract microservices

Extract microservices only when you have clear business justification:

  • Independent scaling requirements: One component needs to scale differently from others
  • Team boundaries: Different teams need to work independently on different components
  • Technology diversity: Specific components benefit from different technology stacks
  • Regulatory isolation: Compliance requirements mandate separation of certain functionality

Hybrid approaches and emerging patterns

“Several trends hint at this post-monolith direction: combining modular design with advanced infrastructure automation.” Modern applications increasingly use hybrid approaches that combine multiple architectural patterns.

Event-driven architecture as a unifying pattern

Event-driven architecture (EDA) provides a middle ground between monoliths and microservices. “This often fits together well with microservices or serverless (for instance, a function might fire off when an event arrives). Overall, EDA marks a shift from orchestrating a series of requests to coordinating everything through events, leading to loosely connected, reactive systems.”

EDA enables loose coupling without requiring full service decomposition. Components communicate through events rather than direct API calls, reducing dependencies whilst maintaining system cohesion.

Key takeaways for architectural decisions

The architecture world has grown up. We’re past the days of “microservices good, monoliths bad.” Smart companies now start simple and evolve based on real needs, not anticipated problems.

Here’s how to do it:

  • Start simple: Begin with the simplest thing that could possibly work for your current situation
  • Evolve when forced to: Add complexity only when you hit real limitations, not imagined ones
  • Match your team: Choose patterns that fit how your team actually works and communicates
  • Measure, don’t guess: Use real data to guide your decisions, not industry hype

The choice between monoliths, modular monoliths, microservices, and serverless isn’t binary. Many successful systems combine multiple patterns, using the right approach for each component based on its specific requirements.

Amazon Prime Video’s story perfectly illustrates this pragmatic approach. Their overall platform still runs on microservices, but they pulled specific components back together when the distributed approach was causing more problems than it solved. That’s mature architectural thinking - choosing the right tool for each specific job.

The most important lesson? Your architecture should serve your business goals, not the other way around. Focus on delivering value to your users whilst building systems your team can actually manage and improve over time. Sometimes that means going against the latest trends, and that’s perfectly fine.

By Ben

Leave a Reply

Your email address will not be published. Required fields are marked *