Measure urql Performance & Reliability

Prerequisites

The mapExchange API

The mapExchange API provided by urql enables developers to react or replace operations with onOperation and onResult. We can use this API to create measurements for all GraphQL operations in our application.

First, we need to customize the urql client to use our custom mapExchange.

ESM
const client = createClient({
  url: GRAPHQL_URL,
  exchanges: [
    // customize the mapExchange
    mapExchange({
      onOperation,
      onResult,
    }),
  ],
});

The onOperation callback

With our custom exchanges configured above, we can now create a onOperation callback.

ESM
const onOperation = useCallback((operation) => {
  return makeOperation(operation.kind, operation, {
    ...operation.context,
    created: performance.now(),
  });
}, []);

In the code above we are creating a new operation using the makeOperation function, and appending a created timestamp to the operation context.

The onResult callback

The onResult callback is called when a GraphQL operation is completed. We can use this to create a measurement for the operation.

ESM
const onResult = useCallback((result) => {
  measurement(
    'request',
    result.error ? MeasurementResult.FAILURE : MeasurementResult.SUCCESS,
    performance.now() - result.operation.context.created
  );
}, []);

A few things to note in the code above:

  • First, the onResult callback function is invoked with the result object from the GraphQL operation.
  • Second, we are using the measurement function to create a measurement. We specify the event name as a request, and the result as either MeasurementResult.SUCCESS or MeasurementResult.FAILURE.
  • Third, we are using the created timestamp from the operation context to calculate the duration of the operation.

Create an indicator

Now that we have configured our urql client to create measurements for all GraphQL operations, we can create a new indicator in Polaris.

  1. First, create a new Indicator in Polaris.
  2. Specify a name for the indicator.
  3. Specify the indicator window. In this example, I'll use a 5-minute window.
  4. Specify the indicator operation. In this example, as I want to create an indicator for request durations, I'll choose the Average operation.
  5. Finally, we set the predicate function as follows.
Indicator predicate function
function (measurement) {
  return measurement.eventName === 'request';
}

The predicate function above will filter all measurements with the eventName of request.