Microservice Boundaries and Distributed Data
Microservices trade local simplicity for independent ownership, deployment, scaling, and fault isolation. A valid service owns a cohesive business capability and its data, exposes stable contracts, and can be operated independently. Splitting technical layers or tables across network calls usually creates a distributed monolith with more latency and failure.
What will you be able to do?
- evaluate extraction using evidence rather than fashion;
- select boundaries from business capability and change patterns;
- handle distributed consistency and query needs explicitly;
- migrate one module with a strangler approach.
- a capability needs independent release ownership;
- scaling or compute differs materially, such as ingestion workers or GPU inference;
- security/regulatory isolation needs a separate boundary;
- failures must be isolated from core ticket traffic;
- the interface and domain language are stable;
- the team can own delivery, on-call, SLO, capacity, and data lifecycle.
Measure change coupling. If ticket and candidate “service” change together constantly in one transaction, the boundary may be wrong.
How should data ownership work?
Each service owns its database schema and only its API/events mutate that data. Other services maintain purpose-built projections through events or call the owning service. Cross-service joins become composition, read models, or analytical pipelines. Avoid shared-table writes and distributed two-phase commit for ordinary product flows.
Consistency is a product decision. Show users pending states, version events, reconcile drift, and design idempotent sagas. Strong consistency can remain inside the service that owns the invariant.
- Enforce the existing knowledge-module boundary inside the monolith.
- Define API/events and contract tests.
- Move heavy parsing/embedding workers behind that boundary while metadata still has one owner.
- Route a small tenant cohort through the new service.
- Compare correctness, SLO, cost, and operations.
- Move ownership only after reconciliation and rollback are proven.
Keep user-facing ticket operations independent from ingestion failure.
Why does this matter in AI-native systems?
AI workloads may justify separate scaling and security, but provider gateways, retrieval, evaluation, and agents should not become services solely because they have fashionable names. Excess network hops multiply latency and failure across already slow model paths.
Common mistakes
- One service per database table or FastAPI router.
- Shared database remains the integration contract.
- Synchronous chains create cascading failure and impossible latency budgets.
- No local development, contract test, or distributed trace story.
- Every team chooses a different stack without platform support.
- Cost of duplicate data and reconciliation is ignored.
AI Pair-Programmer Prompt
Exercise
Write an ADR deciding whether model gateway, ingestion, and ticket modules should each become a service at current scale and at 100 teams.
Acceptance criteria: decisions differ only when evidence differs; every extracted service has an owner, data boundary, contract, SLO, migration, and rollback; distributed queries have a design.
Knowledge check
- Should services share write access to tables?
- What makes a service boundary valuable?
- Why are synchronous service chains risky for AI requests?
Answers
- No; one service owns mutation and publishes contracts.
- Cohesive capability plus independent ownership, scale, security, or fault/release needs.
- Each network/dependency hop adds latency and partial-failure probability to an already slow path.
Completion checklist
Primary references