DGraph @auth rule is doing full scan without index. #9836
Unanswered
arighosh2014
asked this question in
Q&A
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
@auth on a type forces func: type(X) root — indexed filters ignored, O(N) scan on every query
Dgraph version: 23.x (tested on local cluster)
Summary
When @auth is applied to a type, the GQL query translator always generates func: type(X) as the scan root, even when the query includes a filter on an indexed field. This makes every authenticated query O(N) over all nodes of that type, regardless of how selective the filter is.
Without @auth, the same filter correctly uses the index as the root — O(matching nodes).
Reproduction
Schema
Test data
20 Documents (10 owned by u:alice, 10 by u:bob)
80 Comments: 40 with category="bug", 40 with category="feature", split evenly between alice and bob
Query under test
category has an @search(by: [exact]) index. There are 40 matching comments out of 80 total. Alice owns 20 of those 40.
Benchmark results
DQL func: eq(Comment.category, "bug") — no auth
touched_uids: 40 | n returned: 40
Index used as root, O(results).
GQL queryComment(filter:{category:{eq:"bug"}}) + @auth, alice
touched_uids: 220 | n returned: 20
Full type scan over all 80 Comments, then auth intersection.
DQL func: eq(category,"bug") @filter(eq(acl,"u:alice"))
touched_uids: 60 | n returned: 20
40 from category index + 20 for the acl filter, O(results).
Generated DQL (captured via logDQLRequest: true)
GQL with @auth (alice)
Comment_1 always uses func: type(Comment) as root. The eq(category, "bug") index is never used as the scan root — it's a post-scan filter applied after the full type scan.
Direct DQL (O(results))
Expected vs actual behaviour
Expected: queryComment(filter:{category:{eq:"bug"}}) uses the category index as the scan root, reading only matching nodes — O(40), same as plain DQL.
Actual: The GQL translator hardcodes func: type(Comment) as root whenever @auth is on the type, scanning all 80 Comment nodes before applying the filter.
Impact
In production with hundreds of thousands of nodes, every GQL query on an @auth-protected type scans the entire type — regardless of how selective the filter is. A query that should touch 50 nodes touches 100,000+.
Question
Is this a known limitation of the GQL→DQL translator? Is there a way to hint the translator to use a specific field index as root while keeping @auth active?
Any guidance on the intended design or a planned fix would be appreciated.
All reactions