NOVEK LABS
Backend12 min read

Monolith vs microservices: why your startup should pick the boring one

V

Victor

Founder, Novek Labs

Every founder hits this question eventually, usually when someone asks "so what's your architecture?" and "one big app" suddenly feels like the wrong answer. It is not the wrong answer. It is almost always the right one.

Verdict: build a well-structured monolith. Virtually every startup should run a single deployable application until team size, not traffic, forces a split. Microservices solve an organizational problem, many teams needing to ship independently without stepping on each other, that startups simply do not have. In exchange, they import a stack of distributed-systems problems that startups cannot afford to carry. At Novek Labs we build modular monoliths by default for every MVP we ship, and this post explains why, along with the honest cases where that default is wrong.

Key takeaways

  • A monolith is one application deployed as one unit. Microservices split that application into many small services that talk to each other over a network.
  • Microservices exist to let large organizations ship independently. If your whole engineering team fits in one meeting, you do not have the problem they solve.
  • A modular monolith gives you clean internal boundaries without the network in between, which preserves your option to extract services later.
  • Vertical scaling, read replicas, and caching will carry a sane monolith far past product-market fit. Traffic is almost never the real reason to split.
  • Extract a service only when a specific hot path has wildly different scaling needs, or when a stable team boundary has formed around a domain.

What is the difference between a monolith and microservices?

A monolith is a single codebase that builds into a single deployable application. Your API, your business logic, your background jobs, all of it ships together and talks to one database. When you deploy, you deploy everything at once.

Microservices break that application into many small, independently deployed services. The payments service, the notifications service, the user service, each one runs on its own, owns its own data, and communicates with the others over a network, usually through HTTP calls or message queues (a queue is a buffer that lets one service leave work for another to pick up later).

On a whiteboard, microservices look cleaner: small boxes, tidy arrows, every concern in its place. But every arrow is a network call that can time out, fail halfway, or return stale data. In a monolith, the same interaction is a function call you can read in one editor window, and it either happens or it does not.

Why do startups choose microservices, and why is it usually a mistake?

Microservices became famous because companies with hundreds of engineers wrote about them. At that scale, the pattern earns its keep: when forty teams share one codebase, deploys queue up, merge conflicts multiply, and one team's bug blocks everyone's release. Splitting into services lets each team own its slice and ship on its own schedule.

Notice what that problem is: not traffic, but coordination between many teams. A startup with two to eight engineers has no coordination problem that architecture needs to solve. Everyone already knows what everyone else is shipping.

What the startup gets instead is the bill:

  • Network failures between functions. A call that was chargeCustomer(order) becomes an HTTP request that needs timeouts, retries, and a plan for what happens when the payment service is up but the order service is down.
  • Observability overhead. Debugging one app means reading one log. Debugging twelve services means tracing a request across twelve logs, and paying for tracing infrastructure before you have paying customers.
  • Deployment complexity. One app deploys with one pipeline. Twelve services need twelve pipelines, service discovery, and someone who understands the orchestration layer, and that someone would rather be building product.
  • Data consistency. In a monolith, a signup that creates a user, a workspace, and a subscription is one database transaction: all of it commits or none of it does. Across services you get partial failures and half-created accounts, and fixing that properly is genuinely hard engineering.

Each of these is a tax paid in the only currency a startup has: weeks of runway. We wrote elsewhere about why most MVPs die before launch, and self-inflicted complexity is high on that list.

The resume-driven-development trap

There is a quieter reason startups end up with microservices. Engineers know that "designed a distributed microservices architecture" reads better in an interview than "built a Rails app that made money," so the decision gets made with one eye on the next job, not on this company's survival. It is rarely malicious, just an incentive, and founders should recognize it when an early hire pushes hard for Kubernetes on day one. Ask "what specific problem does this solve for us this quarter?" and hold the line until the answer is concrete.

What premature microservices look like from the inside

A meaningful share of our work at Novek Labs is rescue projects: products that arrive half-built, over budget, and stalled. The premature-microservices version of that story is remarkably consistent. A previous team split an MVP into eight or ten services before the product had users. Local development meant running a container swarm on a laptop, so onboarding took days. A one-line feature touched three services and needed three coordinated deploys, and debugging meant guessing which service dropped the message. On one rescue we collapsed everything back into a single application, and feature work that had taken weeks started shipping in days, with the same people. The architecture was the whole bottleneck.

What is a modular monolith?

Here is the part that gets lost in the shouting match: the choice is not between one giant tangle and a fleet of services. A modular monolith is a single deployable application whose code is organized into strict modules, one per business domain: billing, listings, notifications, whatever your product's real domains are.

Each module exposes a small public interface, and other modules may only talk to that interface, never reach into its internals. You get most of what people want from microservices, clear ownership, enforced boundaries, testable seams, without any of the network in between.

The strategic point is that a modular monolith preserves your future option. Because each module already has a defined boundary and its own slice of the data, extracting one into a real service later is a mechanical refactor, not a rewrite. You are not choosing "never microservices." You are choosing "not yet, and cheaply reversible." This is how we design system architecture on every build we take on.

When we built Hype Exchange, a resale marketplace, the marketplace, authentication, payments, and shipping logic were separate modules inside one deployable app from day one. Two years of feature work later, none of them has needed to leave, and any of them still could.

How far can a monolith actually scale?

Much further than the microservices sales pitch implies. The boring scaling playbook, in order:

  1. Vertical scaling. Bigger servers. Modern cloud instances offer hundreds of gigabytes of RAM and dozens of cores, and a well-written monolith on one large box serves enormous traffic. This is a pricing-page change, not an engineering project.
  2. Horizontal copies. Run several identical copies of the monolith behind a load balancer (a router that spreads incoming requests across them). Same codebase, same deploy, more capacity.
  3. Read replicas. Most products read data far more often than they write it. A read replica is a live copy of your database that handles read traffic, leaving the primary free for writes.
  4. Caching. Store the answers to expensive or repeated questions in fast memory so you compute them once, not on every request. A cache layer routinely absorbs most read load.

That playbook carries you well past product-market fit, and every step of it is boring, documented, and cheap compared to a service split. If you are hitting real limits before you have real revenue, the problem is almost certainly a slow query or a missing cache, not your architecture.

Monolith vs microservices: side-by-side for an early-stage startup

Concern Well-structured monolith Microservices
Time to first release Fast: one app, one pipeline Slow: infrastructure before features
Feature speed, small team High: one codebase, one deploy Low: changes span services and deploys
Debugging One log, one stack trace Distributed tracing across services
Data consistency Database transactions, built in Partial failures you must handle yourself
Infrastructure cost One app plus a database Orchestration, queues, tracing, more compute
Team size where it shines 1 to roughly 20 engineers Many teams shipping independently
Ability to change course High: refactors stay in one repo Low: service contracts harden early
Later extraction Cheap, if modular boundaries exist Not applicable, you already paid

When is extracting a microservice genuinely the right call?

The honest trade-offs, because the monolith position is a default, not a religion. Extraction earns its cost in two situations.

A hot path with wildly different scaling needs

Sometimes one narrow slice of the system has a workload profile nothing like the rest: a real-time feed, a media pipeline, a matching engine that bursts hard. When we built Roundup, a micro-investing app, the transaction-processing path was exactly this kind of candidate, spiky and isolated, and because it lived in its own module the extraction conversation was about operations, not archaeology. Extract the hot path. Leave everything else alone.

A team boundary that has hardened

When you genuinely have multiple teams, and one team owns a domain end to end, ships on its own cadence, and keeps colliding with everyone else's deploys, that is the original microservices problem showing up for real. Extract along that team boundary. Note the trigger: headcount and organizational structure, never a traffic graph.

How do you keep a monolith extractable?

The option to extract later is only real if you protect it. Three rules do most of the work:

  • Enforce module boundaries in code. Each domain gets a folder or package with a small public interface. Use lint rules or your language's visibility features so cross-module imports of internals fail the build, because a boundary that is only a convention erodes in six months.
  • No cross-module table joins. This is the rule teams break first. The moment your billing query joins directly against the listings tables, those modules share a data model and cannot be separated without a migration project. Each module owns its tables; other modules ask through its interface.
  • Keep module communication explicit. When billing needs to react to a new signup, publish an event or call a defined method. No shared global state, no reaching across the codebase because it was quicker that day.

Follow those rules and extraction later is measured in weeks. Ignore them and you get the big ball of mud that microservices advocates rightly warn about, except the answer was discipline, not a network.

The decision framework

Before anyone on your team says "microservices" in a planning meeting, answer these in order:

  1. How many engineering teams do you have? Not engineers, teams. If the answer is one, stop here and build a modular monolith.
  2. Have you exhausted the boring scaling playbook? Bigger instances, multiple copies behind a load balancer, read replicas, caching. If not, your bottleneck has a cheaper fix.
  3. Can you point to one specific component with a provably different scaling profile? "The whole app might need to scale" is not an answer. "Transaction processing spikes 50x during market hours" is.
  4. Do you have dedicated infrastructure capacity? Someone must own pipelines, tracing, and on-call for a distributed system. If that person would otherwise be building product, you are trading features for architecture.
  5. Would this survive the runway test? Estimate the migration in engineer-weeks, honestly, then double it. If that number makes your cash-out date uncomfortable, the decision has made itself.

If those answers point at one specific extraction, do that one extraction. If they do not, you have your architecture, and it is the boring one.

Frequently asked questions

Is a monolith bad for startups? No, it is the correct default. A single application is faster to build, cheaper to run, and easier to change while you are still searching for product-market fit. The companies that popularized microservices ran monoliths through their own startup years and split only when organizational scale demanded it.

When should a startup switch to microservices? When team structure, not traffic, demands it: multiple teams genuinely blocking each other in one codebase, or one component with a proven, wildly different scaling profile. Extract that one piece and keep the rest together. A wholesale migration is almost never right for a company still finding its market.

Do microservices scale better than a monolith? Not at startup scale. Vertical scaling, copies behind a load balancer, read replicas, and caching handle far more traffic than most products ever see. Microservices offer finer-grained scaling, but that only outweighs their operational cost well past the point where the boring playbook runs out.

What is a modular monolith in simple terms? One deployable application organized into strict internal modules, one per business domain, that talk to each other only through small public interfaces. You keep the simplicity of a single app and a single database while preserving clean seams, so any module can become a separate service later if a real need appears.

Does the architecture choice affect MVP cost and timeline? Significantly. A monolith means one pipeline, one deploy, and no distributed-systems work before launch, which is a large share of why lean MVPs ship in weeks rather than quarters. We break the timeline math down in how long it takes to build an MVP.

Ship the boring architecture, keep the exciting roadmap

Your users cannot see your architecture. They can see whether the product works, and how fast it improves, and a modular monolith maximizes both while quietly keeping every future door open. If you are weighing this decision for your own build, or holding a half-finished distributed system that has stopped moving, talk to us. We have shipped this playbook across marketplaces, fintech, and SaaS, and we are happy to tell you honestly which parts of it fit your product.

All posts

Contact

Have a project in mind?

We reply within 24 hours.