A curated example by the ChatRound team

GPT-5.6 Sol · Claude Opus 5 · Gemini 3.1 Pro

Round 1Microservices or a monolith for a 10-person startup in 2026? One B2B product, two squads, daily deploys, no platform team. Argue for a concrete choice, not "it depends".

Initial answers

Moderator summary

Choose a disciplined modular monolith; earn service extraction only from demonstrated operational need

Architecture: Use one repository, one backend deployable, and one PostgreSQL cluster, with strict domain modules owned by the two squads. This preserves simple transactions and debugging while keeping future extraction possible.

Delivery: Daily releases should rely on trunk-based development, small pull requests, feature flags, contract and critical-path tests, expand/contract migrations, and automated rollback—not on independently deployed services. Separate worker processes are acceptable when they share the repository and release process.

Boundaries: Package by business domain rather than technical layer; expose narrow public interfaces; prohibit direct imports into another module’s internals and arbitrary cross-module SQL. Enforce these rules in CI with import-boundary checks and schema ownership. Claude’s strongest warning is that aspirational boundaries decay into a ball of mud unless violations fail the build.

Why not microservices now: With only two squads and no platform team, service-specific CI/CD, observability, network security, contract versioning, retries, timeouts, and partial-failure handling would consume product capacity. The exact platform burden is not established here; Sol cites an unverified estimate of two to four senior engineers. A B2B product is also more likely to benefit from local ACID transactions than from prematurely introducing sagas (Gemini).

Extraction rule: Do not schedule a blanket migration. Extract only a module with proven radically different runtime or scaling needs, an isolation or compliance requirement, a repeatedly blocked release cadence, or a materially different failure profile. Vendor-owned capabilities should usually remain vendor services rather than becoming services you operate. The panel differs on when a broader split becomes justified: Claude proposes roughly 25–30 engineers, four-plus squads, and named platform ownership; Gemini says closer to 50 engineers, while Sol avoids a headcount threshold.

Disagreements

  • Future split threshold: Claude proposes considering broader service decomposition at roughly 25–30 engineers and four-plus squads with platform ownership, whereas Gemini places that point closer to 50 engineers; Sol uses workload and organizational triggers rather than a headcount rule.

Blind spots

  • Operational evidence gate: Every reply recommends a monolith but does not define baseline measurements—such as rollback rate, deploy-induced incidents, cross-squad blocking time, or service-specific resource saturation—that should determine whether the choice is still working. These measurements could materially change the next architecture decision.

  • Team and workload specifics: The recommendation assumes ordinary B2B scaling, failure, and compliance needs without confirming the product’s actual workload shape, latency isolation requirements, or regulatory boundaries. A single unusually demanding subsystem could justify an immediate carve-out.

GPT-5.6 Sol

Choose a modular monolith. One repository, one primary deployable, one database cluster, and strict internal module boundaries.

For a 10-person startup with two squads and no platform team, microservices would consume scarce engineering capacity without solving a problem you currently have.

Why this is the right choice

  • Two squads do not require distributed services. Give each squad ownership of specific modules and enforce boundaries through APIs/interfaces, code ownership, and architecture tests.
  • Daily deployment is compatible with a monolith. Use trunk-based development, feature flags, fast CI, and automated rollback. Independent services are unnecessary when the whole B2B product can reasonably ship together.
  • No platform team is the decisive constraint. Microservices require service deployment pipelines, distributed tracing, contract testing, centralized logging, network-failure handling, and substantially more on-call complexity. One 2026 framework estimates that the necessary platform function commonly occupies 2–4 senior engineers—an unreasonable share of your company internative.net.
  • Your priority should be product throughput. Early-stage teams benefit more from easy local development, atomic changes, straightforward debugging, and one production deployment than from theoretical service autonomy. Recent startup guidance likewise recommends beginning with a well-structured monolith rather than paying the distributed-systems tax prematurely yogreet.com.

Build it concretely

Use this operating model:

  1. One repository and deployable

    • A single backend application.
    • One CI pipeline and deployment process.
    • Frontend may remain separately deployed if your hosting naturally supports that; do not turn backend modules into services.
  2. Explicit business modules

    • Organize around domains such as identity, accounts, billing, workflow, and reporting.
    • Assign each module to one squad.
    • Prevent direct imports into another module’s internals.
  3. One PostgreSQL cluster with owned schemas

    • Each module owns its tables or schema.
    • Cross-module access goes through application interfaces, not arbitrary SQL joins from anywhere.
    • Keep transactions local where possible, while retaining the ability to use atomic transactions when the product genuinely requires them.
  4. Background jobs in the same codebase

    • Run workers as separate processes when needed, but deploy them from the same repository and release.
    • This gives workload separation without prematurely creating independently governed services.
  5. Optimize the deployment pipeline

    • Trunk-based development and small pull requests.
    • Feature flags for incomplete work.
    • Automated tests focused on module contracts and critical user journeys.
    • Expand/contract database migrations and automated rollback.
    • CODEOWNERS rather than separate repositories.

A 2026 SaaS MVP analysis recommends essentially this shape—single deployable, modular folders, one Postgres instance, and background jobs in the same codebase—because it minimizes infrastructure work while preserving a later extraction path datasofttechnologies.com.

Set a future extraction rule now

Do not schedule a migration to microservices. Extract one module only after production evidence shows that it needs:

  • radically different scaling or hardware,
  • a hard compliance or security boundary,
  • stronger failure isolation,
  • or an independent release cadence that repeatedly blocks the teams.

Until then, keep the boundary logical rather than networked. Your concrete choice for 2026 should be a disciplined modular monolith, not microservices.

Claude Opus 5

Build the monolith. One deployable, one database, modules inside it.

With 10 people, two squads, and nobody whose job is infrastructure, microservices are a tax you cannot afford. The math is simple: microservices trade coding complexity for operational complexity, and operational complexity requires a platform team to absorb. You don't have one. Every hour your two squads spend on service meshes, distributed tracing, contract versioning, and "why is staging broken" is an hour not spent on the B2B product that has to find product-market fit.

Daily deploys are not an argument for microservices. They're an argument for good CI, trunk-based development, and feature flags — all of which work fine on a single deployable. GitHub, Shopify, and Stack Overflow all shipped many times a day on monoliths at scale far beyond yours.

Why the usual pro-microservices arguments fail at your size

​"Independent deploys so squads don't block each other."​ Two squads don't collide often enough to justify a distributed system. If they do, the problem is unclear code ownership, which a CODEOWNERS file fixes for free. And you don't get independent deploys anyway — you get coordinated deploys with extra steps, because your services will be chatty and version-coupled early on.

​"We'll need to scale."​ You will scale one boring way: bigger instances, then read replicas, then a cache. That runway extends far past the load a single B2B product with early customers will produce. Scaling the pieces independently only matters when one piece has a genuinely different resource profile — and that's a carve-out, not an architecture.

​"Rewriting later is painful."​ Extracting a service from a well-modularized monolith is a week of work. Merging services back together after you got the boundaries wrong is a quarter. Boundaries are the thing you have the least information about right now — you don't know your domain well enough at 10 people to draw them correctly. Wrong boundaries turn a refactor into a distributed-systems migration.

​"Fault isolation."​ A distributed system without a platform team has more failure modes, not fewer: partial failures, retry storms, timeout cascades, and inconsistent state you can't reason about. A monolith fails in one obvious place.

What "modular monolith" concretely means

The discipline isn't optional — this is what buys you the option to split later.

  • Package by domain, not by layer. billing/, onboarding/, reporting/ — not controllers/, services/, repositories/.
  • Enforce boundaries mechanically. Import linting (ESLint boundary rules, Java ArchUnit, Ruby Packwerk, Python import-linter). If a rule isn't enforced in CI, it doesn't exist.
  • Each module exposes a narrow public interface. Everything else is private. Cross-module calls go through that interface only — no reaching into another module's tables.
  • One database, but schemas per module. No cross-schema joins. This is the single highest-leverage rule: it's the constraint that makes a future extraction mechanical instead of archaeological. Keep transactions where they help you, but keep the data ownership clean.
  • Async where the coupling is temporal. An in-process event bus or an outbox table gets you the decoupling benefit of events with none of the message-broker ops.
  • Ship boring ops. One Postgres, one app running on a container platform you don't manage (Fly, Railway, Render, ECS, Cloud Run), one CI pipeline, structured logs, a hosted APM. Migrations run automatically on deploy. Feature flags for everything risky.

The legitimate carve-outs

Pull something out of the monolith only when it meets one of these tests — and expect zero to two of them in your first two years:

  1. Radically different runtime. GPU inference, a Python ML service alongside a TypeScript app, long-running video or document processing.
  2. Different scaling or failure profile. A webhook ingest endpoint that must stay up when the app is down, or a batch job that would starve web workers.
  3. Compliance blast radius. A separate boundary for cardholder data or a customer-specific data-residency requirement.
  4. Something a vendor should own. Auth, billing, search, email. Not your code at all — the best microservice is one you don't operate.

Workers and cron jobs running the same codebase as separate processes are not microservices. Do that freely; it's just process separation.

The trigger to actually split

Write it down now so the decision isn't made by whoever read a blog post most recently. A reasonable line: ~25–30 engineers, four-plus squads, and a named person or pair owning developer platform. Before that, splitting costs you velocity. After that, coordination overhead starts costing more than distribution does.

The honest failure mode

Modular monoliths rot when the boundaries are aspirational. Six months in, someone needs a number from billing for a reporting screen, writes a direct query under deadline pressure, and nobody notices. Do that thirty times and you have a big ball of mud — which is worse than microservices, because you get the coupling without the enforced interfaces.

Prevention is cheap: boundary linting in CI on day one, a schema-access rule that fails the build, and a 15-minute architecture review whenever a PR touches two modules' public interfaces. If your team won't hold that line inside one repo, it definitely won't hold it across twelve.

Gemini 3.1 Pro

Build a modular monolith. For a 10-person startup with no platform support, choosing microservices is an operational trap that will steal your focus from the product and grind your daily deployments to a halt.

Here is exactly why a modular monolith is the only sensible choice for your setup:

  • Zero infrastructure tax: Microservices demand a hidden platform team. Without one, your two product squads will drown in the overhead of managing distributed tracing, complex network security, and multiple CI/CD pipelines. A monolith requires exactly one automated pipeline, one monitoring setup, and one core infrastructure stack.
  • Frictionless daily deploys: Deploying a single artifact daily is a solved, trivial problem. If you use microservices, daily deployments require cross-service integration testing, strict API versioning, and orchestrated rollouts just to ensure Squad A's deployment doesn't break Squad B's service.
  • Perfect boundary for two squads: Two squads (about 4–5 engineers each) do not need physical network boundaries to avoid stepping on each other's toes. You can achieve total team autonomy by enforcing strict logical boundaries—using distinct namespaces, modules, or bounded contexts—while sharing the same codebase.
  • B2B complexity requires simple transactions: A single B2B product usually faces complex business logic and relational data requirements, not massive consumer-scale traffic. A monolith allows you to use standard, safe, ACID-compliant local database transactions. Microservices force you into distributed data patterns like sagas, which are notoriously difficult for a small team to build, debug, and fix when they fail.
  • Cheap pivots and refactors: Startups change direction. In a monolith, moving a feature from Squad A's domain to Squad B's domain is a simple, compiler-checked IDE refactor. In a microservices architecture, changing a domain boundary requires migrating data across databases, writing throwaway API adapters, and coordinating staggered deployments.

Keep your infrastructure boring so your 10 engineers can spend 100% of their cycles building the product your customers pay for. If you build a monolith with clean modular boundaries today, it will be easy to split into microservices years down the line when you finally have 50 engineers and a dedicated platform team.

Follow-up 1

Moderator summary

Start with a modular monolith; extract only a named module after measured operational pain

The round became more precise: Gemini withdrew its rigid 50-engineer threshold, while Claude withdrew the claim that extraction is a roughly one-week task. The recommendation remains a modular monolith, but now with an explicit review instrument and escalation ladder.

What changed: Gemini now accepts roughly 25–30 engineers and four to five squads—with dedicated platform ownership—as a point where the default may flip. Claude demotes that headcount figure to a proxy: a specific module can earn extraction much earlier, while a 24-person team may still need none.

Keep the default simple: Use strict in-repository modules, one primary deployable, and shared database transactions where they are valuable. For heavy imports, PDF generation, or similar workloads, first use separate worker processes and infrastructure profiles rather than network services (Gemini).

Measure before extracting: Claude proposes a monthly scorecard reviewed quarterly: p50 PR merge time above 24 hours, p95 CI above 30 minutes, fewer than 0.5 deploys per squad per day for three weeks, more than three cross-squad-blocked deploys monthly for two months, change-failure rate above 20%, or rollback recovery above 45 minutes are investigation signals—not automatic service triggers. Boundary health should also be tracked: zero cross-schema joins, fewer than five known cross-module transactions, and no rising lint suppressions (Claude). These are proposed operating thresholds, not externally verified facts.

Extraction ladder: Fix CI and PR size, redraw boundaries, then run multiple independently scaled processes from the same artifact before separating schemas and introducing outbox-based integration. Only then create a service with its own database (Claude).

Where the recommendation remains conditional: Claude says a single evidenced compliance boundary, runtime mismatch, availability coupling, or vertical-capacity limit can justify extracting one module even at 12 engineers. Gemini says such compute or failure pressure should first be handled with process separation and reserves true extraction for organizational friction. No product-specific workload or compliance facts were supplied to decide that branch.

Disagreements

  • Early extraction triggers: Claude says one demonstrated compliance, runtime, availability, or vertical-capacity problem can justify extracting a module at 12 engineers; Gemini says compute and failure isolation should normally be solved with separate processes until organizational friction becomes the bottleneck.

  • Delivery metrics as triggers: Claude treats slow CI, low deploy frequency, and rollback time as signals for cheaper monolith fixes rather than direct split triggers; Gemini labels a consistently over-30-minute pipeline or deployment queue blockage an extraction trigger.

  • Role of headcount: Both now reject waiting until 50 engineers, but Claude treats 25–30 engineers as only a default-flip proxy, whereas Gemini treats roughly 25–30 engineers plus platform ownership as the typical tipping point for broader extraction.

Blind spots

  • Current baseline: Neither reply establishes the product’s actual CI duration, change-failure rate, cross-module transaction count, workload saturation, or compliance commitments, so it remains unknown whether the proposed default already has an immediate exception.

Claude Opus 5

First, the conflict: "easy to split later" is the claim that kills modular monoliths

Gemini is directionally right that modularity preserves optionality, and wrong about the word "easy." I should hold myself to the same standard: I said extracting a service from a well-modularized monolith is "a week of work." That was too glib, and it's the same error. Let me correct both.

What clean modules make cheap is the code move. What they don't touch is everything that actually consumes the quarter:

  • Data. A module with its own schema and no cross-schema joins still has foreign keys, shared reference tables, and reports that read across everything. Splitting the database is the project. The code is a rounding error next to it.
  • Transactions. Every place you relied on a local ACID transaction across two modules becomes a saga, an outbox, or a reconciliation job. Enforced import boundaries don't reveal these — a lint rule can't see that two modules commit together.
  • Operations. The first extraction is where you buy tracing, service discovery, contract tests, per-service on-call, and a deploy ordering story. That cost lands on service #1, not service #12.

So the accurate formulation is: clean modules make extraction mechanical rather than archaeological. They convert an unbounded excavation into a scoped, estimable project — a good multi-week project instead of a bad multi-quarter one. Telling a founder it will be "easy" is how they under-invest in the boundaries that make it merely mechanical.

Two things follow. First, add one metric that lint can't give you: count the transactions that span module boundaries. That number, not import graph cleanliness, is your true extraction cost. Second, stop treating headcount as the trigger.

The scorecard

Measure monthly, review quarterly, one page, one named owner. Three families: is the monolith healthy, are the boundaries real, and has a specific module earned its exit.

Family 1 — Delivery health (is the monolith still fast?)

Metric Healthy Investigate Act
PR opened → merged to main, p50 < 4h 4–24h > 24h
CI: commit → green, p95 < 15 min 15–30 min > 30 min
Deploys per squad per working day ≥ 1 0.5–1 < 0.5 for 3 weeks
Deploys blocked waiting on another squad's fix < 1/mo 1–3/mo > 3/mo for 2 months
Change failure rate < 10% 10–20% > 20%
Rollback → green, p95 < 15 min 15–45 min > 45 min
Incidents whose root cause was in a module the deployer doesn't own < 1/quarter 1–2 ≥ 3/quarter

Note that none of these trigger a split. Every one of them has a cheaper fix inside the monolith, and that's the point — they tell you whether the monolith is failing you or whether your CI is just slow.

Family 2 — Boundary integrity (is it still modular?)

These are the leading indicators. If these rot, you lose the option Gemini is counting on.

Metric Healthy Act
Boundary-lint suppressions / allowlist entries Flat or shrinking Any net increase two quarters running
Queries joining across module schemas 0 ≥ 1 (fix this week)
PRs touching more than one module's public interface < 15% > 25% for a quarter
DB transactions spanning module boundaries Known, listed, < 5 > 10, or any you can't enumerate
Files edited by both squads in the last 90 days < 15% > 30%
Modules with no single owning squad 0 ≥ 1

The cross-module PR rate above 25% almost never means "we need microservices." It means your module boundaries are drawn in the wrong place — and splitting on wrong boundaries is the failure Gemini's "years down the line" framing lets you walk into. Redraw first, while it's still a compiler-checked refactor.

Family 3 — Earned extraction (has one specific thing outgrown the process?)

Each of these is about a single module, with production evidence, and each requires that the in-process remedy has already been tried and documented as insufficient.

Signal Threshold
One module's share of peak CPU or memory > 40%, with a resource profile unlike the rest
Interactive p99 during batch/heavy work Degrades > 2× after separate worker pools were tried
Vertical runway Within one instance-size step of your provider's largest, or DB writes > 60% of a single primary at peak
Availability coupling ≥ 2 incidents/quarter where a non-critical module broke a critical path, after timeouts, bulkheads, and circuit breakers
Runtime mismatch A required capability doesn't exist in your language (GPU inference, a Python-only ML library)
Compliance A signed or late-stage deal with a data-residency or certification requirement, with revenue and a date attached
Release cadence One module needs a materially different cadence — a customer-facing SDK, a shipped agent, an on-prem component

Any single one of these, at 12 engineers, justifies extracting that module and nothing else. Zero of them, at 24 engineers, justifies nothing.

Before you split, climb the ladder

Every rung is cheaper than the one above it. Most pressure dissolves by rung 4, and rung 4 is the one almost everyone skips.

  1. Fix CI. Parallelize, cache, test-select on changed modules. Buys back most "the monolith is slow" complaints.
  2. Smaller PRs, feature flags, expand/contract migrations. Buys back most merge and coordination pain.
  3. Redraw module boundaries in-repo. Buys back a high cross-module PR rate.
  4. Same repo, same database, multiple deployables. Run the web app, the webhook ingester, the batch worker, and the report generator as separate processes from one artifact — scaled independently, deployed independently, failing independently. You get most of the operational benefit of a split with almost none of its cost: no network API contract, no data migration, no distributed transactions, one build, one on-call runbook.
  5. Separate the schema, keep the deployable. Cut the cross-boundary transactions; introduce the outbox. This is where the real cost lives, so pay it while you can still roll back in one commit.
  6. Only now: a separate service with its own database. By this point steps 4 and 5 have done the hard parts, which is exactly why the extraction ends up mechanical.

If a proposed split hasn't exhausted rungs 1–5, it isn't an architecture decision, it's an enthusiasm.

What this changes about my 25–30 number

It demotes it. Headcount was a proxy, and the scorecard is the instrument — so treat 25–30 engineers not as a trigger but as the point where the default flips: below it, the burden of proof is on whoever wants to split; above it, on whoever wants to keep everything in one deployable. Coordination cost at four-plus squads eventually dominates regardless of what the metrics say.

That means extraction can and should happen earlier than 25 engineers when Family 3 fires — I'd expect one, maybe two carve-outs before then, most likely an async worker tier or a compliance boundary. What shouldn't happen earlier is a general migration.

Metrics that look like triggers and aren't

Pre-commit to rejecting these, because they will each be argued with real conviction:

  • Lines of code, repo size, file count. Not signals. Well-modularized large codebases are fine.
  • Merge conflicts. A PR-size problem.
  • ​"Onboarding takes too long."​ A documentation and module-ownership problem; twelve repos make it worse.
  • A squad wants a different language or framework. Almost always a preference wearing a costume.
  • Recruiting optics. Real, and not worth a distributed system.
  • A single traffic spike. Needs three months of data, not one bad Tuesday.
  • Headcount alone. Which is the concession I'm making about my own original threshold.

The quarterly review has exactly three possible outputs: keep going, fix a named rung on the ladder, or extract this one named module for this one named reason. Write the reason down at the time. The failure mode isn't picking wrong — it's picking correctly and forgetting why, then relitigating it every time someone senior reads a blog post.

Gemini 3.1 Pro

You should not wait until 50 engineers to extract. I concede to Claude Opus 5: a rigid headcount target of 50 engineers is too late. Waiting that long usually forces teams to suffer through months of deployment gridlock. The tipping point typically arrives around 25–30 engineers (four to five squads), provided you have hired dedicated platform engineers to absorb the distributed systems tax.

However, before reaching that headcount, isolated scaling or failure issues should be solved with infrastructure deployment patterns, not by extracting microservices.

Why scaling and failure profiles don't justify early extraction

If a specific module—like heavy PDF generation or an intensive data import—threatens the monolith at 15 engineers, you do not need a microservice. You need process separation.

You can deploy the exact same monolith codebase onto different infrastructure profiles. Run your web traffic on standard instances, and run your asynchronous background jobs on compute-optimized instances. This solves scaling and failure isolation without introducing multiple repositories, network boundaries, or contract testing. True extraction should be reserved for when organizational friction, not compute limitation, becomes the bottleneck.

The Operational Scorecard

To remove guesswork from the extraction timeline, track these three concrete metrics. As long as your monolith stays within these bounds, it is succeeding. When these thresholds are consistently breached, it is time to extract a service.

  • CI/CD Pipeline Duration:
    • Success: The main branch builds, tests, and deploys in under 15–20 minutes.
    • Extraction Trigger: The pipeline consistently exceeds 30 minutes, or the deployment queue constantly backs up because rollbacks from one squad block another squad's hotfix.
  • Incident Blast Radius:
    • Success: Bugs are localized to the offending squad's domain.
    • Extraction Trigger: A resource exhaustion bug (like a memory leak or database connection exhaustion) in one domain takes down the entire application more than twice in a single quarter.
  • Merge Conflict Frequency:
    • Success: Squads rarely touch the same files or database schemas.
    • Extraction Trigger: Engineers spend more than 10% of their weekly time resolving git conflicts or coordinating schema migrations across team boundaries.

By relying on this scorecard, you let your actual operational pain dictate your architecture, rather than an arbitrary headcount or theoretical scaling concerns.