Async Source Execution

AsyncDataloader will run GraphQL::Dataloader::Source#fetch calls in parallel, so that external service calls (like database queries or network calls) don’t have to wait in a queue.

To use AsyncDataloader, hook it up in your schema instead of GraphQL::Dataloader:

- use GraphQL::Dataloader + use GraphQL::Dataloader::AsyncDataloader 

Also, add the async gem to your project, for example:

bundle add async 

Now, GraphQL::Dataloader::AsyncDataloader will create Async::Task instances instead of plain Fibers and the async gem will manage parallelism.

For a demonstration of this behavior, see: https://github.com/rmosolgo/rails-graphql-async-demo

You can also implement manual parallelism using dataloader.yield.

Rails

For Rails, you’ll need Rails 7.1, which properly supports fiber-based concurrency, and you’ll also want to configure Rails to use Fibers for isolation:

class Application < Rails::Application # ... config.active_support.isolation_level = :fiber end 

ActiveRecord Connections

You can use Dataloader’s Fiber lifecycle hooks to improve ActiveRecord connection handling:

Altogether, it can be improved like this:

def get_fiber_variables vars = super # Collect the current connection config to pass on: vars[:connected_to] = { role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard, prevent_writes: ActiveRecord::Base.current_preventing_writes } vars end def set_fiber_variables(vars) connection_config = vars.delete(:connected_to) # Reset connection config from the parent fiber: ActiveRecord::Base.connecting_to(**connection_config) super(vars) end def cleanup_fiber super # Release the current connection ActiveRecord::Base.connection_pool.release_connection end 

Modify the example according to your database configuration and abstract class hierarchy.

Other Options

You can also manually implement parallelism with Dataloader. See the Dataloader Parallelism guide for details.