user {friends {friends {friends {friends{id}} } } }
case (which is the canonical example in FB's schema of a crazy query), we would note that there's a 5000 friend limit, and so that query would potentially query 5000^4 = 6.25e14 nodes, and based on that we would (hopefully) reject it.For example, a query like "user {moviesWatchedByUser {usersWhoWatchedMovie {moviesWatchedByUser {usersWhoWatchedMovie ..." is allowed by GraphQL and will generate output with size exponential in the input size.
You can also do "{a1: expensiveOperation, a2: expensiveOperation, a3: expensiveOperation, ..." and trigger expensiveOperation an arbitrary number of times (for each item in the list you apply that to).
By using a sequence of fragments that include the next fragment more than once, it looks like you can trigger expensiveOperation an exponential number of times.
It's not clear if there is a way to prevent all this without severely impacting usabilty (by warping the schema design and adding GraphQL limits to handle this) or reliability (by enforcing hardcoded low resource usage limits).
Otherwise, it should be possible to apply throttling to (for example) expensiveOperation in the same way that you would a RESTful API at the moment.
In other words, what stops anyone from easily disabling a website by making a few parallel extremely complex GraphQL requests that consume all CPU and I/O, and perhaps result in holding some locks for a very long time?
In normal APIs you can make sure most endpoints are cheap to run, and throttle, secure or otherwise control the ones that must be expensive, but that doesn't work if you expose a flexible layer like GraphQL (or SQL).