Skip to main content
The k6/net/grpc module provides a gRPC client for making Remote Procedure Calls (RPC) over HTTP/2.

Overview

Use this module to test gRPC services by making unary and streaming RPC calls. The module supports loading protocol buffer definitions, establishing connections, and invoking RPC methods with full support for metadata and parameters.

Importing the Module

import grpc from 'k6/net/grpc';

API Reference

Client Class

new grpc.Client()
constructor
Creates a new gRPC client for making RPC calls to a gRPC server.

Client Methods

Client.load(importPaths, ...protoFiles)
function
Loads and parses protocol buffer definitions to be made available for RPC requests.Parameters:
importPaths
string | string[]
Paths to search for imported proto files. Use null to load from current directory.
protoFiles
...string
required
One or more proto file paths to load
Client.connect(address, params)
function
Connects to a gRPC service.Parameters:
address
string
required
Server address (e.g., grpc.example.com:443)
params
Params
Connection parameters (TLS, credentials, timeout, etc.)
Client.invoke(url, request, params)
function
Makes a unary RPC call for the given service/method.Parameters:
url
string
required
RPC method in format package.Service/Method
request
object
required
Request message object matching the proto definition
params
Params
Request-specific parameters (metadata, tags, timeout)
Returns:
response
Response
gRPC response object
Client.asyncInvoke(url, request, params)
function
Asynchronously makes a unary RPC call for the given service/method.Parameters:
url
string
required
RPC method in format package.Service/Method
request
object
required
Request message object matching the proto definition
params
Params
Request-specific parameters
Returns:
promise
Promise<Response>
Promise that resolves to a gRPC Response
Client.close()
function
Closes the connection to the gRPC service.

Response Object

status
number
gRPC status code (see Constants below)
message
object
Response message from the server
headers
object
Response headers/metadata
trailers
object
Response trailers/metadata
error
object
Error information if the call failed

Params Object

metadata
object
Custom metadata to send with the request as key-value pairs.
tags
object
Custom metric tags for filtering results and setting thresholds.
timeout
string
Request timeout (e.g., "10s", "500ms")
plaintext
boolean
Use plaintext connection (no TLS). Default: false

Status Constants

The module provides constants to distinguish between gRPC response statuses:
ConstantDescription
StatusOKSuccess
StatusCanceledOperation canceled (typically by caller)
StatusUnknownUnknown error
StatusInvalidArgumentClient specified invalid argument
StatusDeadlineExceededOperation expired before completion
StatusNotFoundRequested entity not found
StatusAlreadyExistsEntity already exists
StatusPermissionDeniedCaller lacks permission
StatusResourceExhaustedResource exhausted (quota, space, etc.)
StatusFailedPreconditionSystem not in required state
StatusAbortedOperation aborted (concurrency issue)
StatusOutOfRangeOperation past valid range
StatusUnimplementedOperation not implemented or supported
StatusInternalInternal errors
StatusUnavailableService currently unavailable (transient)
StatusDataLossUnrecoverable data loss or corruption
StatusUnauthenticatedRequest lacks valid authentication

Stream Support

For bidirectional and streaming RPCs:
new grpc.Stream(client, url, params)
constructor
Creates a new gRPC stream for bidirectional or streaming calls.
Stream.on(event, handler)
function
Adds an event listener for stream events: data, error, end
Stream.write(message)
function
Writes a message to the stream.
Stream.end()
function
Signals to the server that the client has finished sending.

gRPC Metrics

k6 automatically collects gRPC-specific metrics:
MetricTypeDescription
grpc_req_durationTrendTotal request duration
grpc_streamsCounterTotal number of streams
grpc_streams_msgs_sentCounterMessages sent
grpc_streams_msgs_receivedCounterMessages received

Examples

Basic Unary RPC

import grpc from 'k6/net/grpc';
import { check, sleep } from 'k6';

const client = new grpc.Client();
client.load(null, 'quickpizza.proto');

export default () => {
  client.connect('grpc-quickpizza.grafana.com:443', {
    // plaintext: false
  });

  const data = { ingredients: ['Cheese'], dough: 'Thick' };
  const response = client.invoke('quickpizza.GRPC/RatePizza', data);

  check(response, {
    'status is OK': (r) => r && r.status === grpc.StatusOK,
  });

  console.log(JSON.stringify(response.message));

  client.close();
  sleep(1);
};

Async Invocation

import grpc from 'k6/net/grpc';
import { check } from 'k6';

const client = new grpc.Client();
client.load(null, 'service.proto');

export default async () => {
  client.connect('grpc.example.com:443');

  // Make multiple concurrent requests
  const promises = [
    client.asyncInvoke('service.API/Method1', { id: 1 }),
    client.asyncInvoke('service.API/Method2', { id: 2 }),
    client.asyncInvoke('service.API/Method3', { id: 3 }),
  ];

  const responses = await Promise.all(promises);

  responses.forEach((response, i) => {
    check(response, {
      [`request ${i} status is OK`]: (r) => r.status === grpc.StatusOK,
    });
  });

  client.close();
};

Streaming RPC

import grpc from 'k6/net/grpc';

const client = new grpc.Client();
client.load(null, 'service.proto');

export default () => {
  client.connect('localhost:50051', { plaintext: true });

  const stream = new grpc.Stream(client, 'service.API/BiDiStream');

  stream.on('data', (message) => {
    console.log('Received:', JSON.stringify(message));
  });

  stream.on('error', (err) => {
    console.error('Stream error:', err);
  });

  stream.on('end', () => {
    console.log('Stream ended');
    client.close();
  });

  // Send messages
  stream.write({ message: 'Hello' });
  stream.write({ message: 'World' });
  
  // Signal we're done sending
  stream.end();
};

Status Code Checking

import grpc from 'k6/net/grpc';
import { check } from 'k6';

const client = new grpc.Client();
client.load(null, 'service.proto');

export default () => {
  client.connect('grpc.example.com:443');

  const response = client.invoke('service.API/GetUser', { id: 'invalid' });

  check(response, {
    'status is OK': (r) => r.status === grpc.StatusOK,
    'status is NOT_FOUND': (r) => r.status === grpc.StatusNotFound,
    'status is INVALID_ARGUMENT': (r) => r.status === grpc.StatusInvalidArgument,
  });

  if (response.status !== grpc.StatusOK) {
    console.error(`gRPC error: ${response.error.message}`);
  }

  client.close();
};

Response Object

gRPC response structure

Stream

Streaming RPC support

gRPC Testing Guide

Learn gRPC testing patterns

Protocol Buffers

Protocol buffer documentation

Build docs developers (and LLMs) love