Homepage

NestedGraphQLQuery

Last edit: Apr 01, 2026

NestedGraphQLQuery

Severity: warning | Type: LiquidHtml

This check detects {% graphql %} tags placed inside loop tags ({% for %}, {% tablerow %}), which causes one database request per loop iteration — the classic N+1 pattern. It also follows {% function %} and {% render %} calls transitively to detect indirect GraphQL queries.

The N+1 problem often arises when dealing with related records. To address it, fetch all required data in a single query before the loop and pass it as a variable.

Exceptions: GraphQL inside {% background %} or {% cache %} blocks within a loop is not flagged, as those contexts have different performance characteristics.

Examples

✗ Incorrect Code Example (Avoid using this):

Direct GraphQL in a loop:


{% assign arr = 'a,b,c' | split: ',' %}
{% for el in arr %}
  {% graphql g = 'my/graphql', el: el %}
  {{ g.records.results[0].id }}
{% endfor %}

Transitive GraphQL via function call in a loop:


{% for item in items %}
  {% function result = 'lib/fetch_item_data', id: item.id %}
{% endfor %}

Where lib/fetch_item_data internally calls {% graphql %}.

✓ Correct Code Example (Use this instead):


{% assign arr = 'a,b,c' | split: ',' %}
{% graphql g = 'my/graphql', arr: arr %}
{% for el in arr %}
  {% comment %}Use data from g here{% endcomment %}
{% endfor %}

For related records, use the related_records approach to fetch all data in a single query.

Configuration

The default configuration for this check:

NestedGraphQLQuery:
  enabled: true
  severity: warning

Disabling This Check

Ideally, there should be no need to disable this check. platformOS provides alternative solutions for all scenarios that would otherwise require a GraphQL query inside a loop.

Resources

Questions?

We are always happy to help with any questions you may have.

contact us