Intro into gRPC
RoadRunner gRPC plugin enables PHP applications to communicate with gRPC clients.
It consists of two main parts:
protoc-plugin
protoc-gen-php-grpc: This is a plugin for the protoc compiler that generates PHP code from a gRPC service definition file (.proto). It generates PHP classes that correspond to the service definition and message types. These classes provide an interface for handling incoming gRPC requests and sending responses back to the client.gRPC server: This is a server that starts PHP workers and listens for incoming gRPC requests. It receives requests from gRPC clients, proxies them to the PHP workers, and sends the responses back to the client. The server is responsible for managing the lifecycle of the PHP workers and ensuring that they are available to handle requests.
For custom gRPC interceptor plugins, see Interceptors.
Protoc-plugin
The first step is to define a .proto file that describes the gRPC service and messages that your PHP application will handle.
In our documentation, we will use the following example of a .proto file that is stored in the <app>/proto directory:
syntax = "proto3";
option go_package = "proto/greeter";
option php_namespace = "GRPC\\Greeter";
option php_metadata_namespace = "GRPC\\GPBMetadata";
package helloworld;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}It defines a simple gRPC service called Greeter that takes a name as input and returns a greeting.
The php_namespace and php_metadata_namespace options allow you to specify the namespaces to use in the generated DTO and Service interface.
Generating PHP code
Use protoc 36.1 and Go 1.27.1. Install the RoadRunner generator from its pinned source revision:
Add the Go binary installation directory to PATH. Create the generated directory before running protoc.
The PHP generator uses the separate protoc_plugins/v5 module. Its module version is independent of the gRPC plugin v6.
Here's an example command:
After running the command, you can find the generated DTO and GreeterInterface files in the <app>/generated/GRPC/Greeter directory.
We recommend also registering the GRPC namespace in the composer.json file:
By doing this, you can easily use the generated PHP classes in your application.
Using BUF plugin
You can also use the BUF RoadRunner gRPC plugin to generate PHP code from the .proto file instead of using the protoc compiler.
To use BUF to generate PHP gRPC services, you'll need to create two files: buf.yaml and buf.gen.yaml.
Here's an example of a buf.yaml file:
The module contains the .proto files in proto/. If your files import external schemas, add their Buf modules under deps, run buf dep update, and keep the resulting buf.lock with your source files.
Here's an example of a buf.gen.yaml file:
Run buf generate from the directory that contains buf.yaml and buf.gen.yaml. The configuration pins each generator version and uses the RoadRunner plugin to generate PHP gRPC services.
For Buf output, set the GRPC\\ Composer autoload path to generated/php/GRPC. The example also generates Go and Python code.
PHP Client
The RoadRunner gRPC plugin comes with a convenient PHP package that simplifies the process of integrating the plugin with your PHP application.
Installation
You can install the package via Composer using the following command:
Implement Service
Next, you will need to create a PHP class that implements the Greeter service defined in the .proto file. This class should implement the GRPC/Greeter/GreeterInterface.
Here's an example:
Usage
To use the Greeter service, you can create a PHP worker that registers the service with the gRPC server.
Here's an example of how to do this:
After creating the worker, you need to configure RoadRunner to register the proto/helloworld.proto service.
Here's an example configuration:
You can also define command to start server in the grpc.pool.command section to separate server and grpc workers.
After configuring the server, you can start it using the following command:
This will start the gRPC server and make the Greeter service available for remote clients to call. You can use any gRPC client library in any language that supports gRPC to call the SayHello method.
To quickly verify your code's correctness, you can install grpc-client-cli which provides an interactive CLI tool for talking to gRPC services.
To access the Greeter service with grpc-client-cli run the following in a terminal:
grpc-client-cli --proto proto/helloworld.proto 127.0.0.1:9001
It will provide some interactive prompts asking you what service and method you want to call
You will then be prompted to manually form the JSON payload it expects and upon pressing enter, your Greeter service should respond in an amicable manner:
With debug logging enabled, RoadRunner writes records such as:
Congratulations on being able to communicate over gRPC to PHP using Roadrunner!
Metrics
RoadRunner has a metrics plugin that provides metrics for the gRPC server, which can be used with Prometheus and a preconfigured Grafana dashboard

mTLS
To enable mTLS use the following configuration:
require_and_verify_client_cert requires a client certificate signed by a trusted CA. request_client_cert only requests a certificate; it does not require or verify one.
Options for the client_auth_type are:
request_client_certrequire_any_client_certverify_client_cert_if_givenrequire_and_verify_client_certno_client_certs
Server reflection
The gRPC plugin enables server reflection on the gRPC listen port. Both the v1 and v1alpha reflection APIs are available without an enable flag.
Without a descriptor registry, reflection lists registered services but cannot return the file and message descriptors for PHP services. Configure the bundled Protoreg plugin with the same service definitions used by grpc.proto to provide those descriptors. See gRPC PR #141.
For a listener without TLS, list services with:
Health Checking
RoadRunner automatically registers a grpc.health.v1.Health service on the same gRPC listen port. This is the standard gRPC health checking protocol. No additional configuration is required.
Available methods
Check
Returns the current serving status of the server: SERVING or NOT_SERVING.
Watch
Opens a server-side stream that pushes status changes in real time.
List
Returns the health status of all registered services. Available since v2025.1.0 (requires grpc >= v1.72.0).
Lifecycle
When RoadRunner starts, the gRPC health service reports NOT_SERVING until workers are allocated and ready, then transitions to SERVING. On stop or reset the status reverts to NOT_SERVING.
Using grpc-health-probe
grpc-health-probe is a command-line tool commonly used as a Kubernetes health check for gRPC services.
If the server is healthy the tool exits with code 0; otherwise it exits with a non-zero code.
Example Kubernetes liveness probe:
Full example of Configuration
Unix Socket
Configure optional mode, uid, and gid fields under grpc.unix_socket. See Unix socket attributes for their values. Keep the other gRPC settings from the preceding example:
Configure clients to use the same Unix socket. These settings apply to the listener socket. They were added in gRPC PR #154.
Connection age grace
max_connection_age_grace controls how long active RPCs can continue after the connection reaches max_connection_age. Zero or omitted grace means unlimited time. Set a finite grace to close the connection after that period.
The v5 plugin used max_connection_age as the grace period and ignored max_connection_age_grace. To preserve that behavior, explicitly set both values to the same duration.
Error details in logs
For a failed unary call, the grpc logger adds a details field when the error contains supported google.rpc.Status details. This field contains an array of type names and one-line message values. It is omitted when the error has no supported details.
The supported types from google/rpc/error_details.proto are BadRequest, ErrorInfo, DebugInfo, Help, LocalizedMessage, PreconditionFailure, QuotaFailure, RequestInfo, ResourceInfo, and RetryInfo. Other detail types are omitted.
Use a structured log mode to retain the field:
For example, a field validation error can include:
See logger configuration and gRPC PR #148.
OTLP support in the gRPC plugin
In the v2023.3.8 we added experimental support for the OTLP protocol in the gRPC plugin. Stable since v2024.1.1. To enable it, you need to activate otel plugin by adding the following lines to the .rr.yaml file:
Trace keys passed to the PHP workers are:
TraceparentUber-Trace-Id
Example:
More about OTLP plugin you may read here.
Common issues
Registering two services with the same name is not allowed. GRPC server will panic after that.
Last updated
Was this helpful?