5.2.6 Sky Query Mode
recommendedSome repository-wide questions are awkward for ordinary bazel query: reverse
dependency searches need an explicit universe expression, and finding every
BUILD file that loads a changed .bzl file requires edges outside the ordinary
target graph. Sky Query is a mode of bazel query that evaluates against a
declared universe by inspecting Bazel's existing Skyframe graph. It adds
allrdeps() and rbuildfiles() and can, in some circumstances, use less memory
or run faster than the default query implementation.1
That is a conditional advantage, not a repository-size threshold. There is no documented target count at which Sky Query becomes necessary, and it is not a general cure for an expensive expression. Choose it when its universe-scoped operators answer the question directly, or benchmark it when ordinary query's separate graph is the suspected cost.
allrdeps() uses target labels
rbuildfiles() takes path fragments
Activate the mode with both required flags
Sky Query requires two choices: a universe and unordered output. Supply either
--universe_scope or --infer_universe_scope, and set
--order_output=no:1
bazel query \
--universe_scope=//... \
--order_output=no \
'allrdeps(//lib:core)'
--universe_scope accepts a comma-separated list of additive and subtractive
target patterns. Bazel preloads the transitive closure of those roots, then
evaluates the expression inside that scope. The universe is therefore a graph
closure, not merely a package-name filter.1 This is the same distinction that
matters for rdeps() in 5.2.1 bazel query — Static Graph Analysis, but the universe moves from the
function's first argument to the command line.
The basic-query snippet makes that visible. With
--universe_scope=//..., allrdeps(//lib:core) returns the library and the
targets in the snippet that transitively depend on it. Narrowing the universe
to one application root deliberately excludes consumers outside that root's
dependency closure.
In a fresh Bazel 9.0.0 process, the snippet's explicit command produced this result (Sky Query output order is not significant):
//lib:core
//service:menu
//config:app_config
//app/data:repo
//app:runner
Predict: What does this command find?
bazel query --infer_universe_scope --order_output=no \
'allrdeps(//lib:core)'
Reveal
Usually only //lib:core. Inference extracts the unique target patterns from
the expression, so the inferred universe is the dependency closure of
//lib:core itself. Reverse consumers are not in that universe by construction.
In a fresh process, the snippet command produced:
//lib:core
--infer_universe_scope is safe only when the target patterns already embedded
in the whole expression describe the intended consumer roots. For reverse
impact analysis, spell out the universe unless you have inspected what
inference will select.1
One local Bazel 9.0.0 observation adds a practical testing caveat: after the
same long-lived server evaluated the broad explicit-universe command above, the
inferred command also emitted reverse consumers that the broad query had
loaded. A fresh bazel --batch query --infer_universe_scope --order_output=no 'allrdeps(//lib:core)' process returned only //lib:core. This is evidence
from that version and snippet, not a general guarantee about other releases.
Use a fresh process or server when correctness-sensitive comparisons need to
isolate universe inference from warm Skyframe state.
Use allrdeps() when the universe is already a command-level decision
allrdeps(x) computes the transitive reverse dependencies of x in the
command's universe. It also accepts an optional maximum depth:
# The changed target plus direct consumers in the selected product areas
bazel query \
--universe_scope=//app/...,//service/... \
--order_output=no \
'allrdeps(//lib:core, 1)'
Given --universe_scope=//foo/..., allrdeps(//bar) is equivalent in set
semantics to rdeps(//foo/..., //bar).1 The benefit is not that it performs
an unconstrained global search. It makes one deliberately selected universe
available to universe-scoped operators without repeating it inside each call.
Start with the smallest universe that contains every consumer relevant to the decision. A narrow universe is faster to load but can produce a confidently incomplete answer. A repository-wide universe is broader evidence but may cost substantially more. Add a depth bound when direct or near-direct consumers are all the investigation needs. 2.1.6 Reverse Dependencies & Change Impact introduces the change-impact interpretation of reverse edges. Sky Query changes how the universe is supplied, not what a reverse dependency means.
Use rbuildfiles() for reverse load dependencies
rbuildfiles() answers a different question: which BUILD files transitively
depend on these BUILD or .bzl path fragments?
bazel query \
--universe_scope=//... \
--order_output=no \
'rbuildfiles(tools/lint/rules.bzl)'
If packages load tools/lint/rules.bzl, the result contains their BUILD-file
targets. Transitive load chains are followed, so a BUILD file that loads an
intermediate .bzl file can also be returned. Arguments are workspace-relative
path fragments, not labels. Ordinary source files such as foo.cc are ignored.
the operator is about package-definition and Starlark load dependencies.1
This is useful when changing a shared macro or rule definition and deciding
which packages need further inspection. It is not by itself a configured impact
analysis: it finds loading relationships, while 5.2.2 bazel cquery — Configured Graph resolves
configured target edges and 5.2.3 bazel aquery — Action Graph inspects generated actions. A CI
pipeline may use rbuildfiles() as one input to target determination. See
6.5.1 Affected-Target Service Contract for the complete pipeline and its correctness policy.
Treat unordered output as part of the contract
Sky Query cannot preserve graph-ordered presentation. --order_output=no may
print compatible formats in arbitrary order, and --output=graph,
--output=minrank, and --output=maxrank are forbidden in this mode.1
For a person, sort labels after the query when alphabetical presentation helps:
bazel query --universe_scope=//... --order_output=no \
'allrdeps(//lib:core)' | sort
For automation, treat results as a set. Do not infer dependency order from line
position, and do not make a diff depend on the raw emission order. If the next
step needs graph rendering or ranked output, use ordinary query with an
appropriate rdeps() universe instead.
Choose Sky Query from evidence, not assumptions
Sky Query introspects Skyframe instead of constructing the separate graph used by default query. Official documentation promises only that this is faster and uses less memory in some circumstances.1 It does not promise lazy or parallel evaluation, immunity from out-of-memory failures, or a fixed scale at which it wins.
A defensible operating sequence is:
- State the required consumer roots or package-definition scope.
- Use ordinary
rdeps()when its explicit universe is clear and sufficient. - Use Sky Query for
allrdeps()orrbuildfiles(), or benchmark it against the default implementation for the actual expression and repository state. - Narrow universe roots and add a depth bound when that still answers the question. Do not narrow merely to make a command finish if it invalidates the answer.
- Record the universe alongside saved results. Without it, another reader cannot tell what the query was capable of finding.
Sky Query is an unordered, universe-scoped mode of bazel query. Activate it
with --order_output=no plus either an explicit or inferred universe. Prefer an
explicit universe for reverse-impact questions, because inference can exclude
the very consumers you want to find. Use allrdeps() for reverse dependencies
within that universe and rbuildfiles() for reverse BUILD/.bzl load
relationships. Treat performance as a measured, workload-specific benefit—not
as a guaranteed consequence of repository size.
Check your understanding · 4 questions
1.Which flag combination activates Sky Query mode?
Select one answer
2.Why can inferred universe scope make allrdeps(//lib:core) miss consumers of //lib:core?
Select one answer
3.Match each Sky Query operator to the relationship it follows:
Drag each answer onto the matching prompt, or click an answer and then click a prompt
4.How should callers handle Sky Query results?
Choose True or False for each sentence