The Microservices Myth
There's a dangerous myth in the startup world: if you want to scale, you need microservices.
The logic seems sound. Netflix uses microservices. Amazon uses microservices. Therefore, microservices = scale. Right?
Wrong.
What Netflix and Amazon don't tell you is that they started as monoliths. They only moved to microservices when their scale (thousands of engineers, millions of concurrent users) made it necessary. For most startups, premature microservices are a death sentence.
Distributed systems are exponentially harder to build, debug, and operate. A startup with 5 engineers trying to manage 20 microservices is a startup burning runway on infrastructure instead of product.
Enter Shopify
Shopify powers over 10% of all US e-commerce. They process billions of dollars in transactions. Their codebase has over 2.8 million lines of Ruby and 500,000 commits.
And it's all in one repository. One deployable unit. One modular monolith.
What Is a Modular Monolith?
A modular monolith is a single codebase that's carefully structured into logical boundaries—components or modules—each handling a specific business domain.
Think of it as the best of both worlds:
- Simplicity of a monolith: One repo, one deploy, one team to coordinate
- Clarity of microservices: Clear boundaries, domain ownership, isolated concerns
The key difference from a "big ball of mud" monolith? Enforced boundaries.
Shopify's Implementation
1. Components as Rails Engines
Each business domain (Checkout, Payments, Orders, Inventory, Admin) is implemented as a Rails Engine—a mini-application within the larger app. Engines can be extracted into standalone services later if needed.
2. Packwerk for Boundary Enforcement
Shopify built Packwerk, an open-source tool that automatically detects when one module
tries to access another module it shouldn't. Think of it as a compiler for your architecture—it
fails the build if boundaries are violated.
3. Domain-Oriented Organization
Code is organized by business functionality (billing, orders, inventory) rather than by technical layer (controllers, models, views). This makes it easier for engineers to understand and modify specific domains.
4. Data Ownership
Each module owns its data and exposes a public API. Other modules can't reach directly into its database—they must go through the API. This is the same principle microservices use, without the network overhead.
5. Hexagonal Architecture
Core business logic is decoupled from external concerns (databases, APIs, message queues) using ports and adapters. This means the core can evolve without being tied to specific infrastructure.
The Scaling Strategies
"But wait," you say, "how does a monolith handle Shopify-level scale?"
Great question. Here's their playbook:
Database Sharding with Vitess
The database is usually the first bottleneck. Shopify uses Vitess (originally built by YouTube) to horizontally scale MySQL. Data is sharded across multiple clusters, with each "pod" serving a distinct group of shops.
Podded Architecture
Instead of one giant database, Shopify splits merchants into "pods"—independent units with their own dedicated resources. This provides:
- Fault isolation (one pod failing doesn't affect others)
- Horizontal scalability (add more pods as you grow)
- Simpler deployments (can deploy to one pod first as canary)
Aggressive Caching
Memcached everywhere. Precomputation of expensive operations. Caching at every layer—from database queries to rendered HTML.
Background Jobs
Anything that doesn't need to happen synchronously goes to Redis-backed job queues. This keeps the main request path fast and responsive.
When to Choose What
The modular monolith isn't always the answer. Here's a framework:
Start with a Monolith when:
- You're a small team (< 20 engineers)
- You're still finding product-market fit
- Speed of iteration matters more than scale
- You don't have dedicated DevOps/SRE capacity
Evolve to Modular Monolith when:
- Your monolith is becoming a "big ball of mud"
- Teams are stepping on each other's toes
- You need clearer ownership and boundaries
- You want microservice benefits without the complexity
Extract Microservices when:
- A specific domain has dramatically different scaling needs
- Different teams need different deployment cadences
- Different technology stacks are genuinely required
- You have dedicated platform engineering capacity
"Start with a modular monolith. Extract microservices only when the pain is clear and specific."
— The Shopify Engineering Team
The Ruby on Rails Factor
One more thing Shopify proves: Ruby on Rails can power internet-scale platforms.
Despite years of "Rails doesn't scale" FUD, Shopify has invested heavily in their "Ruby and Rails Infrastructure" team. They actively contribute to the framework and aim to keep Rails a "100-year tool."
The lesson? It's not about the language or framework. It's about how you architect.
The My Coding Team Approach
We help startups avoid both extremes—the unmaintainable monolith and the premature microservices.
Our approach:
"Invisible Power, Visible Simplicity."
We design modular architectures from Day 1—clean boundaries, clear ownership, room to grow. When you need to extract a service, the path is already prepared.
Ready to Build for Scale?
Book a free Architecture Review. We'll analyze your current codebase and show you exactly how to structure it for growth—without the microservices tax.
Get Your Free Review →Conclusion
The modular monolith is not a compromise—it's a strategic choice that some of the most successful companies in the world have made.
Key takeaways:
- Microservices are not required for scale
- Boundaries matter more than deployment units
- Start simple, evolve deliberately
- The right architecture depends on your team, not your ambition
Before you spin up that Kubernetes cluster, ask yourself: could a well-structured monolith get you to your next milestone faster?
For most startups, the answer is yes.