When not to split a bounded context around a shared table
Learn when not to split a bounded context when two teams share one table, and use simple checks to find the real business boundary first.

Why shared tables confuse people
A big shared table makes people uneasy. It looks messy, crowded, and too broad to belong to one business area. Once a table holds orders, payments, refunds, notes, flags, and status fields, teams often assume it hides two or three separate domains.
Sometimes that is true. Often it is not.
Database shape and business shape are different things. A table can grow for dull reasons: old migrations, reporting needs, shortcuts from earlier releases, or a team that kept adding columns instead of redesigning the model. None of that proves a real boundary exists. In bounded context design, the boundary shows up in the rules people use to make decisions, not in the fact that one table feels too large.
Org charts make this harder. One team owns checkout, another owns refunds, and a third owns finance reporting. Before long, the software starts to mirror the company structure instead of the business itself. Then a split feels obvious because different teams touch the same data. But different teams do not always mean different domains. Sometimes they are just different groups working on the same rules from different angles.
A split starts to make sense when the rules stay different over time. If one area changes its terms, approvals, timing, and language without dragging the other area along, that is a strong signal. If both sides still change together whenever the business updates a policy, you probably still have one domain with a crowded model.
That is why deciding when not to split a bounded context is often harder than spotting when to split it. Splitting sounds clean. In practice, it can add handoffs, duplicate logic, more meetings, and messy sync work between services or teams.
Take refunds. If every refund rule still depends on order state, pricing rules, fraud checks, and support actions, refunds may not be a separate business boundary yet. They may just be one stage in the order lifecycle. Cut that in two too early and you get more coordination work without clearer ownership.
A shared table is not a boundary
A table tells you where data sits. It does not tell you who owns the meaning of that data.
Teams often see one table touched by two parts of the product and assume they have found two domains. Most of the time, they have found old storage design. A legacy app wrote everything into one place years ago. Reporting grew around it. A new feature reused the same rows because that was faster than adding a new model. That may be messy, but it still does not create a business boundary.
Start with the fields, not the schema diagram. Ask what each field means, who can change it, and which rule decides whether a change is valid. If fields like "refund_status," "approved_by," and "refund_reason" all follow the same support policy, the refund work probably still belongs with order operations, even if finance reads the same table later.
Business language is usually clearer than database structure. If two groups describe the work with the same words, argue about the same exceptions, and follow the same approval path, they are probably inside one context. Split them too early and you usually get duplicate rules, sync jobs, and bugs that show up in two places at once.
A real split shows up in behavior, not storage. You should see differences like these:
- One side can approve or reject changes while the other only reads them.
- The same field means different things to each group.
- Each side uses different terms for the same event.
- Each side can change rules without asking the other.
If you do not see those differences, keep it together. A shared table can look like a clean boundary on a whiteboard and still fall apart the moment both sides need the same business rules.
This shows up all the time in older startup systems. A team sees orders and refunds in one crowded table and wants a neat split. But if the same staff handles both, the same policy decides both, and the same timeline explains both, that is one piece of business work living in awkward storage. Clean up the model first. Split later if the business really splits.
Signs one domain still owns the rules
A real boundary shows up in decisions, not in tables. If one set of policies decides what counts as valid, blocked, approved, or complete for both sides, you still have one domain in practice. The database may look shared, but the business logic still has one owner.
The easiest clue is change control. Watch who asks for rule changes. If the same manager, analyst, or operations group changes both areas, the work usually belongs together. People split systems too early when they see different screens or different reports, even though the rules still come from one place.
Dependency is another strong signal. If workflow B almost always has to ask workflow A for permission, state, or timing, B may not be a separate domain yet. A refund process can look separate from orders because it has its own statuses and notes. But if nearly every refund decision still depends on order state, payment status, shipping progress, and the same approval rules, the order domain still owns the logic that matters.
A few clues tend to show up together. The same people approve changes to both rule sets. Teams edit the same fields in the same release. One group handles exceptions for both areas. Staff use one business name for the whole process instead of naming two distinct capabilities.
That last part is easy to miss, and it helps a lot. Listen to how people talk when something goes wrong. If support, finance, and operations all say "this is part of order handling" instead of naming two separate business capabilities, they probably see one process with a few stages, not two domains.
Release patterns tell the same story. When developers keep touching the same records, validations, and state transitions at the same time, a split will often add friction without giving you clearer ownership. You end up with two services that still need the same meetings and the same decisions.
Wait until the rules, owners, language, and release cadence actually pull apart. Until then, keep the model together and make the internal workflow clearer.
What a real split looks like
A real split shows up in day-to-day work, not in the database. Two areas can touch the same customer, invoice, or shipment record and still be separate domains, but only when they use different business language for different goals. Sales talks about closing a deal and starting billing. Support talks about access, pauses, and policy checks. The same data can appear in both places, but the meaning is different.
The clearest sign is independent rules. One side can change how it works without pulling the other side into the change. If billing changes late-fee rules, support should not need to rewrite its process. If support changes how it verifies an account before reopening it, billing should keep working as usual. That kind of freedom is hard to fake.
A real split also has a handoff that people can name. One team owns the work before the handoff, and another team owns the work after it. You might hear phrases like "payment settled," "claim approved," or "contract signed." Those are not table updates. They are business moments. They tell people where responsibility moves.
Ownership gets clearer too. When something breaks, the team that owns that business moment should pick it up first. If everyone argues about who owns a bad result, the split is still blurry. In a clean boundary, errors have a first owner and people can trace the cause without a long meeting.
Reports often expose the truth. Separate domains produce separate reports because they track different work. Finance may report collected revenue and failed charges. Support may report reopened accounts and exception requests. If one report still mixes everything into a single flow, the business probably has one domain with shared tasks, not two real boundaries.
Think about driver records in a delivery company. Routing uses them to assign trips. Payroll uses them to calculate hours. Both read some of the same data, but each side has its own rules, handoff points, and owner. If you cannot name those three things in your own system, keep the context together a bit longer.
A practical test before you split
Start with decisions, not tables. A shared table can support two features and still belong to one domain if the same rules keep deciding what the data means.
Write down the actual decisions people make from that table. Be concrete. "Can we refund this order?" and "Should we show this order in the customer portal?" are different decisions, but they may still depend on the same business rules.
A simple check usually works:
- List the daily decisions the table supports.
- Mark the rules that tend to change together.
- Note who approves those changes and who deals with the fallout.
- Name the exact handoff where one side gives facts to the other.
- Pause the split if that handoff still sounds fuzzy.
The second step usually tells the truth. If discount rules, refund windows, fraud checks, and status changes keep moving together every quarter, one domain still owns the logic. Two teams may touch the same rows, but that alone does not create a real business boundary.
Approval paths matter too. If the same founder, product lead, or finance manager signs off on changes across both sides, the split is probably cosmetic. The people who feel the impact matter just as much. If support, accounting, and operations all treat the table as one workflow, you likely still have one context.
The clearest signal is the handoff. A real split appears when one side can finish its work and pass facts, not half-made decisions, to the other side. One domain can say, "Payment captured at 10:32, amount $84, method card." The other domain can then apply its own rules without reaching back into the first domain's internals.
If you cannot name that handoff in one plain sentence, wait. Splitting too early usually creates duplicated columns, sync jobs, and arguments about which service tells the truth.
Orders and refunds
Picture a shop where one order touches several records at once: order lines, payment captures, tax amounts, shipping charges, and refund entries. The support team works in the refund screen every day, so it asks for a separate Refunds context.
That request makes sense from a team workflow view. It does not automatically make sense in the domain model.
A refund is rarely its own business area in this setup. The refund decision still depends on order state and payment state. Has the card charge settled? Did the customer receive one shipment or two? Is tax returned in full or only for unopened items? Did fraud checks block manual refunds? Those rules do not live in a support screen. They live in the same policy space as orders and payments.
Now add one policy change. The company updates its order rules so split shipments can be refunded per package, and some express shipping fees stay nonrefundable after dispatch. The refund logic changes at the same time. Support may press the button, but product and finance still decide what that button can do.
That is the pattern to watch. Two teams may touch the same data, yet one domain still owns the rules.
A quick test is to ask a few blunt questions. Can the refund team approve or reject refunds without checking order and payment state? Can order policy change without forcing refund rule changes? Can you define "refund completed" without reusing order, tax, and payment terms?
If the answer is mostly no, you probably have one boundary with different user roles inside it, not two separate domains.
A separate Refunds context starts to make sense only when refunds have their own policies, language, and life cycle. A marketplace is a good example. Refunds there can become a formal claims process with dispute windows, evidence, seller debit rules, and outside payment recovery. That is different.
Until then, keep the model together. Let support own the screen if needed, but do not confuse screen ownership with business ownership.
Mistakes that create fake boundaries
Fake boundaries usually appear when people react to a real pain point that has little to do with the model itself. Two teams argue over a table, so they split the domain. A reporting request grows, so they invent a new context around analytics. The code feels old and tangled, so they rename a module and call the job done.
That move often makes things worse. The table stays shared, the rules stay mixed, and now the system has extra APIs, sync jobs, and new places for bugs to hide.
Team structure causes a lot of bad splits. If sales ops and finance both touch the same customer record, that does not mean the business has two separate domains there. It may only mean both teams need the same data for different reasons. Org charts change every year. Business rules usually do not.
Reporting creates another fake boundary. A dashboard, export, or monthly summary is a read need, not always a domain of its own. If nobody makes decisions or enforces rules inside that reporting area, it probably does not own a bounded context. It is just reading from one.
This shows up in startup systems that grew fast. Someone copies a textbook example and tries to force it onto a business that works differently. The result looks tidy in diagrams and awkward in real life.
Quick checks before you draw the line
A shared table can make two areas of the system look more separate than they really are. Before you split anything, check whether the business actually behaves like two parts or whether one team just reads the same rows for a different reason.
Ask a few blunt questions and answer them with real examples, not architecture diagrams. If the answers stay fuzzy, the boundary probably is too.
Start with decision-making. If the people on one side still need to read the other side's rules before they can act, you do not have a clean split. You have one domain with extra steps.
Then describe the handoff in one short sentence. If you need a paragraph, several edge cases, or a meeting to explain it, the line is not clear enough yet.
Look at the customer view too. Do people experience these as two separate services with different goals, or as one flow with several screens? Customers expose fake boundaries fast.
Release timing helps as well. Separate release cycles should remove waiting and reduce coordination. If they create more sync work, more regression checks, and more broken assumptions, the split is working against you.
One useful thought experiment is simple: if you merged the teams tomorrow, would the boundary still feel natural, or would everyone quietly go back to treating it as one area? That question is often more honest than a design workshop.
This matters even more in small teams. A split that looks clean on a whiteboard can turn into daily back-and-forth, duplicate tests, and release friction. Oleg Sotnikov sees this often in startup work: teams split too early, then spend more time translating rules than building product.
Draw the line only when each side can explain its job, own its rules, and change at its own pace without constant permission from the other side.
What to do in a messy system
When the model feels tangled, do not rush to split it. Start with one table that keeps causing debate, then follow one business workflow through it from start to finish. Look at who creates the record, who changes it, who approves exceptions, and who gets blamed when something goes wrong. That usually tells you more than the schema.
This is often the fastest way to see when not to split a bounded context. Two teams may touch the same data, but that does not mean they own different domains. Sometimes one area still makes the real decisions and the rest of the system only reacts.
Bring product, operations, and engineering into the same review. Product usually knows why a field exists. Operations knows where the process breaks in real life. Engineering knows which rules still sit in shared code, jobs, or database triggers. One short meeting with all three groups can clear up weeks of abstract design talk.
Keep the review simple. Trace the lifecycle of one record, not the whole system. Mark every rule, approval, exception, and status change. Write down which team owns each decision in practice. Keep the context whole until you can name a clean event that hands control to someone else.
That event matters. If you cannot point to something clear like "refund approved," "invoice issued," or "shipment dispatched," the split is probably still fuzzy. A shared-table boundary becomes real when business ownership changes at a specific moment, not when the codebase feels crowded.
It is usually better to keep an awkward model intact for a bit longer than to create two neat-looking contexts with duplicated rules and constant back-and-forth. Premature splits add coordination work, extra bugs, and long arguments about who owns the truth.
If you want a second opinion, Oleg Sotnikov at oleg.is works as a Fractional CTO and helps startups sort out architecture and ownership questions like this. The useful part is not the diagram. It is finding a boundary the whole team can explain without opening the table definition.