# Query Complexity

Information about query complexity and limits in the Font Awesome GraphQL API.

> Manage the complexity of queries to improve performance and prevent error responses.

## When is a Query Too Complex?

We have a lot of releases, thousand of icons in each, and most icons are available in several familyStyles.
So there's much more that _could_ be queried than is allowed in a _single_ query.

If your query is too complex, you'll get an error response that explains what is too complex about it.
You'll need to modify your query to select less. You can issue multiple queries that are less complex instead
of a single query that's too complex.

  <h4>
   What's the Maximum Complexity Value?
  </h4>

When we first added complexity calculations, we started with a value of `100,000`.

But as we add families and styles this value has been increased.

So we may _increase_ this value from time to time but we will not _decrease_
the value. Decreasing the value could lead to an unexpected query failure and
our goal is to never introduce a backward-incompatible change to this API
server.

For example, this query is too complex:

```graphql
query {
  release(version: "6.4.2") {
    icons {
      id
      unicode
      svgs(
        filter: {
          familyStyles: [
            { family: CLASSIC, style: SOLID }
            { family: CLASSIC, style: LIGHT }
            { family: CLASSIC, style: REGULAR }
          ]
        }
      ) {
        width
        height
        pathData
        html
      }
    }
  }
}
```

It selects all icons in Font Awesome 6.4.2. For each icon, it gets the `id` and `unicode` fields, plus `svgs` for three familySyles: Classic Solid, Classic Light, and Classic Regular. For each of those SVGs, it selects four fields.

Let's see how this is too complex.

The basic rule of thumb for calculating the complexity of the query is to count `1` for each field that is selected,
considering that some of these fields, like `icons` or `svgs` represent _multiples_.

Working from the bottom up:

There are three familyStyles being selected for `svgs`, so there's a `3` multiplier on that field. And there are `4` fields selected under `svgs`.
So that means that the `svgs` field is going to have complexity of `3 * 4 == 12` for _each icon_.

Each icon also has an `id` and `unicode`. So that's a complexity of `14` for each icon (`12` for `svgs`, plus the other `2`).

There are `3,690` icon IDs in Font Awesome 6.4.2; so that's the multiplier on the `icons` field for Font Awesome 6.4.2.

Other versions of Font Awesome will have different counts of icons.
See [Counting Icon IDs vs. Counting Icons](/apis/graphql/complexity.md#counting-icon-ids-vs-counting-icons) below for a query that shows how many icon IDs are in a release.

So the `icons` field in this query will have a complexity of `51,660`.

The `release` field just counts as `1`.

So the total complexity of the query is `51,661`.

Since the maximum complexity allowed for queries is `50,000`, the error you'll see with this query looks like this:

```json
{
  "errors": [
    {
      "locations": [
        {
          "column": 3,
          "line": 3
        }
      ],
      "message": "Field icons is too complex: complexity is 51,660 and maximum is 50,000"
    },
    {
      "locations": [
        {
          "column": 2,
          "line": 2
        }
      ],
      "message": "Field release is too complex: complexity is 51661 and maximum is 50,000"
    },
    {
      "locations": [
        {
          "column": 1,
          "line": 1
        }
      ],
      "message": "Operation is too complex: complexity is 51661 and maximum is 50,000"
    }
  ]
}
```

In this case, simply removing one of the familyStyles in the `filter` on the `svgs` field would make
it significantly less complex.

## Counting Icon IDs vs. Counting Icons

To select the `icons` field is to select all icon IDs in a particular release of Font Awesome.
Each item of `icons` has an `id` field that is a unique name within the icon set
for a given version of Font Awesome.

For example, there's an icon named `avocado` that, as of Font Awesome 6.4.2 is available
in 8 different familyStyles. So that counts as eight icons, but only one icon ID.

There are some properties about that icon ID that are the same regardless of family-style.
See the various fields on the [`Icon`](/apis/graphql/objects.md#icon) object.
It's `unicode`, or `label`, for example.

So the complexity multiplier that corresponds to the `icons` field is the count of icon IDs
in a release, not the total number of icons.

For example, in Font Awesome 6.4.2, there are:

- 3,690 icon IDs
- 24,208 icons

The following query gives you both counts for the release:

```graphql
query {
  release(version: "6.4.2") {
    iconCount {
      pro
    }
    iconIdCount {
      pro
    }
  }
}
```

There are 24,208 icons because most of the icon IDs are available in the same
8 familyStyles as avocado. So why isn't it just 3,690 icon IDs multiplied
by 8 familyStyles for total of 29,520? Why are there 24,208 icons instead of 29,520?
Because some of the icon IDs are only present in the Classic Brands family-style.

There are 473 icon IDs that are in the brands family-style, and most of those are
available _only_ in that family-style. But making the math even more complicated,
there are just a couple of those are both in Classic Brands _and_ the other 8 familyStyles.

So it just works out that there are 24,208 distinct icons in Font Awesome 6.4.2.

## Playing it Safe

If your query selects SVGs for all icons in some release, then a safe bet is to use
the `filter` on the `svgs` field to select just one family-style at a time. If your application
requires three different familyStyles, then issue three separate queries, each selecting
one of those familyStyles.

For example, the following query has a complexity of only `22,141`, and it gives you
everything you need to render all SVG icons in one family-style for Font Awesome 6.4.2:

```graphql
query {
  release(version: "6.4.2") {
    icons {
      id
      svgs(filter: { familyStyles: [{ family: SHARP, style: LIGHT }] }) {
        familyStyle {
          prefix
        }
        width
        height
        pathData
      }
    }
  }
}
```

You can get a decent estimate of the complexity using the `iconIdCount { pro }` value
in the query above as the multiplier for the `icons` field (3,690) and multiplying that by the
number of fields selected under `icons`, which is 6. That's 22,140. Add 1 for the top-level
`release` field, and you've got the total of 22,141.

If you change the filter to use any other single family-style, it'll have the same complexity.

So you could run that same query three times for three different family-styles,
if that's what your app needs, and be confident that the complexity will be well under the limit.

This same query would _still_ be under the limit, even if run for a later release of Font Awesome
where the `iconIdCount` _doubles_.

## Constant vs. Variable Complexity

Complexity calculations for any given version of Font Awesome are stable. Font Awesome 6.4.2
has 3,690 icon IDs and 9 familyStyles. That won't change. So a query whose complexity is
based on those multipliers won't change.

However, later releases will have more icon IDs and more familyStyles.

A query run against a smaller release may fit within the complexity allowance; but that
same query when run against a larger release may be too big.

However, it's also possible to use `version="7.x"`, and _that_ changes with each release.

As mentioned above, while Font Awesome 6.4.2 has 3,690 icon IDs, a future version will have more.

When you use `version="7.x"` in a query, you're asking for whatever version is the latest
major v7 at the moment the query is executed. While the example query above had a multiplier
of 3,690 on the `icons` field, if a later version of Font Awesome has 4,000 icon IDs, then that same
field in the same query would have a multiplier of 4,000.
