Skip to content

Conversation

freshjsw
Copy link
Contributor

@freshjsw freshjsw commented Feb 8, 2025

The cost complexity cost-limit plugin does not take into account how many entities are being returned when either the first or last argument are specified at the field level. This PR supports calculating complexity based on the number of records requested in the query.

This commit fixes #761

These two examples which have the same complexity cost (I have omitted edges and pageInfo to keep these examples simple)

query simpleQuery {
      books {
        title
        author
      }
}

query connectionQuery {
      books(first: 1) {
        title
        author
      }
}

The cost complexity of the query below should increase by a factor of the number of books requested

query connectionQuery {
      books(first: 3) {
        title
        author
      }
}

Note the PR does not currently handle VariableDefinitions but will handle the example above

Copy link

changeset-bot bot commented Feb 8, 2025

⚠️ No Changeset found

Latest commit: 8c0bd56

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

return arg.value.kind === 'IntValue' ? parseInt(arg.value.value, 10) : 1;
}
return mult;
}, 1) : 1;
Copy link
Member

@LMaxence LMaxence Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution :)

This function is already fairly complex, and it would be preferred that we avoid using a reduce in favor of more readable items:

let multiplier = 1

if ('arguments' in node && node.arguments) {
   if (arg.name.value === 'first' || arg.name.value === 'last') {
     multiplier = arg.value.kind === 'IntValue' ? parseInt(arg.value.value, 10) : multiplier
   }
}

Also, we should check that parseInt does not return NaN

Copy link

@marceloverdijk marceloverdijk Apr 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be nice if this could be configurable, like supporting a limit argument as well.

Copy link

@quinkinser quinkinser Jul 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The cost-multiplier logic based on first/last arguments is a solid feature, but it’s hidden as an implementation detail. It also frames this as a Relay specific addition, which probably isn't the main goal (I use relay spec, so I'm not complaining about that!).

To improve clarity and flexibility as mentioned by @marceloverdijk, could we expose it as a config option? Naming ideas below:

costMultiplyingArgs: string[] | false; // or empty array if don't want to deal with false

// or
costMultiplyingPaginationArgs: string[] | false;

// the default could be ['first', 'last'] if needed for backwards compat

This would:

  • Make the behavior visible in the public API (even if users don't deviate from default, at least it's clear there is a cost multiplier for pagination args)
  • Let users extend it to support limit, take, etc.
  • Let users disable it entirely (setting to false or empty array)

Right now, users might miss that this logic is in effect, or be unable to adapt it to different pagination conventions.

Copy link
Member

@LMaxence LMaxence left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello !

Thanks a lot for your contribution. I added some comments above to improve the PR before we can merge it :)

@Urigo
Copy link

Urigo commented Sep 17, 2025

I think this PR could be closed as it was merged and released here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support Connections in cost complexity calculation
5 participants