A practical decision guide for engineering leads and CTOs at UK, US, Canadian, Australian and European software companies — covering trade-offs, migration strategies, and real cost implications.
TL;DR
A monolith is a software application where all components — the user interface, business logic, and data access layer — are built and deployed as a single, unified unit. When you deploy, you deploy everything at once. When one part crashes badly enough, everything goes down with it.
Despite the negative connotations the word has picked up in recent years, monoliths have powered some of the most successful companies in the world. Shopify, Stack Overflow, and Basecamp all scaled to enormous traffic on a monolith. Many UK fintechs and US SaaS businesses serving thousands of customers run entirely monolithic systems with no practical reason to change.
A microservices architecture decomposes the application into a collection of small, independently deployable services, each responsible for a specific business capability. A typical e-commerce platform might have separate services for: user authentication, product catalogue, inventory, orders, payments, notifications, and search.
Each service owns its own data store, exposes an API (REST, gRPC, or event-based), and can be deployed, scaled, and updated independently. Teams in the US working on the payment service don't need to coordinate release windows with teams in Canada working on the notification service.
| Dimension | Monolith | Microservices |
|---|---|---|
| Initial development speed | Fast — single codebase, no inter-service wiring | Slower — service boundaries, APIs, and infrastructure must be designed upfront |
| Scalability | Scale the entire application — inefficient at high scale | Scale individual services independently — highly efficient |
| Deployment complexity | Simple — one artifact, one pipeline | High — each service has its own pipeline, container image, and deployment config |
| Fault isolation | Poor — a critical bug can take down everything | Excellent — failures are contained to individual services |
| Technology flexibility | Limited — typically locked to one stack | High — each service can use the best-fit language and database |
| Testing | Unit and integration tests are straightforward | Requires contract testing, integration environments, and careful test orchestration |
| Team structure fit | Best for small, co-located or tightly coordinated teams (2–15 engineers) | Best for large organisations with multiple autonomous teams (15+ engineers) |
| Operational overhead | Low — minimal DevOps tooling required | High — requires service mesh, API gateway, distributed tracing, orchestration |
| Data management | Single database — easy ACID transactions | Distributed data — sagas, eventual consistency, complex cross-service queries |
| Upfront cost | Lower — less infrastructure to provision and manage | £20k–£40k additional complexity cost vs equivalent monolith |
The monolith is the right choice — and often the only sensible one — in the following situations:
Whether you're building a SaaS product in Manchester, a marketplace in Toronto, or an enterprise tool in Sydney, the single most important thing at the start is speed of iteration. A monolith lets a team of two to five developers focus entirely on product rather than infrastructure. Companies like GitHub, Twitter, and Airbnb all started as monoliths. They only moved to microservices after proving product-market fit and experiencing genuine scaling pain.
Conway's Law states that organisations build systems that mirror their communication structure. A five-person engineering team working on twenty microservices will spend more time on coordination overhead than on features. The cognitive load of owning multiple independently deployed services crushes small teams. A single, well-modularised codebase is the better choice.
If your application serves a well-understood, stable domain with predictable load patterns — such as an internal HR tool for a European company or a reporting dashboard for a US professional services firm — the complexity of microservices delivers no practical benefit. The uniformity of load and the stability of requirements make a monolith not just acceptable, but actively superior.
For a business needing a custom software solution delivered within a defined budget, a monolith will typically deliver far more features for the same spend. Many UK SMEs and Australian mid-market companies benefit greatly from a well-built monolith that can be extended for years without architectural change.
Scale requirements: When different components of your system have dramatically different traffic patterns — for example, a product search service handling 50,000 requests per second while an admin dashboard handles 100 — microservices let you scale each component independently. This is why Netflix, Amazon, and Uber operate microservices at thousands of individual services.
Multiple autonomous teams: When you have 30+ engineers working across the same codebase, coordination overhead becomes the bottleneck. Microservices, aligned to team ownership along domain boundaries (the so-called "you build it, you run it" model), unlock truly parallel delivery. Teams across UK, US, and Canada offices can release independently without blocking each other.
Different technology needs per domain: If your recommendation engine needs Python and PyTorch, your real-time notification system needs Go, and your payment service needs Java with strict compliance tooling — microservices enable each team to use the best tool for their domain rather than compromising on a single shared stack.
Regulatory or compliance isolation: In the UK financial sector, certain data and processes must be kept strictly separated. Microservices with well-defined boundaries and separate data stores make compliance with FCA requirements, GDPR, and PCI-DSS more tractable than trying to enforce data isolation within a shared database schema.
Named after the strangler fig tree, which grows around a host tree until the host is completely replaced, this migration pattern is the industry-standard approach for transitioning from a monolith to microservices without a big-bang rewrite.
Warning: Never attempt a big-bang rewrite — rewriting the entire application from scratch as microservices simultaneously. This approach has a near-100% failure rate for complex systems. The strangler fig pattern is the only proven safe approach to this migration, and it still requires careful planning, strong testing, and disciplined execution over 12–36 months for a mid-sized system.
Docker containers are the standard packaging format for microservices. Each service is packaged as a container image with all its dependencies — eliminating "works on my machine" problems across development environments in the UK office and production environments in AWS US East. Key Docker best practices for microservices include:
Kubernetes (K8s) is the de-facto standard for orchestrating containerised microservices at scale. It handles:
As the number of microservices grows, managing communication between them becomes complex. A service mesh (such as Istio or Linkerd) provides a dedicated infrastructure layer for service-to-service communication, handling:
Traffic Management
Canary releases, circuit breaking, retries, and timeouts — all configurable without changing application code
mTLS Security
Mutual TLS between all services — ensuring encrypted, authenticated communication across the entire mesh
Observability
Automatic distributed tracing and metrics for every service call — without instrumentation code in the application
Before committing to a full microservices architecture, many teams benefit from adopting an event-driven architecture (EDA) within a modular monolith. Instead of direct function calls between modules, modules communicate via an internal event bus. This decouples components without the operational overhead of separate deployments.
When you're ready to extract a service, the event-based interface you've already defined makes the extraction far cleaner — you simply move the event consumer to a new service and route events through an external message broker like Apache Kafka, AWS SNS/SQS, or RabbitMQ.
EDA is particularly well-suited to workflows with asynchronous processing needs, such as order fulfilment, document processing, and notification pipelines — common in UK e-commerce, Canadian healthcare platforms, and Australian logistics software.
Upfront Complexity Cost: £20,000–£40,000
This covers the additional engineering effort to design service boundaries, set up a Kubernetes cluster (managed services like EKS, GKE, or AKS reduce this), configure an API gateway, implement distributed tracing (Jaeger, Zipkin, or Datadog APM), and establish individual CI/CD pipelines per service. For a team building the same feature set, microservices consistently cost 30–60% more to build initially.
Ongoing Infrastructure Cost: 20–40% Higher
Running fifteen services each with their own minimum compute allocation costs significantly more than a single application server with the same aggregate resources. Load balancers, managed Kubernetes control planes, and inter-service data transfer fees add up. A monolith serving 10,000 users might cost £500/month on cloud infrastructure; equivalent microservices might cost £700–£900/month minimum.
Real-World Note for UK and European Teams: Many businesses are sold on microservices by consultancies and vendors because it generates more billable work. Unless you genuinely have the scaling requirements or team size that justifies it, a well-architected modular monolith on a managed cloud service (AWS Elastic Beanstalk, Heroku, Render, or Railway) will serve you for years at a fraction of the cost and operational burden.
A London-based payments startup launched with a Django monolith. For the first 18 months, the team of six shipped features weekly without any architecture concerns. At £2M ARR and 40 engineers across UK and Poland offices, deployment coordination became the main bottleneck. They used the strangler fig pattern to extract the payments processing service first, followed by the KYC verification service. Today they run eight microservices. They kept the admin and reporting modules as a monolith — there was no business case to split them.
A Melbourne-based workforce management SaaS serving the healthcare sector in Australia, New Zealand, and Canada built their initial version as a Ruby on Rails monolith. After five years and 500+ enterprise clients, they have resisted microservices migration. Their engineering team of twelve is highly productive, their deployment pipeline is simple, and their cloud costs are predictable. They've invested instead in a modular internal architecture, thorough test coverage, and a robust CI/CD pipeline — achieving 99.95% uptime without the complexity of distributed systems.
Answer these questions honestly:
If you answered "yes" to three or more of these — and you have the operational maturity to support it — microservices may be the right path. Otherwise, invest in a well-structured monolith and keep the option to migrate open.
A monolith is a single deployable unit containing all application components. Microservices split the application into small, independently deployable services that communicate over APIs or message queues. Monoliths are simpler to build and operate; microservices offer greater scalability and team autonomy at the cost of significantly higher operational complexity.
Start with a well-structured monolith. Microservices introduce distributed systems complexity that slows down small teams and burns runway. Many successful companies — including GitHub, Shopify, and Stack Overflow — scaled to millions of users on a monolith. Migrate to microservices only when you hit genuine scaling or team coordination pain points.
Consider migrating when: different parts of the system require vastly different scaling; multiple independent teams are causing deployment conflicts; a component failure takes down the entire system; or you need different technology stacks per domain. These signals typically emerge at 30+ engineers or at significant, uneven traffic scale.
The strangler fig pattern is an incremental migration strategy where you gradually replace monolith functionality with microservices using a routing layer (API gateway or reverse proxy). New requests for extracted features are routed to the new service while the monolith handles everything else. Over time, the monolith shrinks until it can be retired — without a risky big-bang rewrite.
Microservices typically add £20,000–£40,000 in upfront complexity costs versus an equivalent monolith. This covers Kubernetes infrastructure setup, API gateway configuration, distributed tracing, and additional engineering time for service boundary design. Ongoing cloud costs run 20–40% higher due to per-service resource allocation and inter-service networking overhead.
SpiderHunts Technologies builds custom AI and software solutions for businesses across the UK, US, Canada, Europe, and Australia. Tell us what you need and we'll come back with a proposal within 24 hours.
Get Your Free Consultation