Monoliths and composable sit on my mind tonight because a client pinged me at 2 AM. Their checkout froze during a promotion and the hotfix was stuck waiting for a full deploy of a single giant app. The team stared at the progress bar the way you stare at a microwave when you are starving. We got it live, but it felt like pushing a car up a hill. On the other side of the thread, another client bragged about pushing a change to a headless commerce cart in two minutes. Same market. Same traffic spike. Very different body language.
That is the split. Do we keep a monolith that feels safe and simple, or do we go composable with smaller services, Jamstack front ends, and cloud bits that talk through APIs. It is not a faith decision. It is a fit decision. And right now, with teams spread across homes and Slack rooms, with Next.js conf still fresh and MACH Alliance messaging everywhere, a lot of folks are asking the same thing: where do we draw the line.
Story time is over. What split makes sense today
The old rule of thumb used to be pretty loud. Start with a monolith. Keep shipping. Break apart when pain shows up. That still works, but it needs a clearer map because the stack got richer. Kubernetes is boring now. Serverless runs close to free at small scale. Vercel, Netlify and Cloudflare Workers give front ends super fast delivery. Headless CMS is normal. Composable commerce is not fringe. So the question is not only when to split. It is also what to split.
Here is a pattern that holds up in real teams:
- Split on change rate. Parts that change daily deserve independence from parts that move once a quarter. Think pricing rules, search tuning, content, checkout tweaks, experiment flags.
- Split on blast radius. If a mistake in promo logic can not be allowed to bring down account log in, give promo logic its own box. If search burns out under load, do not let it eat the rest of the site.
- Keep data where it belongs. If two domains share a database table and a deploy, they are the same thing. If you find yourself doing gymnastics to keep them from stepping on each other, they want to be separate.
- Follow Conways law, but on purpose. If you have a team for checkout and a team for catalog, do not glue their work into one deploy train.
Notice what we did not say. We did not say split because microservices are trendy. We did not say split because a talk convinced you that your monolith is a dinosaur. The move to microservices and APIs creates new work. You only want that work if it buys you speed or stability.
For commerce and content sites, a clean line forms between the experience layer and the core domain:
- Experience layer: routing, pages, UI, cart widget, search results, personalized blocks. This pairs well with Jamstack and edge caching. It likes small services and fast deploys.
- Core domain: catalog data, pricing engines, inventory, order state, payment capture. This prefers stronger data rules, fewer moving pieces, and deeper tests.
So a common split right now is a monolith core with a composable experience. That gives you the faster loop at the edge with the calmer center that moves slower. People call this headless because the front end is out on its own, talking to the core through APIs. This is not only for giant shops. A small team can pull this off with one repo for core and one for frontend. That alone cuts a ton of friction.
Tradeoffs that are real, not theoretical
Let us be straight. Complexity moves. You do not delete it. You decide where it lives.
- Deploy speed vs mental load. Many small services ship faster, but you spend more time thinking about edges and contracts. One big app ships slower, but you can jump around the code with less context switching.
- Latency vs cache. Calls across the network add time. You will lean on caching. That brings cache misses and stale content problems. A monolith can do a function call in memory and skip all that, but then you cannot put the response at the edge as easily.
- Data truth vs data copies. Composable setups often copy data to make the front end fast. That is fine until you forget a refresh path and show old prices. Monolith keeps data in one place, but then you pay in slower page builds or fewer features at the edge.
- Team focus vs team drift. Separate services keep teams focused. They also drift in style and tooling. A monolith keeps style tight but creates traffic jams in the backlog.
Today the industry mood leans to APIs first. Jamstack Conf just wrapped and the energy was real. BigCommerce had a big year. Shopify Storefront API keeps gaining fans. The MACH Alliance is publishing playbooks and case studies. AWS re Invent is around the corner and will flood our feeds with more managed parts to wire up. All that is fuel for composable thinking. Still, shipping wins. Choose the shape that lets your team ship safely on a steady beat.
Risks when you split too far or not far enough
- Ping pong performance: Pages call five services which call three more. Under load you get the worst kind of outage. Nothing is down, but everything is slow. Users bounce.
- Orphaned services: A small service loses its owner. No one knows how it works. Then a minor change causes a chain reaction. Documentation will not save you if ownership is unclear.
- Test holes: Unit tests are great. What fails in composable setups is the contract between services. Without consumer driven tests or contract checks, a tiny change can break a checkout.
- Monolith drag: On the other side, a single giant app blocks high change areas. Promotion rules wait for a release train that runs once a week. Marketing misses the moment.
- Security sprawl: Many services mean many tokens, secrets, and roles. A quick script with the wrong key can leak data. Centralize secrets and keep short lived credentials.
- Cost surprises: Small calls feel free until you add up egress, function runs and build minutes. Watch your bills and set budgets with alerts.
Decision checklist
Use this before you cut a new service or before you decide to keep everything in one box.
- Does it change faster than its neighbors? If yes, give it a path to ship on its own.
- Would a failure take down core checkout or account? If yes, isolate it behind a feature flag or a separate service.
- Can you draw a clean API? If the contract is fuzzy, the split will hurt. If the contract is crisp, the split will help.
- Do you have an owner? Services without owners become chores. No owner means no split.
- Is data ownership clear? One service should be the source of truth. Others can cache or index, but one owns writes.
- Do you have end to end tests for the flow? If not, add them before the split. You will need them the day after.
- Will this lower your time to recover? If the split makes rollbacks or hotfixes faster, that is a strong yes.
- Can you measure it? Add metrics for latency, error rate, and deploy frequency. If you can not see it, you can not guide it.
Action items for the next month
- Map your domains: Draw boxes for catalog, pricing, inventory, checkout, content, search, account. Under each, list owners, change rate, and pain points.
- Pick one seam: Choose the cleanest boundary. For many shops, it is the front end. Move to a Jamstack site that calls your existing APIs. Keep the core as is. Ship faster at the edge.
- Add a gateway: Put an API gateway in front of the core. Even if you stay monolith inside, the gateway gives you a place to add rate limits, auth and routing to future services.
- Flag everything: Wrap high risk features in flags. A flag is a mini service split without the network hop. You get safe rollouts and instant off switches.
- Own your contracts: Write down API shapes and add contract checks in CI. When a change breaks the contract, fail the build. Talk before you ship.
- Measure deploys: Track deploy count, lead time, and time to recover. If the numbers get better after a split, you are on track. If not, stop and learn.
- Lean on caching on purpose: Add short TTL caches at the edge for read heavy calls. Pair with clear refresh paths. Do not rely on luck.
- Set a cost budget: Add alerts on your cloud bill for data transfer and function runs. Catch surprises early.
There is no single right answer. The right split is the one that your team can own and ship with. A calm core. A fast front end. Clear data owners. Clean contracts. That mix suits where web tech is today, with strong hosting at the edge, solid managed databases, and a lot of pressure to move quickly without breaking the cash register.
So next time you are staring at a frozen deploy bar in the middle of the night, ask a simple question. What is the smallest thing we can pull out that would have let us fix this in minutes. If you can name it in one sentence, you just found your next split.