Vitess query-serving documentation (23.0)
The project’s own reference pages on how a sharded query is planned and executed — Execution Plans, VTGate, VEXPLAIN and Sharding, read at version 23.0 on 2026-08-03. Pulled deliberately as the readable counterpart to sharded-pagination-interview-post, which posed the cross-shard pagination question from behind a paywall.
The design principle, stated in one sentence
One of the underlying goals of Vitess’ planning strategy is to push down as much work as possible to the underlying MySQL instances. When this is not possible, Vitess will use a plan that collects input from multiple sources and merges the results to produce the correct query result.
That sentence is the whole of cross-shard-queries. Everything else is mechanism for deciding which case you are in.
How a plan is built
A plan is a tree of operators, each taking zero or more rows in and producing zero or more rows out. Leaves pull from VTTablet or the topology service; each node pipes into its parent; the root returns the result. Operators that join two branches merge two input streams into one.
A routing operator “instructs Vitess which destination to send a piece of work to” — the keyspace, whether it is sharded, and which vindex to use. The vindex is the pivot: it maps a column value to a shard.
Scatter is defined by its absence:
A routing operator which specifies a sharded keyspace, but which does not specify a vindex, will “scatter” to all shards in a sharded keyspace.
With a careful qualifier the docs add immediately after: “not all queries which are sent to multiple (or all) shards in a sharded keyspace are considered scatter queries.” Fan-out and scatter are not synonyms — a query can address several shards because it named several keys.
VTGate is the merge point
VTGate is a lightweight proxy server that routes traffic to the correct VTTablet servers and returns consolidated results back to the client. It speaks both the MySQL Protocol and the Vitess gRPC protocol. Thus, your applications can connect to VTGate as if it is a MySQL Server.
Routing decisions weigh “the sharding scheme, required latency and the availability of tables and their underlying MySQL instances.” This is database-sharding‘s proxy-router bullet in the vendor’s own words, and the “as if it is a MySQL Server” is the promise that makes the whole abstraction usable and occasionally expensive.
VEXPLAIN — the instrument
Since Vitess 16, VEXPLAIN shows what a statement actually does. Five modes, and two of them matter
for this spoke’s open question:
TRACE executes the query and annotates every operator with what it cost: NoOfCalls,
AvgNumberOfRows, MedianNumberOfRows, and — the number the corpus was missing — ShardsQueried.
The docs recommend it for “identifying performance bottlenecks” and “understanding how your query
is executed across different shards and operators.” A sample trace in the docs shows a
Route/Scatter leaf reporting "ShardsQueried": 2 under an Aggregate with
"Variant": "Ordered" and a Projection above it — the merge happening at the proxy, made visible.
KEYS analyses a statement without executing it and reports groupingColumns, joinColumns,
filterColumns and statementType, explicitly as candidates for “sharding keys”, vindexes or
indexes. That is the design-time half: it tells you which column would have to be the vindex for a
given query to stop scattering.
The other three: QUERIES (the queries sent to tablets), PLAN (the operator tree without running
it), ALL (plan plus MySQL’s own EXPLAIN output per shard). Cached plans are also browsable at
VTGate’s /queryz endpoint.
What these pages do not say
No statement about deep LIMIT/OFFSET across shards, no documented cost model for it, and no
guidance recommending keyset or cursor pagination. The MySQL-compatibility page lists ordering,
limit, aggregation and grouping among supported query types with the advice to “leave schema
tracking enabled to leverage full support”, and defers edge cases to an unsupported-cases
repository. So the original question — what it costs to serve page 100,000 — is answered in
principle and not in detail: the plan must fan out and merge, and Vitess gives you an instrument to
measure it rather than a number.
Tier
T1. First-party reference documentation for shipped software, version-pinned, describing observable behaviour that VEXPLAIN will confirm or contradict against a running cluster. The standing caution for first-party docs applies: this describes intent and mechanism, not measured performance, and nothing here is a benchmark. Version-specific — operator names and VEXPLAIN modes have changed across releases (VEXPLAIN itself only exists from 16).
Related
cross-shard-queries · vitess · database-sharding · planetscale · sharded-pagination-interview-post · operational-databases · synthesis