GraphQL API Query Limitations

AVAILABLE API VERSION
API v56.0 and later
Event and task beta available in API v59.0–65.0
Event and task generally available in API v66.0 and later

GraphQL has the same limitations as SOQL. When working with GraphQL API queries, consider the following limitations.

  • Each GraphQL query can contain up to 10 subqueries.
  • Each subquery counts as one request for rate limiting.
  • Each subquery can return up to 2000 records within the same GraphQL query.
  • By default, the first 10 records are returned. You can use pagination information to retrieve additional records.
  • You can query only objects that User Interface API supports.

Some fields are not filterable using the where filter. To find out if a field is supported for filtering, see the Object Reference for the Salesforce Platform. For example, the NewValue and OldValue fields on the CaseHistory object don’t include “Filter” in the Properties section and aren’t supported for filtering. If you attempt to pass in an unsupported field to the where filter, you get a “Field ‘FieldName’ in type ‘ObjectName’ is undefined” error.

Note

Relationship Queries 

An object must have a parent or child relationship with another object to form a query similar to an SOQL join. Limitations for relationship queries are discussed in the next few sections.

Child-to-Parent Relationships 

Child-to-parent relationships follow these limits.

  • A query can specify up to 55 child-to-parent relationships. A custom object allows up to 40 relationships, so you can reference all the child-to-parent relationships for a custom object in one query.
  • You can specify up to five levels in a child-to-parent relationship.
  • A child relationship name can’t be the same as a parent relationship name within an object.

This example shows three levels of child-to-parent relationship, which is Contact.Account.Owner.FirstName.

Query contacts with child-to-parent relationship to accounts
1query  {
2  uiapi {
3    query {
4      Contact {
5        edges {
6          node {
7            Id
8            Name { value }
9            Account { # first level of child-to-parent relationship
10              Owner { # second level
11                FirstName { value } # third level
12              }
13            }
14          }
15        }
16      }
17    }
18  }
19}

Additionally, consider these differences between API versions.

  • In API version 57.0 and earlier, you can specify up to two levels of child-to-parent relationship in a query.
  • In API version 58.0 and later, you can specify up to five levels of child-to-parent relationship for standard and custom objects.

Parent-to-Child Relationships 

Parent-to-child relationships follow these limits.

  • A query can specify up to 20 parent-to-child relationships.
  • You can specify one level in a parent-to-child relationship.
  • A parent relationship name can’t be the same as a child relationship name within an object.

This example shows a parent-to-child relationship, which is Account.Contacts.

Query accounts with parent-to-child relationship to contacts
1query  {
2  uiapi {
3    query {
4      Account {
5        edges {
6          node {
7            Id
8            Name { value }
9            Contacts { # parent-to-child relationship
10              edges {
11                node {
12                  Owner { # child-to-parent relationship
13                    CreatedBy { # child-to-parent relationship
14                      Name {
15                        value
16                      }
17                    }
18                  }
19                }
20              }
21            }
22          }
23        }
24      }
25    }
26  }
27}

If you’re querying Account, the fields you select can specify only the Contact or other objects at that level. The query can’t specify a child object of Contact.

Semi-Join and Anti-Join Queries 

GraphQL API follows SOQL restrictions on semi-join and anti-join queries.

  • You can use up to two nin and ninq operators in a where argument. A nin and ninq operator can support up to two in or nin operators.
  • You can’t use the ne operator with semi-joins and anti-joins. Using this operator converts a semi-join to an anti-join and vice versa. Instead, write the query in the appropriate semi-join or anti-join form.

Main Query Limits 

Consider these restrictions on the where argument of a semi-join or anti-join query.

  • You must use a single ID for the semi-join or anti-join query.
  • The ID in the where argument that’s used in the semi-join or anti-join can’t use relationships.

This example uses a single ID in a semi-join to return contact names associated with accounts whose ownership is public.

Query contacts with a semi-join on accounts
1query {
2  uiapi {
3    query {
4      Contact (where: {
5        AccountId: { inq: {
6          Account: { Ownership: { eq: "Public" } },
7          ApiName:"Id" },
8         }
9        }) {
10            edges {
11              node {
12                Id
13                Name {
14                  value
15                }
16              }
17            }
18        }
19     }
20  }
21}

The previous query is similar to this SOQL statement.

SOQL statement with semi-join on contacts and accounts
1SELECT Id, Name
2FROM Contact
3WHERE AccountId
4IN (
5    SELECT Id FROM Account
6    WHERE Ownership = 'Public'
7)

Subquery Limits 

A subquery must query a field referencing the same object type as the main query. For example, use the Id field on the where argument followed by ApiName:"AccountId"in the inq operator. Using Account.Id (dot notation) instead of AccountId isn’t supported.

This example returns specific accounts using AccountId as the selected field in the subquery, in which the contacts’ last names start with “B”.

Query accounts with a semi-join on contacts
1query {
2  uiapi {
3    query {
4      Account (where: {
5        Id: { inq: {
6          Contact: { LastName: { like: "B%" } },
7          ApiName:"AccountId" },
8         }
9        }) {
10            edges {
11              node {
12                Id
13                Name {
14                  value
15                }
16              }
17            }
18        }
19     }
20  }
21}

The previous query is similar to this SOQL statement.

SOQL statement with semi-join on accounts and contacts
1SELECT Id, Name
2FROM Account
3WHERE Id IN
4  (
5    SELECT AccountId
6    FROM Contact
7    WHERE LastName LIKE 'B%'
8  )

There’s no limit on the number of records matched in a subquery. By default, the first 10 records are returned. You can use the pagination information to retrieve additional records.

Query accounts with a semi-join on contacts and return the first 50
1query {
2  uiapi {
3    query {
4      Account (first:50, where: {
5        Id: { inq: {
6          Contact: { LastName: { like: "B%" } },
7          ApiName:"AccountId" },
8         }
9        }) {
10            edges {
11              node {
12                Id
13                Name {
14                  value
15                }
16              }
17            }
18        }
19     }
20  }
21}

The selected field in a subquery must be a reference to a different object, and can’t traverse relationships. In the previous example, the main query selects from accounts and the subquery selects from contacts.

You can’t query on the same object in a subquery as in the main query. Instead of selecting from the same object in the main query and subquery, you can rewrite a semi-join query using the Parent field.

Query parent accounts
1query {
2  uiapi {
3    query {
4      Account ( where: {
5        Parent: { Name: { like: "United%" } }
6        }) {
7            edges {
8              node {
9                Id
10                Name {
11                  value
12                }
13              }
14            }
15        }
16     }
17  }
18}

The previous query is similar to this SOQL statement.

SOQL statement with parent accounts
1SELECT Id, Name
2FROM Account
3WHERE Parent.Name LIKE 'United%'

A semi-join or anti-join statement:

  • Can’t be nested in another semi-join or anti-join statement
  • Can’t be used in a subquery where argument.

A subquery can’t be used with:

  • The or operator
  • The orderBy operator

Multiple Semi-Joins and Anti-Joins 

You can combine semi-join or anti-join clauses in a query using the inq or ninq functions in a where argument. However, you can use only up to two subqueries in a single semi-join or anti-join queries.

This example includes 2 semi-join filters that return accounts if they have an associated opportunity and an associated case that has its Priority field set to “High”.

Query accounts with 2 semi-join filters
1query {
2  uiapi {
3    query {
4      Account (where: { and: [{
5        Id: { inq: {
6          Opportunity: {},
7          ApiName:"AccountId" },
8         },
9         Id: { inq: {
10           Case : { Priority : { eq : "High" } },
11           ApiName:"AccountId" }
12         }
13       }] }) {
14            edges {
15              node {
16                Id
17                Name {
18                  value
19                }
20              }
21            }
22        }
23     }
24  }
25}

The previous query is similar to this SOQL statement.

SOQL statement with 2 semi-join filters
1SELECT Id, Name
2FROM Account
3WHERE Id IN
4(
5    SELECT AccountId
6    FROM Opportunity
7)
8AND Id IN
9(
10    SELECT AccountId
11    FROM Case
12    WHERE Priority = 'High'
13)

Object-Specific Limitations 

Only the UI API supported objects are available in GraphQL API. Certain supported objects come with additional limitations.

Note Object Limitations 

The Note object has these limitations.

  • You can’t query the Note object in subqueries.
  • You can query the Note object but you can’t evaluate the body of a note, such as filtering on Note.Body by using the eq or like operator. You also can’t filter against the content of textarea fields, blobs, or S-control components in any object.

You can return the content of the body of the note like this.

Query notes on accounts
1query {
2  uiapi {
3    query {
4      Account ( where: { Name: { like: "Edge%" }
5         }) {
6            edges {
7              node {
8                Notes {
9                  edges {
10                    node {
11                      Body {value}
12                    }
13                  }
14                }
15                Id
16                Name {
17                  value
18                }
19              }
20            }
21        }
22     }
23  }
24}

The previous query is similar to this SOQL statement.

SOQL statement with Note.Body on Account.Notes
1SELECT Name, (SELECT Note.Body FROM Account.Notes) FROM Account
2WHERE Name LIKE 'Edge%'

You can also return all account names and the owner ID for any notes associated with the account.

Query Note.Body on accounts
1query {
2  uiapi {
3    query {
4      Account ( where: { Name: { like: "Edge%" }
5         }) {
6            edges {
7              node {
8                Notes {
9                  edges {
10                    node {
11                       OwnerId { value }
12                    }
13                  }
14                }
15                Id
16                Name { value }
17              }
18           }
19        }
20     }
21  }
22}

The previous query is similar to this SOQL statement.

SOQL statement with Note.OwnerId
1SELECT Account.Name, (SELECT Note.OwnerId FROM Account.Notes) FROM Account

External Objects Limitations 

External objects have these limitations.

  • A subquery that involves external objects can fetch up to 1,000 rows of data.
  • Each query can have up to 4 joins across external objects and other types of objects. Each join requires a separate round trip to the external system when executing the query. Expect longer response times for each join in a query.
  • External objects don’t support the orderBy argument in relationship queries. This limit applies only when the external data is accessed via the OData 2.0 adapter for Salesforce Connect.

See Also 

SOQL Limits on Objects

Understanding Relationship Query Limitations