DEV Community

Cover image for How to setup Prometheus Metrics for NestJS GraphQL

Posted on

How to setup Prometheus Metrics for NestJS GraphQL


Start of this week (14. Nov 2022) I needed to setup Prometheus + Grafana for an API-Gateway in my company.

I was afraid that nearly nothing already exists out there 🙀 and I only had this (spoiler: broken) guide

The whole code examples on that blog article are not just copy&paste-able but also stale/broken.

So I needed to put some hard work into how to wire everything up and to safe hopefully some work for other devs like me, I created now a sample minimal reproducible repository and this article.

If this helped you at any time, feel free to sponsor me a cup of coffee ☕️ PayPal or via

I assume you already have a running GraphQL NestJS app, so I will skip these steps, otherwise please follow the instructions at

First we need to install some dependencies:

npm add @willsoto/nestjs-prometheus prom-client # The general Prometheus metrics provider which will expose the endpoint /metrics
npm add apollo-metrics apollo-tracing@0.15.0 # Provides Apollo GraphQL server plugins
npm add --save-dev apollo-server-plugin-base # Contains the ApolloServerPlugin interface
Enter fullscreen mode Exit fullscreen mode

Now we will add a module file src/metrics/prom.module.ts

import { Module } from "@nestjs/common";
import { PrometheusModule } from "@willsoto/nestjs-prometheus";
import createMetricsPlugin from "apollo-metrics";
import { plugin as apolloTracingPlugin } from "apollo-tracing";
import { register } from "prom-client";


  imports: [
    // Register the general Prometheus module
  providers: [
      provide: TRACING_PLUGIN_KEY,
      // Provide the apollo tracing plugin
      // This is only needed if you also want to measure timings
      useValue: apolloTracingPlugin(),
      provide: METRICS_PLUGIN_KEY,
      // Provide the apollo metrics plugin
      useValue: createMetricsPlugin(register),
export class PromModule {}
Enter fullscreen mode Exit fullscreen mode

The tracing plugin is only needed if you also want to measure timings of your field resolvers. At this time, there is NO Grafana Dashboard that will display this data. Maybe I will create one in the future, but for now at least just lets collect these additional data.
The tracing plugin will be used here apollo-metrics index L124

Now we need to register the PromModule in our AppModule

import { ApolloDriver, ApolloDriverConfig } from "@nestjs/apollo";
import { Module } from "@nestjs/common";
import { GraphQLModule } from "@nestjs/graphql";
import { ApolloServerPlugin } from "apollo-server-plugin-base";
import { join } from "path";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { CatsModule } from "./cats/cats.module";
import {
} from "./metrics/prom.module";

  imports: [
    // Import the PromModule generally (e.g. also for other metrics like non GraphQL stuff)
      driver: ApolloDriver,
      // Import the PromModule for GraphQL
      imports: [PromModule],
      useFactory: (
        // Use provided plugins injected from below
        tracingPlugin: ApolloServerPlugin,
        metricsPlugin: ApolloServerPlugin
      ) => ({
        debug: true,
        introspection: true,
        playground: true,
        // Plugins added to apollo server
        plugins: [tracingPlugin, metricsPlugin],
        autoSchemaFile: join(process.cwd(), "src/schema.gql"),
      // We need to inject the provider keys
  controllers: [AppController],
  providers: [AppService],
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

Warning: It is important to provide the plugins via that way, as otherwise if not registered to the NestJS context e.g. E2E tests will fail because the prom-client can only register a metric name once and will fail if a plugin tries to recreate a metric.

Now we are ready and just need to connect our metrics endpoint to Prometheus and then add Prometheus as Datasource for Grafana. (Please watch some other tutorials for that)

Now import the Grafana Dashboard:

⚠️ But attention! ⚠️ You need to reconfigure the parameter operation_name to operationName (snake_case to camelCase)

renamed operationName

The blog article was manually using its own metric names 🤷

Please let me know if this was helpful and leave some comments.


I started to edit the dashboard provided by Adin Hodovic and extended it with tracing/timing panels.

Grafana Dashboard (json export):

I tried to publish it at dashboards, but somehow the upload does not work 🤷

Top comments (2)

victor_io profile image
Victor Ihuoma

Great article! I’m trying to do same for a nestjs app using fastify under the hood, no graphql, how do I modify this to fit that purpose

lintong profile image
Linton Galloway

Top work, this worked for me first time!