Skip to main content

gRPC communications

Concept

A gRPC communication is a single Remote Procedure Call carried over gRPC-over-HTTP/2, decoded from the HTTP/2 frames of a TCP session. Each call maps to one HTTP/2 stream: its request message(s), its response message(s), the call metadata (HTTP/2 headers and trailers) and the final gRPC status.

Each gRPC communication is associated with:

  • Source and destination IP address
  • Source and destination TCP port
  • The fully-qualified method called, split into its service (e.g. echo.Echo) and method (e.g. Ping)
  • The kind of call:
    • unary - one request message, one response message
    • server-stream - one request, a stream of responses
    • client-stream - a stream of requests, one response
    • bidi - a stream of requests and a stream of responses
    • misc - a stream whose shape could not be classified
  • The request and response metadata (HTTP/2 headers / trailers)
  • The final gRPC status (OK, NOT_FOUND, UNAVAILABLE…) and message
  • The protobuf message(s) carried by the request and the response, optionally transcoded to JSON via a schema binding

gRPC communications are extracted while parsing the TCP sessions in streaming, on the Spider backend. gRPC is almost always carried over TLS (ALPN h2); the master secrets captured by Gocipher are used to decrypt it before parsing.

Hybrid com model

A simple unary call is stored as one paired communication (request + response), like an HTTP communication. A streaming call (server / client / bidi) is exploded into one communication per message, all sharing a single transactionId (the call id), so the message-centric UI (grid, sequence diagram, waterfall, timeline, statistics) renders and time-buckets each message individually. Every communication still carries req and res parts - the message's own side is real, the other side is synthetic (it only carries the fullMethod and a timestamp) so req.start and req.fullMethod stay searchable on every message. See Transaction.

gRPC communications appear in the dedicated gRPC view - grid, timeline, dashboard, sequence diagram, waterfall and statistics. Each streaming message is its own row, grouped by call:

Grpc-Grid.png

Global Tab

The Global tab summarises the call: timing, identification, network, request, response and Spider info.

Grpc-GlobalTab.png

Timing

The timing diagram shows the client and server hosts, the request (green) and response (orange) shapes scaled by the packet timestamps with per-packet markers, the identity line (service/method - size), and the response summary (gRPC status + size). The gRPC server port (50051 by convention) is labelled with the service.

  • The client and server hosts are shown, by order of preference:
    • The short name of the Host, as extracted during integration in the backend, or as renamed by a user
    • The FQDN of the Host
    • The IP address, if no Host found

General

The General section shows identification information:

FieldDescription
MethodThe fully-qualified method service/method (e.g. echo.Echo/Ping)
ServiceThe gRPC service called (e.g. echo.Echo)
RPCThe method called (e.g. Ping)
Kindunary, server-stream, client-stream, bidi or misc
TransactionThe call id grouping all per-message communications of a streaming call
StatusA computed status, made to match HTTP semantics
IdentificationThe resolved identification of the client

Spider maps the final gRPC status onto HTTP-like status codes so gRPC communications are comparable with HTTP, PostgreSQL and Redis ones (e.g. 200 for OK, 404 for NOT_FOUND, 401 / 403 for UNAUTHENTICATED / PERMISSION_DENIED, 503 for UNAVAILABLE). The original gRPC status code and name are kept on the response.

Request

The Request section shows summary information of the request part:

FieldDescription
StartDate the request started, user's local time
EndDate the request ended
MessagesNumber of request messages
SizeTotal bytes sent to the server

Response

The Response section shows summary information of the response part:

FieldDescription
StartDate the response started
EndDate the response ended
DurationThe difference between request start and response end
gRPC statusThe final gRPC status code and name (0 / OK, 5 / NOT_FOUND…)
gRPC messageThe status message returned in the trailers, when any
MessagesNumber of response messages
SizeTotal bytes received from the server

Network

The Network section shows the connection endpoints (From / To) and the Whisperer that captured the call.

The call metadata (HTTP/2 headers and trailers) is shown on its own Headers tab.

The request Template (a stable name for recurrent calls, defaulting to the full method) and any extracted Tags are configured at Whisperer level and are searchable.

Tags

Tags are a very powerful feature of Spider parsing process.

They are configured at Whisperer level, and allow custom extraction of the data exchanged. They allow searching and aggregating by the extracted values.

Unlike HTTP / Redis tags - which match a regular expression over the exchanged bytes - gRPC tags are field paths. Each tag names a path into a per-side view of the call:

  • on the request: service, method, fullMethod, metadata.<key> or message.<field.path> (into the decoded protobuf message)
  • on the response: grpcStatus, grpcStatusName, grpcMessage, metadata.<key> or message.<field.path>

This makes message-field extraction exact (no regex over binary), at the cost of needing a schema binding to reach message.* paths.

tip

Tags may be enriched / decoded by a plugin. For instance:

  • To translate internal identifiers from a message field into their business names
  • With a link to open them in the application under observation

Transaction

A streaming call (server / client / bidi) is stored as one communication per message; a Transaction line links all those messages together through a shared transactionId, so you can follow the whole streaming call at once. Each streaming-message communication carries a direction (req / res), a 0-based index within its direction, and a terminal flag on the last response (which also carries the final gRPC status). A unary call is its own transaction (transactionId equals its @id, with no direction / index).

Spider info

This section shows Spider own information:

FieldDescription
WhispererName and link to the Whisperer
InstanceInstance of the Whisperer that captured the communication
Tcp sessionTcp session id and link
Request parsingParsing status of the request
Response parsingParsing status of the response

Actions

For messages from streaming communications, you may access the full streaming flow by clicking on the View full stream button. It opens the whole call - all of its messages, grouped by transactionId - in the dedicated Transaction view. The button only appears on a streaming message (one that carries a direction); a unary call is its own transaction, so there is nothing extra to open.

Headers tab

The Headers tab shows the call metadata: the Request metadata (HTTP/2 request headers) and the Trailers & status (HTTP/2 response trailers, including the :status and the grpc-status).

Grpc-HeadersTab.png

Request tab

The Request tab shows the protobuf message(s) sent by the client.

Each message is shown in an indexed message table - one row per message. A toggle switches between the raw bytes and the transcoded JSON form when a schema binding matches the call's (service, method).

Grpc-RequestTab.png

Response tab

The Response tab shows the protobuf message(s) returned by the server, with the final gRPC status.

Streaming responses are shown in the same indexed message table - one row per message - with the same raw ↔ transcoded toggle.

Grpc-ResponseTab.png

Transcoded view

When a content schema is bound to a (service, method) pair, Spider transcodes the matching request and response messages from their binary protobuf form to searchable JSON. The message table then defaults to the Transcoded view, and falls back to Raw with a banner when the binding misses or decoding fails. The request and response sides are bound independently. Tags and templates can extract from the JSON form of transcoded messages.

Transaction view

A streaming call (server / client / bidi) is exploded into one communication per message, so the grid shows each message on its own row. To follow the whole call at once, open the Transaction view: from any streaming message, go to its Global tab and click View full stream (see Actions). The view is titled gRPC call: <fullMethod> and gathers every message sharing the same transactionId, ordered by their absolute position in the stream.

It has three tabs: Global, Flow and Source.

Transaction - Global tab

The Global tab summarises the whole call (not a single message), with a compact timeline of all its messages and the following sections:

SectionFields
CallMethod (service/method), Service, RPC, Kind (unary / server-stream / client-stream / bidi)
TimingStart (first message), Stop (last message) and Duration of the whole call
MessagesTotal messages, Request messages, Response messages, Request size, Response size
StatusThe final gRPC status code and name, the gRPC message, and the HTTP-mapped status code
Spider infoThe Whisperer, the Tcp session and the Transaction id

Grpc-Transac-GlobalTab.png

Transaction - Flow tab

The Flow tab renders the call as a time-aligned, chat-style flow of its messages - the natural way to read a streaming conversation:

  • A compact timeline header shows every message as a bar (request above the centerline, response below), sized by payload, with a scroll-synced cursor window marking which messages are currently visible in the flow below.
  • The client and server endpoints are shown on the left and right.
  • Each message is a card, laid out chat-style (requests to the left, responses to the right), showing:
    • its direction and index (Req #0, Res #3…), its timestamp, and - on the terminal response - a terminal marker and the final gRPC status,
    • the message payload size, and an icon to open that individual message in its own detail view,
    • the message content in a coloured block (green for a request, orange for a response): the transcoded protobuf when a schema binding matches, falling back to the raw bytes otherwise (truncated for very large messages),
    • the inter-message delay (∆ <n> ms) from the previous message, when any.

Grpc-Transac-FlowTab.png

Message contents are fetched lazily as you scroll, so even long streams open quickly.

Transaction - Source tab

The Source tab shows the raw JSON of the transaction: the call summary object together with the array of all its per-message communications.

Packets tab

The Packets tab shows the network packets composing the gRPC communication. You may open them by clicking on the rows.

FieldDescription
DirDirection of the packet
TimeTime the packet was captured
PayloadSize of the TCP payload
InfoFlags and beginning of TCP payload, in ASCII

::: note gRPC is almost always carried over TLS, so the packets are encrypted. The only ways to see them decrypted is to access the TCP session, and:

  • to read the packets from the beginning, in the content tab,
  • or to export the session in .pcapng format (for Wireshark or alike) :::

Source

The Source tab shows the gRPC communication in JSON format. Below is a sample unary gRPC communication as it is available through the API:

{
"@id": "oWl09MaiTVOz6Kuk7H9eOg.grpc-server-7c9f8d-q2xkz.494744.10.42.0.67-40122-10.42.0.53-50051.554123633.GrpcCom.5",
"@type": "GrpcCom",
"dateModified": "2026-06-18T08:51:35.289+00:00",
"tcpSession": "oWl09MaiTVOz6Kuk7H9eOg.grpc-server-7c9f8d-q2xkz.494744.10.42.0.67-40122-10.42.0.53-50051.554123633",
"instanceId": "grpc-server-7c9f8d-q2xkz",
"name": "554123633.10.42.0.67-40122-10.42.0.53-50051.GrpcCom",
"whisperer": "oWl09MaiTVOz6Kuk7H9eOg",
"kind": "unary",
"transactionId": "oWl09MaiTVOz6Kuk7H9eOg.grpc-server-7c9f8d-q2xkz.494744.10.42.0.67-40122-10.42.0.53-50051.554123633.GrpcCom.5",
"req": {
"status": "COMPLETE",
"service": "echo.Echo",
"method": "Ping",
"fullMethod": "echo.Echo/Ping",
"template": "Ping",
"streamingKind": "single",
"messageCount": 1,
"totalSize": 18,
"size": 18,
"metadata": {
"content-type": "application/grpc",
"user-agent": "grpc-go/1.64.0"
},
"start": 1781081483.696741,
"startDate": "2026-06-18T08:51:23.696Z",
"end": 1781081483.696741,
"endDate": "2026-06-18T08:51:23.696Z",
"startMinute": "2026-06-18T08:51:00Z"
},
"res": {
"status": "COMPLETE",
"fullMethod": "echo.Echo/Ping",
"streamingKind": "single",
"grpcStatus": 0,
"grpcStatusName": "OK",
"grpcMessage": "",
"messageCount": 1,
"totalSize": 20,
"size": 20,
"metadata": {
"content-type": "application/grpc"
},
"start": 1781081483.696792,
"startDate": "2026-06-18T08:51:23.696Z",
"end": 1781081483.696984,
"endDate": "2026-06-18T08:51:23.696Z"
},
"stats": {
"withTls": true,
"statusCode": 200,
"statusText": "OK",
"duration": 0.00024318695068359375,
"dst": {
"ip": "10.42.0.53",
"name": "grpc-server-7c9f8d-q2xkz",
"port": 50051,
"socket": "10.42.0.53:50051"
},
"src": {
"ip": "10.42.0.67",
"name": "grpc-client-645b88849b-gkrmm.test-grpc-tls.pod.cluster.local.",
"port": 40122,
"socket": "10.42.0.67:40122"
},
"timespan": {
"gte": "2026-06-18T08:51:23.696Z",
"lte": "2026-06-18T08:51:23.696Z"
},
"tags": {
"values": {},
"count": {},
"cardinality": {}
}
},
"grpcParsing": "oWl09MaiTVOz6Kuk7H9eOg.grpc-server-7c9f8d-q2xkz.494744.10.42.0.67-40122-10.42.0.53-50051.554123633.GrpcParsingLog"
}

Most fields are self-explanatory. Most fields are indexed and searchable.

Some extra explanation:

FieldDescription
kindunary, server-stream, client-stream, bidi or misc
transactionIdGroups all per-message communications of one streaming call; equals @id on a unary call
directionreq / res - set on a streaming-message communication; empty on a unary call
index0-based message index within its direction (streaming only)
terminaltrue on the last response message (carries the final gRPC status)
req.fullMethodFully-qualified method service/method (the default req.template)
req.templateComputed call name (see Templates) - defaults to fullMethod
req|res.metadataHTTP/2 headers (request) / trailers (response), as key / value pairs
req|res.messageCountNumber of protobuf messages on that side
res.grpcStatusThe numeric gRPC status code (0 = OK)
res.grpcStatusNameThe gRPC status name (OK, NOT_FOUND, UNAVAILABLE…)
res.grpcMessageThe gRPC status message returned in the trailers
statsStats object regroup most important information
stats.withTlstrue when the call was carried over TLS
stats.statusCodeThe gRPC status mapped onto HTTP semantics
stats.timespanIndexed as range, to allow range searching and aggregations
stats.src|dst.nameHostname resolved on the Whisperer
stats.tags.*Extracted tags values, count and cardinality
req|res.statusParsing status
note

The full request and response messages are stored separately (in a dedicated per-message content store) and fetched on demand from the Request / Response tabs, so the communication document itself stays small and fast to search.