Skip to content
KeystoneJS LogoKeystoneJS (α)


Query Performance Monitoring with Apollo Engine

The GraphQL stack in keystone-alpha is powered by Apollo Server, which comes with performance monitoring built in via the Apollo Engine.

Apollo Engine provides a free service up to 25 million monthly requests, including:

  • Query logging
  • Error logging
  • Query performance monitoring
  • Query performance tracing
  • Schema version history

Apollo Engine Query Trace Example

Setting up Apollo Engine

Apollo Engine Account

Sign up for an Apollo Engine account.

Follow the prompts to create a new service. On the second step, you will see a screen such as:

Apollo Engine Setup Step 2

Ignore the npx apollo service:push command for now, we'll need to upload the schema a slightly different way to account for any Access Control you may have setup.


Create the .env file as suggested:


(👆 that's not a real key!)

Create a file apollo.config.js:

module.exports = {
  service: {
    localSchemaFile: './schema.graphql',

Push Schema To Apollo Engine

We will use the keystone.dumpSchema() command to create a schema we can upload to Apollo Engine.

Somewhere in your main Keystone application code you will be calling keystone.createList(), followed by a call to new WebServer(keystone, { ... }). We will now add some extra commands between these two calls:

keystone.createList('Foo', {
  /* ... */

// ---- Schema dumping ----
if (typeof process.env.DUMP_SCHEMA === 'string') {
  console.log(`Schema dumped to: ${path.resolve(process.env.DUMP_SCHEMA)}`);
// ---- End Schema dumping ----

const server = new WebServer(keystone, {
  /* ... */

Next, start the Keystone server but include a DUMP_SCHEMA environment variable. This will output the Keystone schema to the given path (ready for us to upload to Apollo Engine!):

DUMP_SCHEMA=./schema.graphql node index.js

Note ./schema.graphql is the same path we set in apollo.config.js

schema.graphql should look something like:

scalar Upload
scalar DateTime

input GroupRelateToOneInput {
  # ...

# ... And so on

Now we can push our generated schema to Apollo Engine with the command:

npx apollo service:push

(Note: For performance and security reasons, you may wish to add apollo to your devDependencies, and add the command above to your package.json without the npx prefix)

Wait for Apollo Engine to show the newly uploaded service:

Successfully pushed schema to Apollo Engine

Send stats to Apollo Engine

Ensure your application is reading .env environment variables on boot. We recommend the dotenv library for this:

node -r dotenv/config index.js

(Note: you do not need the DUMP_SCHEMA environment variable when starting the server - it is only used for exporting an updated schema and should not be set when trying to start the Keystone GraphQL API)

Apollo Server will read the ENGINE_API_KEY env var and start sending graphQL stats to Apollo Engine.

Within seconds of triggering graphQL requests, they will begin to show in Apollo Engine:

Apollo Engine > Metrics > Slow Query > Trace > Inspect

Tweaking stats sent to Apollo Engine

The WebServer config option can accept an apollo key for setting different options, one of which can be used to configure the Apollo Engine connection:

const server = new WebServer(keystone, {
  /* ... */
  apollo: {
    engine: {
      privateVariables: ['password'],

See the Apollo Server docs for more options.

Have you found a mistake, something that is missing, or could be improved on this page? Please edit the Markdown file on GitHub and submit a PR with your changes.

Edit Page