• Stars
    star
    263
  • Rank 155,624 (Top 4 %)
  • Language TSQL
  • License
    Apache License 2.0
  • Created over 6 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A super simple tool to benchmark GraphQL queries

GraphQL Bench

Introduction

GraphQL Bench is a versatile tool for benchmarking and load-testing GraphQL Services. It can be run as a CLI application (local or Docker), and also provides a programmatic API. Both HTTP (Queries/Mutations) and Websocket (Subscriptions) tests are supported.

HTTP tests can be configured to run with your choice of:

  • Autocannon
  • K6
  • wrk2

Each benchmark tool will produce live output you can monitor while running your tests:

Autocannon K6

The output is standardized internally across tools using HDRHistograms and can be viewed in a web app:

Usage

CLI

Commands Overview

❯ graphql-bench --help

USAGE
  $ graphql-bench [COMMAND]

COMMANDS
  help          display help for graphql-bench
  query         benchmark queries or mutations
  subscription  benchmark subscriptions
❯ graphql-bench query --help
benchmark queries or mutations

USAGE
  $ graphql-bench query

OPTIONS
  -c, --config=config    (required) Filepath to YAML config file for query benchmarks
  -h, --help             show CLI help
  -o, --outfile=outfile  Filepath to output JSON file containing benchmark stats
  --url=url              URL to direct graphql queries; may override 'url' from the YAML config, which is optional if this flag is passed

EXAMPLE
  $ graphql-bench query --config ./config.query.yaml --outfile results.json
❯ graphql-bench subscription --help
benchmark subscriptions

USAGE
  $ graphql-bench subscription

OPTIONS
  -c, --config=config  (required) Filepath to YAML config file for subscription benchmarks
  -h, --help           show CLI help

EXAMPLE
  $ graphql-bench subscription --config ./config.subscription.yaml

Queries/Mutations

When running locally, add executable permission to the

  • run binary at app/cli/bin by running chmod +x run
  • k6 binary at app/queries/bin/k6/ by running chmod +x k6
  • wrk binary at app/queries/bin/wrk/ by running chmod +x wrk
Config

The Query/Mutation CLI bench expects a YAML config of the following format:

url: 'http://localhost:8085/v1/graphql'
headers:
  X-Hasura-Admin-Secret: my-secret
# "Debug" mode enables request and response logging for Autocannon and K6
# This lets you see what is happening and confirm proper behavior.
# This should be disabled for genuine benchmarks, and only used for debugging/visibility.
debug: false
queries:
    # Name: Unique name for the query
  - name: SearchAlbumsWithArtist
    # Tools: List of benchmarking tools to run: ['autocannon', 'k6', 'wrk2']
    tools: [autocannon, k6]
    # Execution Strategy: the type of the benchmark to run. Options are: 
    # REQUESTS_PER_SECOND: Fixed duration, fixed rps. Example parameters:
    #   duration: 10s
    #   rps: 500
    # FIXED_REQUEST_NUMBER: Complete requests as fast as possible, no duration. Example parameters:
    #   requests: 10000
    # MAX_REQUESTS_IN_DURATION: Make as many requests as possible in duration. Example parameters:
    #   duration: 10s
    # MULTI_STAGE: (K6 only currently) Several stages of REQUESTS_PER_SECOND benchmark. Example parameters:
    #   initial_rps: 0
    #   stages:
    #     - duration: 5s
    #       target: 100
    #     - duration: 10s
    #       target: 1000
    # CUSTOM: Pass completely custom options to each tool (see full API spec for all supported options, very large)
    execution_strategy: REQUESTS_PER_SECOND
    rps: 2000
    duration: 10s
    connections: 50
    query: |
      query SearchAlbumsWithArtist {
        albums(where: {title: {_like: "%Rock%"}}) {
          id
          title
          artist {
            name
            id
          }
        }
      }
  - name: AlbumByPK
    tools: [autocannon, k6]
    execution_strategy: FIXED_REQUEST_NUMBER
    requests: 10000
    query: |
      query AlbumByPK {
        albums_by_pk(id: 1) {
          id
          title
        }
      }
  - name: AlbumByPKMultiStage
    tools: [k6]
    execution_strategy: MULTI_STAGE
    initial_rps: 0
    stages:
      - duration: 5s
        target: 100
      - duration: 5s
        target: 1000
    query: |
      query AlbumByPK {
        albums_by_pk(id: 1) {
          id
          title
        }
      }
Run with Docker

Note: to be updated when image published to Dockerhub

The Makefile contains steps to automate building/tagging/running the image. You can run make build_local_docker_image and then make run_docker_query_bench.

The configuration used by these make commands lives in /docker-run-test/config.(query|subscription).yaml, so edit those files to change the run parameters.

To manually execute, run the following (where the current directory contains the file config.query.yaml):

docker run --net=host -v "$PWD":/app/tmp -it \
  graphql-bench-local query \
  --config="./tmp/config.query.yaml" \
  --outfile="./tmp/report.json"
Run Locally
cd cli
yarn install
./bin/run query  --config="<query YAML config file path here>" --outfile="report.json"
Usage Guide
  • Watch the tool-specific output during the benchmark to view live metrics
  • Save the output to a file, IE report.json
  • Inspect report.json to view detailed statistics and histograms
  • Open the report.json in the web viewer app (hosted at https://hasura.github.io/graphql-bench/app/web-app/) for visual metrics

Subscriptions

Config

The Subscription CLI bench expects a YAML config of the following format:

url: 'http://localhost:8085/v1/graphql'
db_connection_string: postgres://postgres:postgrespassword@localhost:5430/postgres
headers:
  X-Hasura-Admin-Secret: my-secret
config:
  # Label must be unique per-run, it identifiers the run in the DB
  label: SearchAlbumsWithArtistUpdated
  # Total number of websocket connections to open
  max_connections: 20
  # New connections to make per second until target reached
  connections_per_second: 10
  # Whether or not to insert the subscription payload data into the DB at the end
  insert_payload_data: true
  # The subscription to run
  query: |
    subscription AlbumByIDSubscription($artistIds: [Int!]!) {
      albums(where: {artist_id: { _in: $artistIds}}) {
        id
        title
        updated_at
      }
    }
  # Optional variables (if subscription uses variables)
  variables:
    some_value: a_string
    # Ranges will loop repeatedly from "start" to "end" and increment by one for each new subscription
    some_range: { start: 1, end: 10 }
    another_range: { start: 50, end: 100 }
    some_number: 10
    artistIds: [1, 2, 3, 4]
    some_object:
      a_key: a_value
Note: Required Table

For the Subscriptions test to record data in the DB, it requires a table events present with the following schema:

CREATE TABLE public.events (
  -- unique label to identify benchmark
  label text NOT NULL
  -- connection_id represents the n'th connection
  connection_id int NOT NULL
  operation_id int NOT NULL
  -- event_number represents the nth event that was received by the client
  event_number int NOT NULL
  -- event_data stores the payload that was received
  event_data jsonb NOT NULL
  -- event_time stores the time at which the event was received by the client
  event_time timestamptz NOT NULL
  -- is_error represents whether the event was error or not
  is_error boolean NOT NULL
  --  latency is not populated by the benchmark tool, but this can be populated by calculating event_time - <event_triggered_time>
  latency int
)
Run with Docker

Note: to be updated when image published to Dockerhub

The Makefile contains steps to automate building/tagging/running the image. You can run make build_local_docker_image and then make run_docker_subscription_bench.

The configuration used by this make commands lives in /docker-run-test/config.(query|subscription).yaml, so edit those files to change the run parameters.

To manually execute, run the following (where the current directory contains the file config.query.yaml):

docker run --net=host -v "$PWD":/app/tmp -it \
  graphql-bench-local subscription \
  --config="./tmp/config.subscription.yaml" \
Run Locally
cd cli
yarn install
./bin/run subscription --config="<subscription YAML config file path here>"
Usage Guide
  • Create events by making changes in the subscribed table

  • As you create changes, you should notice the number of data events increasing in stdout output:

  • Stop the benchmark with ctrl + c

  • The script should say it has inserted the event data:

    ❯ Executing Teardown Process
    ❯ Starting to close socket connections
    ❯ Sockets closed, attempting to insert event data
    ❯ Inserted total of 10 events for label SearchAlbumsWithArtistUpdated
    ❯ Trying to close DB connection pool
    ❯ Database connection destroyed
    ❯ Now exiting the process
    

Programmatic API

Note: A good reference/usage demo exists at /queries/src/tests.ts and /subscriptions/src/tests.ts.

Queries/Mutations

The easiest way of interacting with this library is to use the exported BenchmarkRunner class.

It exposes a single method, .runBenchmarks() which takes a GlobalConfig object defining the benchmarks to be run. Here's an example of running a REQUESTS_PER_SECOND benchmark for a query using all of autocannon, k6, and wrk2:

import { BenchmarkRunner } from './main'
import {
  GlobalConfig,
  BenchmarkTool,
  MaxRequestsInDurationBenchmark,
  FixedRequestNumberBenchmark,
  RequestsPerSecondBenchmark,
  MultiStageBenchmark,
  CustomBenchmark,
} from './executors/base/types'

const queries = {
  searchAlbumsWithArtist: `
    query SearchAlbumsWithArtist {
      albums(where: {title: {_like: "%Rock%"}}) {
        id
        title
        artist {
          name
          id
        }
      }
    }`,
}

const rpsBench: RequestsPerSecondBenchmark = {
  tools: [BenchmarkTool.AUTOCANNON, BenchmarkTool.K6, BenchmarkTool.WRK2],
  name: 'AlbumsArtistTrackGenreAll',
  execution_strategy: 'REQUESTS_PER_SECOND',
  duration: '3s',
  rps: 500,
  query: queries.albumsArtistTracksGenreAll,
}

const tests: GlobalConfig = {
  url: 'http://localhost:8085/v1/graphql',
  headers: { 'X-Hasura-Admin-Secret': 'my-secret' },
  queries: [rpsBench],
}

async function main() {
  const runner = new BenchmarkRunner(tests)
  const results = await runner.runBenchmarks()
  console.log('Test results:', results)
}

main()

Subscriptions

The main exported method from the Subscriptions repo is what runs the benchmarks. Here's an example of programmatically running a subscription test:

import { SubscriptionBenchConfig } from './utils'
import { main as runSubscriptionBenchmark } from './main'

const testConfig: SubscriptionBenchConfig = {
  url: 'http://localhost:8085/v1/graphql',
  db_connection_string:
    'postgres://postgres:postgrespassword@localhost:5430/postgres',
  headers: {
    'X-Hasura-Admin-Secret': 'my-secret',
  },
  config: {
    label: 'SearchAlbumsWithArtist',
    max_connections: 20,
    connections_per_second: 10,
    insert_payload_data: true,
    query: `
      subscription AlbumByIDSubscription($artistIds: [Int!]!) {
        albums(where: {artist_id: { _in: $artistIds}}) {
          id
          title
          updated_at
        }
      }
    `,
    variables: {
      artistIds: [1, 2, 3, 4],
    },
  },
}

async function main() {
  await runSubscriptionBenchmark(testConfig)
}

main()

More Repositories

1

graphql-engine

Blazing fast, instant realtime GraphQL APIs on your DB with fine grained access control, also trigger webhooks on database events.
TypeScript
31,162
star
2

gitkube

Build and deploy docker images to Kubernetes using git push
Go
3,805
star
3

graphqurl

curl for GraphQL with autocomplete, subscriptions and GraphiQL. Also a dead-simple universal javascript GraphQL client.
JavaScript
3,339
star
4

skor

Now part of Hasura GraphQL Engine. Listen to postgres events and forward them as JSON payloads to a webhook
C
1,246
star
5

learn-graphql

Real world GraphQL tutorials for frontend developers with deadlines!
JavaScript
1,177
star
6

gatsby-gitbook-starter

Generate GitBook style modern docs/tutorial websites using Gatsby + MDX
JavaScript
985
star
7

awesome-react-graphql

A curated collection of resources, clients and tools that make working with `GraphQL and React/React Native` awesome
738
star
8

eff

🚧 a work in progress effect system for Haskell 🚧
Haskell
547
star
9

react-check-auth

Add auth protection anywhere in your react/react-native app
JavaScript
530
star
10

3factor-example

Canonical example of building a 3factor app : a food ordering application
JavaScript
458
star
11

awesome-live-reloading

A curated collection of live-reloading / hot-reloading / watch-reloading tools for different languages and frameworks.
435
star
12

ra-data-hasura

react-admin data provider for Hasura GraphQL Engine
TypeScript
335
star
13

awesome-vue-graphql

A curated collection of resources, clients and tools that make working with `GraphQL and Vue.js` awesome
302
star
14

hasura-ecommerce

TypeScript
246
star
15

pgdeltastream

Streaming Postgres logical replication changes atleast-once over websockets
Go
244
star
16

graphql-engine-heroku

Blazing fast, instant realtime GraphQL APIs on Postgres with fine grained access control, also trigger webhooks on database events.
Dockerfile
231
star
17

graphql2chartjs

graphql2chartjs reshapes your GraphQL data as per the ChartJS API.
JavaScript
222
star
18

hasura-aws-stack

A complete production ready 100% serverless stack on AWS with Hasura
JavaScript
215
star
19

json2graphql

From a JSON file to postgres-backed realtime GraphQL
JavaScript
200
star
20

3factor

3factor app is an architecture pattern for modern fullstack apps. 3factor apps are fast to build and are highly scalable.
SCSS
181
star
21

client-side-graphql

147
star
22

hasura-k8s-stack

A feature-complete Hasura stack on Kubernetes
JavaScript
138
star
23

hasura-actions-examples

Examples of handling custom business logic with Hasura Actions
JavaScript
135
star
24

awesome-angular-graphql

A curated collection of resources, clients and tools that make working with `GraphQL and Angular` awesome
132
star
25

gqless-movies-demo

A movies app using Hasura and gqless
TypeScript
127
star
26

awesome-fluent-graphql

Awesome list of fluent GraphQL clients & examples
TypeScript
106
star
27

graphiql-online

Explore your GraphQL APIs with headers
JavaScript
90
star
28

kubeformation

Create declarative cluster specifications for your managed Kubernetes vendor (GKE, AKS)
Go
86
star
29

data-dictionary

TypeScript
85
star
30

firebase2graphql

Move from Firebase realtime db to instant GraphQL APIs on Postgres
JavaScript
81
star
31

jwt-guide

TypeScript
79
star
32

nodejs-graphql-subscriptions-boilerplate

Boilerplate to setup GraphQL subscriptions in your nodejs code
JavaScript
78
star
33

pacha

Connect your private data to LLMs
PLpgSQL
74
star
34

graphql-serverless

Example boilerplates for GraphQL backends hosted on serverless platforms
Go
71
star
35

graphql-parser-hs

A GraphQL query parser for Haskell
Haskell
59
star
36

sphinx-graphiql

Sphinx plugin that adds a GraphiQL directive so that you can embed an interactive GraphQL query explorer in your docs
JavaScript
57
star
37

kriti-lang

A minimal JSON templating language
Haskell
55
star
38

schema-stitching-examples

JavaScript
44
star
39

gitkube-example

An example repo to be used with gitkube: git push to deploy on to Kubernetes
HTML
43
star
40

graphql-backend-benchmarks

GraphQL performance benchmarks across Hasura, Postgraphile and Prisma
Shell
42
star
41

comment-progress

Notify progress by commenting on GitHub issues, pull requests, and commits :octocat: πŸ’¬
JavaScript
42
star
42

local-development

[Deprecated] Run Hasura locally on your computer
37
star
43

rxdb-hasura-demo

An Offline first todo app
JavaScript
37
star
44

monad-validate

(NOTE: REPOSITORY MOVED TO NEW OWNER: https://github.com/lexi-lambda/monad-validate) A Haskell monad transformer library for data validation
Haskell
32
star
45

pod42

Python
31
star
46

gitlab-graphql

Install gitlab and expose the gitlab api's over GraphQL
JavaScript
29
star
47

codegen-assets

TypeScript
27
star
48

ndc-hub

Go
26
star
49

data-hub

Explore data sources from a native GraphQL API, database schemas to custom code contributed by the community.
PLpgSQL
26
star
50

pg-client-hs

A low level Haskell library to connect to postgres
Haskell
25
star
51

yelp-clone-react

A Yelp clone built using React + GraphQL + Hasura
JavaScript
24
star
52

github-integration-starter

Try out Hasura's GitHub Integration on Cloud Projects using the examples in this repo.
24
star
53

template-gallery

Repository containing schema sharing packages.
PLpgSQL
24
star
54

authz-workshop

TSQL
23
star
55

hasura-cloud-preview-apps

TypeScript
22
star
56

graphql-schema-stitching-demo

Schema Stitching Example with Hasura GraphQL + MetaWeather API
JavaScript
22
star
57

hasura-discord-docs-bot

PLpgSQL
21
star
58

ndc-typescript-deno

Instant Hasura Native Data Connector by writing Typescript Functions
TypeScript
21
star
59

ndc-spec

NDC Specification and Reference Implementation
Rust
20
star
60

issues

Dump and sync org wide issues into postgres and visualise with metabase.
Python
19
star
61

realm-pg-sync

The realm-pg-sync microservice
JavaScript
18
star
62

graphql-data-specification

A specification for Data APIs with GraphQL
Haskell
18
star
63

imad-app

Base repository for IMAD course application.
JavaScript
18
star
64

ndc-postgres

Hasura v3 Data Connector for PostgreSQL
Rust
18
star
65

react-apollo-todo

A todo app with react, apollo demonstrating graphql queries, mutations and subscriptions.
CSS
17
star
66

architect-graphql-workshop

JavaScript
16
star
67

continuous-backup

Postgres wal-e continuous backup system
Shell
16
star
68

preview-actions

Starter kit to try out actions
JavaScript
16
star
69

auth-ui-kit

Web UI Kit for Hasura Authentication
JavaScript
15
star
70

graphql-example-apps

PLpgSQL
14
star
71

smooth-checkout-buildkite-plugin

All the things you need during a Buildkite checkout 🧈 πŸͺ
Shell
14
star
72

js-sdk

JavaScript
14
star
73

cloud-functions-boilerplates

Boilerplates for cloud functions (AWS Lambda, Google Cloud Functions, Azure Cloud Functions, Zeit, etc.) that work in conjunction with Hasura GraphQL Engine's event triggers
JavaScript
14
star
74

graphql-subscriptions-benchmark

TypeScript
13
star
75

sample-apps

TypeScript
12
star
76

demo-apps

Config to deploy Hasura demo apps using Docker Compose
HTML
12
star
77

github-bot

Hasura's own GitHub bot πŸ€–
JavaScript
11
star
78

generator-hasura-web

JavaScript
11
star
79

open-data-domain-specification

Rust
11
star
80

sqlite-dataconnector-agent

SQLite Data Connector Agent for Hasura GQL Engine. Please note that this repository is a mirror. We will still accept PRs, but will have to mirror them to our upstream repo.
TypeScript
11
star
81

ndc-sdk-typescript

NDC SDK for TypeScript
TypeScript
11
star
82

smooth-secrets-buildkite-plugin

A buildkite plugin to setup ssh keys and env secrets for your pipelines 🧈 πŸ”’
Shell
11
star
83

chat-app-android

Java
10
star
84

custom-resolvers-boilerplate

A boilerplate for writing custom resolvers with Hasura GraphQL Engine
JavaScript
10
star
85

reactathon-workshop

10
star
86

go-buildkite-dsl

Write Buildkite configs in Go πŸͺ πŸ“
Go
9
star
87

android-sdk

The Android SDK for Hasura
Java
9
star
88

sample-auth-webhook

Sample auth webhooks for the Hasura GraphQL engine
JavaScript
9
star
89

generator-hasura-node

JavaScript
9
star
90

graphql-asia-workshop

JavaScript
9
star
91

supergraph-io

Content for the supergraph.io website
HTML
8
star
92

graphql-on-various-pg

Hasura's GraphQL engine on various Postgres systems/providers
Shell
8
star
93

cli-plugins-index

Shell
8
star
94

graphql-weather-api

A simple GraphQL express weather api server boilerplate
JavaScript
8
star
95

supergraph-top-n-challenge

JavaScript
8
star
96

ddn-sample-app

TypeScript
8
star
97

ndc-nodejs-lambda

Write NodeJS TypeScript functions and easily expose them in your Hasura DDN project
TypeScript
7
star
98

haskell-docker-builder

Package haskell binaries as docker images
Makefile
7
star
99

graphql-engine-install-manifests

Various installation manifests for Hasura's GraphQL Engine
Shell
7
star
100

laravel-todo-hge

A sample Laravel app with an auth webhook
PHP
7
star