Routing Sharded Queries Through Vitess vtgate Without Rewriting Your App
How Vitess vtgate routes queries to the correct MySQL shard, how to use hints when the sharding key is missing, and how to verify routing with /debug/route.
05 Dec 2025, 20:25 UTC

The problem: your app still talks to one database, but your data lives on many shards
You moved from a single MySQL server to a Vitess cluster because one node could no longer handle the load. Vitess splits a logical database, called a keyspace, into smaller pieces called shards. Each shard holds a subset of rows, chosen by a sharding key such as customer_id or tenant_id.
Your application, however, was written for a single database. It sends statements like:
SELECT * FROM users WHERE email = '[contact removed]';
If email is not the sharding key, vtgate—the Vitess gateway that accepts MySQL protocol connections—cannot tell which shard owns Alice's row. Without help, it either fans the query out to every shard or rejects it. Rewriting every repository in a legacy application is expensive and error-prone.
The useful takeaway is that vtgate can inspect the WHERE clause, extract the sharding key, and forward the statement to the correct shard automatically. When the key is missing, you can supply it with a hint. You can verify the decision before changing production traffic.
How vtgate routes by sharding key
vtgate sits between your application and the MySQL shards. For a SELECT, UPDATE, or DELETE that includes the sharding key in the WHERE clause, vtgate parses the statement, extracts the key value, and forwards the query to the shard that owns that value. Writes always go to the primary of the target shard; reads can be sent to replicas, which gives read scaling without extra configuration.
This works for simple statements that reference a single sharding key. If your query joins tables across shards or uses a subquery that vtgate cannot resolve to one shard, it is rejected unless you provide an explicit hint.
When the sharding key is missing: defaults and hints
Legacy code sometimes omits the sharding key entirely. Vitess can rewrite the statement by inserting a default key value, or you can supply the key through a SQL comment hint. The hint syntax varies by Vitess version and routing rule, so check your cluster configuration before adopting it in production:
/*vt+ */ SELECT * FROM users WHERE email = '[contact removed]';
If the key is missing and no hint or default exists, vtgate may fall back to a configured shard or return an error. Either outcome can hide data-access bugs, so treat missing-key queries as a design problem, not just a routing problem.
Worked example: verify a routing decision
Before you route production traffic through a rewritten query, confirm where vtgate intends to send it. Vitess exposes a debug endpoint on vtgate that shows the routing decision and the rewritten SQL.
Run this from any machine that can reach the vtgate service:
curl "http://$VTGATE_HOST:15000/debug/route?query=SELECT+*+FROM+users+WHERE+id%3D12345"
- Where to run: your laptop, CI runner, or a debug pod inside the same cluster as vtgate.
- Permissions: network access to the vtgate debug port; no database superuser privileges are required.
- Placeholders: replace
$VTGATE_HOSTwith your vtgate hostname or service name, and adjust the query to match a real sharding key in your keyspace. Use the port configured for vtgate debugging in your environment. - Expected check: the response identifies the target shard and shows the statement after any rewrite. Compare the target shard against your sharding-key map to confirm correctness.
- Risk: the endpoint can reveal query internals. Do not expose it to the public internet; restrict it to internal networks or administrative clients.
You can also inspect vtgate logs on the node or pod where vtgate runs:
kubectl logs -n vitess deployment/vtgate | grep -i "route"
Look for log lines that name the target shard and the rewritten query. If the log shows a different shard than your sharding-key map predicts, the key extraction or vschema configuration is likely wrong.
Trade-offs and limitations
Automatic routing only supports simple statements that reference a single sharding key. Multi-shard joins, cross-shard subqueries, and queries without the sharding key require hints, defaults, or application changes. If the sharding key is ambiguous or missing, vtgate may default to a fallback shard or return an error, which can cause silent data-access failures.
Schema changes that alter the sharding key or keyspace definition require coordinated updates across shards. Test those changes in a staging cluster first; a misconfigured keyspace can lead to routing failures or, in worst cases, data being written to the wrong shard.
What to check before you deploy
- Identify the sharding key for each table in your vschema.
- Run representative SELECT, UPDATE, and DELETE statements through
/debug/routeand confirm the target shard. - Check vtgate logs for the same statements under load to verify the debug endpoint matches runtime behavior.
- For queries that omit the sharding key, decide whether to add a hint, set a default key, or refactor the query.
vtgate removes the need for manual routing code in many cases, but it cannot fix a schema that hides the sharding key. Verify the route, restrict the debug endpoint, and keep the sharding key in your WHERE clause.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.