Timeout

You can apply a timeout to query execution with the GraphQL::Schema::Timeout plugin. For example:

class MySchema < GraphQL::Schema
  use GraphQL::Schema::Timeout, max_seconds: 2
end

After max_seconds, no new fields will be resolved. Instead, errors will be added to the errors key for fields that weren’t resolved.

Note that this does not interrupt field execution (doing so is buggy). If you’re making external calls (eg, HTTP requests or database queries), make sure to use a library-specific timeout for that operation (eg, Redis timeout, Net::HTTP’s ssl_timeout, open_timeout, and read_timeout).

Custom Error Handling

To log the error, provide a subclass of GraphQL::Schema::Timeout with an overridden handle_timeout method:

class MyTimeout < GraphQL::Schema::Timeout
  def handle_timeout(error, query)
    Rails.logger.warn("GraphQL Timeout: #{error.message}: #{query.query_string}")
  end
end

class MySchema < GraphQL::Schema
  use MyTimeout, max_seconds: 2
end

Customizing the Timeout Window

To dynamically pick a timeout duration (or bypass it), override GraphQL::Schema::Timeout#max_seconds in your subclass. To bypass the timeout altogether, max_seconds can return false.

For example:

class MyTimeout < GraphQL::Schema::Timeout
  # Allow 10s for an incoming mutation, but don't apply any timeout for an admin user.
  def max_seconds(query)
    if query.context[:current_user]&.admin?
      false
    elsif query.mutation?
      10
    else
      super
    end
  end
end

# ...

class MySchema < GraphQL::Schema
  use MyTimeout, max_seconds: 5
end