How do you decide which subgraph should own a field so that query plans stay shallow?
answer
- Latency, ownership, change cost
- Budget the hot operations only
- Every lever has a stated price
- Some callers cannot be redeployed
- Check the shape in the pipeline
basics
~20 sStart from the hot operations, not the schema. Place a field where the traffic that matters reaches it in the fewest dependent hops, and treat ownership as a team decision with a real migration cost.
solid answer
~50 sPlan depth is decided at schema-design time, so field placement is a latency decision disguised as a modelling one. The defensible method is traffic-first: take the handful of operations that carry real volume, plan them, and set a depth budget for those — not for the schema in the abstract. Then choose among the levers with their costs stated. Moving a field to the subgraph that already holds the objects removes a hop but moves on-call ownership with it. Promising a borrowed field inline removes a hop only where the promise was declared. Duplicating a small, stable field across two subgraphs removes a hop and buys a consistency obligation. Doing nothing is often correct for cold paths. Finally, sequence the change against reality: documents pinned in shipped clients cannot be redeployed, so an ownership move is a coordinated migration, not a schema edit — a careless rename of an owned field is how a mobile release breaks.
code
graphql · 13 lines# Jobs subgraph
type Job @key(fields: "id") {
id: ID!
title: String!
employer: Employer!
}
# Employers subgraph
type Employer @key(fields: "id") {
id: ID!
name: String!
verified: Boolean!
}go deeper
Recall only that where a field lives affects how many services a request has to visit, and that the composed schema hides that from callers. You will not be asked to make this call.
Be able to trace a single field's placement to a round trip in a plan, and to say what a duplicate copy of a field would cost in consistency terms. Recognise the tradeoff rather than resolve it.
Argue a specific placement with numbers: which operations improve, by how many rounds, and what the migration costs. Show you would keep the composed schema stable through the change.
Own the method and the process: a depth budget on operations chosen by real traffic, a check in the composition pipeline with a named owner, and a clear stance on when the boundary itself, not the field, is the problem.
## The decision is not "where does this field belong" Asked abstractly, field placement has a tidy answer: a field belongs with the team that owns the data behind it. Asked in the context of a real graph it is messier, because that tidy answer is also what produces four-round plans on your busiest screen. The honest framing for a lead is that placement trades three things against each other — **latency**, **ownership clarity**, and **change cost** — and that no rule resolves all three at once. ## Start from traffic, not from the schema The common failure is to survey the whole composed schema hunting for deep paths. Most of them do not matter. On a job-board graph, ten operations typically carry the overwhelming majority of volume: the search results page, the posting detail, the application list, the employer dashboard. Plan those, record their depth, and give *those* a budget. A five-round plan behind an internal reporting screen used twice a day is not a problem worth a cross-team migration, and treating it as one spends the organisation's appetite for schema change on something with no return. ## The levers, with their costs said out loud **Move the field.** Cleanest for latency when the field's data genuinely sits with the objects that need it, and it usually also improves the model. It moves on-call and roadmap ownership with it, which is why it is a negotiation and not a pull request. Federation gives a directive for taking over a field from another subgraph so the move can be staged rather than done as a flag-day cutover. **Promise the field inline.** When an intermediate subgraph already has a borrowed value in hand, it can declare that it can supply it, which lets the planner skip a round for that path. This is the cheapest lever when it applies, and its failure mode is subtle: the promise holds only where it was declared, so the same field elsewhere in the graph still costs a hop, and a plan that looked shallow for one operation is not shallow for another. **Duplicate a small, stable field.** Verification status, a display name, a currency code — fields that are tiny, change rarely, and are read constantly. Duplicating one across two subgraphs removes a hop outright and buys an obligation: two writers, or one writer plus a propagation path, and a real answer to what a reader sees during the window in between. Worth it for a handful of fields, corrosive as a habit, because a graph where every subgraph carries a copy of everything has stopped being a federated graph. **Reshape the operation.** Sometimes the fix is not the schema. Splitting a deep branch out of the first-paint request and fetching it after render removes it from the critical path without any cross-team negotiation at all. This is frequently the fastest available win and it is routinely overlooked because it lives on the calling side. **Consolidate a boundary.** If two subgraphs are so entangled that every interesting operation crosses between them repeatedly, the question is not where a field goes; it is whether the split is real. Boundaries drawn around teams that later merged, or around a decomposition that never finished, produce depth that no per-field decision fixes. ## The constraint people forget Callers you cannot redeploy. Shipped mobile builds hold documents you no longer control, and they will keep sending them for as long as those versions are installed. That has two consequences for this decision. First, changing where a field lives must be invisible in the composed schema — same name, same type, same nullability — or you have made a breaking change dressed as an optimisation, and a rename here is exactly how a mobile release breaks in the field weeks after the schema merged. Second, the operations you must protect are the ones already in flight, which means the traffic sample you plan against should come from real observed documents rather than from what the current front end happens to send today. ## Making it a process rather than a heroic The part a lead actually owns is turning this from occasional archaeology into something routine. Composition already runs in a pipeline before deployment; planning a fixed set of important operations against the newly composed schema and comparing their depth to the previous one is a mechanical addition to it. Then a change that pushes a hot operation from two rounds to four fails a check with a named owner, instead of arriving as a latency alert three weeks later that three teams each investigate separately and each conclude is not theirs. That last outcome — every service healthy, the composed query slow, nobody accountable — is the organisational failure mode this whole discipline exists to prevent.
- When is duplicating a field across two subgraphs the right call rather than a modelling smell?When the field is small, changes rarely, is read on a hot path, and has an unambiguous writer. Verification status or a display name qualify; anything transactional or frequently updated does not. State the consistency contract explicitly — who writes, how the copy is propagated, what a reader sees in between — and cap how many such fields exist, because the habit dissolves the ownership model that justified federating at all.
- How do you move a field's ownership between two teams without breaking callers?Keep the composed schema identical throughout — same field name, type and nullability — so no caller sees a change. Stage the move with the federation directive that transfers ownership of a field from one subgraph to another, deploy the receiving subgraph first, compose, verify the plan shape and the served values, then remove the field from the original owner. Treat it as a migration with a rollback, not a schema edit.
- Which operations should carry a plan-depth budget?The ones with volume and a user waiting: typically a small number of screens that dominate traffic. Derive the list from observed operations at the router, including documents from client versions you cannot redeploy, rather than from what the current front end sends. Cold and internal paths get no budget; spending cross-team change risk on them buys nothing.
- What signal tells you the boundary itself is wrong rather than one field's placement?Repeated crossings in both directions. If most valuable operations bounce between the same two subgraphs several times, no per-field move will help — you will keep relocating fields and keep finding new depth. That pattern usually means the split follows an org chart that has since changed, or a decomposition that stopped halfway, and the honest fix is to revisit the boundary.
saying these in an interview costs you the question
- Moves field ownership without checking documents already shipped
- Duplicates fields across subgraphs with no writer named
- Optimises plan depth on paths nobody actually calls
- Treats a subgraph boundary as a purely technical choice
- Assumes a shallower plan is always the better design