Some clients may send several queries to the server at once (for example, Apollo Client’s query batching). You can execute them concurrently with Schema#multiplex.

Multiplex runs have their own context, analyzers and instrumentation.

Concurrent Execution

To run queries concurrently, build an array of query options, using query: for the query string. For example:

# Prepare the context for each query:
context = {
  current_user: current_user,

# Prepare the query options:
queries = [
   query: "query Query1 { someField }",
   variables: {},
   operation_name: 'Query1',
   context: context,
   query: "query Query2 ($num: Int){ plusOne(num: $num) }",
   variables: { num: 3 },
   operation_name: 'Query2',
   context: context,

Then, pass them to Schema#multiplex:

results = MySchema.multiplex(queries)

results will contain the result for each query in queries.

Validation and Error Handling

Each query is validated and analyzed independently. The results array may include a mix of successful results and failed results

Multiplex-Level Context

You can add values to Execution::Multiplex#context by providing a context: hash:

MySchema.multiplex(queries, context: { current_user: current_user })

This will be available to instrumentation as multiplex.context[:current_user] (see below).

Multiplex-Level Analysis

You can analyze all queries in a multiplex by adding a multiplex analyzer. For example:

MySchema = GraphQL::Schema.define do
  # ...

The API is the same as query analyzers , with some considerations:

Multiplex analyzers may return AnalysisError to halt execution of the whole multiplex.

Multiplex Instrumentation

You can add hooks for each multiplex run with multiplex instrumentation.

An instrumenter must implement .before_multiplex(multiplex) and .after_multiplex(multiplex). Then, it can be mounted with instrument(:multiplex, MyMultiplexAnalyzer). See Execution::Multiplex for available methods.

For example:

# Count how many queries are in the multiplex run:
module MultiplexCounter
  def self.before_multiplex(multiplex)"Multiplex size: #{multiplex.queries.length}")

  def self.after_multiplex(multiplex)

# ...

MySchema = GraphQL::Schema.define do
  # ...
  instrument(:multiplex, MultiplexCounter)

Now, MultiplexCounter.before_multiplex will be called before each multiplex and .after_multiplex will run after each multiplex.