DocumentationGatewayOther FeaturesPerformance/CacheOverview

Performance & Caching

Hive Gateway provides a set of features to help you optimize the performance of your GraphQL gateway. Hive Gateway provides a shared caching storage that can be used across plugins, transforms, subgraph execution and remote schema caching.

💡

If you are running Hive Gateway serverless on the edge, you’re highly advised to provide a cache. Aside from all of the aforementioned benefits, the biggest one is caching the remote schema so that it does not get pulled on each request.

Providing Cache Storage

In order to enable features that need a storage to keep the data, you need to define a cache storage implementation, and pass it to the gateway.

You can choose the best-fit cache storage for your use case.

LocalForage

LocalForage is a library that improves the existing storage mechanism in the browser by using IndexedDB, WebSQL and localStorage, see more.

Even if it is known as a browser storage, Hive Gateway provides you as a platform-agnostic cache storage to leverage the well-known storage APIs that are available in most JavaScript environments.

gateway.config.ts
import { defineConfig } from '@graphql-hive/gateway'
 
export const gatewayConfig = defineConfig({
  cache: {
    type: 'localforage',
    // All of the following options are listed with default values, you don't need to provide them
    driver: ['WEBSQL', 'INDEXEDDB', 'LOCALSTORAGE'] // The order of the drivers to use
    name: 'HiveGateway', // The name of the database
    version: 1.0, // The version of the database
    size: 4980736, // The size of the database
    storeName: 'keyvaluepairs', // The name of the store
    description: 'Cache storage for Hive Gateway', // The description of the database
  }
  responseCaching: {
    session: () => null,
  }
})

Redis

Redis is an in-memory data structure store, used as a database, cache, and message broker. You can use Redis as a cache storage for your Hive Gateway.

💡
The Redis cache currently only works in Node.js environments.
gateway.config.ts
import { defineConfig } from '@graphql-hive/gateway'
 
export const gatewayConfig = defineConfig({
  cache: {
    type: 'redis',
    host: 'localhost', // The host of the Redis server
    port: 6379, // The port of the Redis server
    password: undefined, // The password of the Redis server
    lazyConnect: true, // If true, the connection will be established when the first operation is executed
    // or
    url: 'redis://localhost:6379' // The URL of the Redis server
  },
  responseCaching: {
    session: () => null
  }
})

Cloudflare Workers KV

Cloudflare Workers KV is a distributed, eventually consistent key-value store available in the Cloudflare Workers runtime. You can use Cloudflare Workers KV as a cache storage for your Hive Gateway. Learn more about KV here.

💡

This is only available for Cloudflare Workers runtime. If you want to learn how to deploy your Hive Gateway to Cloudflare Workers, you can check the deployment documentation.

worker.ts
import { createGatewayRuntime } from '@graphql-hive/gateway-runtime'
import CloudflareKVCacheStorage from '@graphql-mesh/cache-cfw-kv'
import supergraph from './my-remote-supergraph-config'
 
export default {
  fetch(request, env, ctx) {
    const gateway = createGatewayRuntime({
      supergraph,
      transports: { http },
      responseCaching: {
        session: () => null
      },
      cache: new CloudflareKVCacheStorage({
        logger,
        namespace: env.NAMESPACE
      })
    })
    ctx.waitUntil(gateway[Symbol.asyncDispose]())
    return gateway(request, env, ctx)
  }
}

Custom Cache Storage

You can also implement your own cache storage by extending the CacheStorage class. It needs to match KeyValueCache interface from @graphql-hive/gateway.

my-cache-storage.ts
import { LRUCache } from 'lru-cache'
import { KeyValueCache } from '@graphql-hive/gateway'
 
export class MyKeyValueCache<V = any> implements KeyValueCache<V> {
  // Your cache implementation here
  private cache = new LRUCache<string, V>()
 
  // Get the value of the key
  async get(key: string) {
    return this.cache.get(key)
  }
 
  // Set the key with the value and optional options
  async set(key: string, value: V, options?: { ttl?: number }) {
    this.cache.set(key, value, options?.ttl)
  }
 
  // Delete the key from the cache
  async delete(key: string) {
    this.cache.del(key)
  }
 
  // Get all keys that match the given prefix
  async getKeysByPrefix(prefix: string) {
    return Array.from(this.cache.keys()).filter(key => key.startsWith(prefix))
  }
 
  // This should be implemented if you want to clear the cache on shutdown
  [Symbol.asyncDispose]() {
    this.cache.reset()
  }
}