While Memorystore for Redis provides real-time, server-side metrics to monitor throughput, CPU utilization, and memory usage, this data alone might not explain why your client application experiences high latency within complex distributed systems.
Client-side metrics solve this by providing transparency into the full request-response cycle. They measure a command from the time the application initiates it until the application processes the response. By capturing these data points, you can accurately determine whether the latency originates from the application logic, the network path, or the Redis server.
Before you begin
Ensure that your client application uses a service account and the following Identity and Access Management (IAM) roles are assigned to it:
roles/cloudtrace.agent(Cloud Trace Agent)roles/monitoring.metricWriter(Monitoring Metric Writer)
For more information about granting roles, see the Grant an IAM role by using the Google Cloud console quickstart.
Enable the Cloud Monitoring API
To export client-side metrics to Monitoring, your application requires the Monitoring API to be enabled. Exporting and visualizing these metrics in Monitoring lets you pinpoint the root cause of bottlenecks to determine whether the latency originates.
To enable the Monitoring API, do the following:
In the Google Cloud console, go to the APIs & Services page.
Select the project where you created the Memorystore for Redis instance.
Click Enable APIs and services.
Search for
monitoring.In the search results, click Cloud Monitoring API.
If API enabled appears, then the API is already enabled. Otherwise, click Enable.
Enable the Cloud Trace API
To view distributed traces in Trace, you must enable the Trace API. You can then use Trace Explorer to view these traces, diagnose bottlenecks, and isolate the source of latency in your application.
To enable the Trace API, do the following:
In the Google Cloud console, go to the APIs & Services page.
Select the project where you created the Memorystore for Redis instance.
Click Enable APIs and services.
Search for
trace.In the search results, click Cloud Trace API.
If API enabled appears, then the API is already enabled. Otherwise, click Enable.
Enable client-side metrics
To enable client-side metrics, add the OpenTelemetry SDK, the Cloud Monitoring exporter, and the Cloud Trace exporter to your application's code. The OpenTelemetry instrumentation, which runs directly inside of your application's Redis client library, captures the metrics. This lets your application record latency data points and export them to Monitoring and Trace for visualization.
To enable client-side metrics, you can use Go, Java, Node.js, or Python. Information for enabling the metrics for each language appears in the tabs that follow.
Go
To install the required OpenTelemetry and Google Cloud exporter dependencies, run the following commands in your terminal:
go get github.com/gomodule/redigo/redis@latest go get go.opentelemetry.io/otel go get go.opentelemetry.io/otel/sdk/trace go get go.opentelemetry.io/otel/sdk/metric go get github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace go get github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric
To enable the client-side metrics, create a
main.gofile and add the following code to it:Run your application for at least a minute to give the exporter enough time to batch and send the published metrics to Monitoring.
Java
To install the required OpenTelemetry and Google Cloud exporter dependencies, add the following code to your application's
pom.xmlfile:To enable the client-side metrics, create a
RedisTelemetryApp.javafile and add the following code to it:Run your application for at least a minute to give the exporter enough time to batch and send the published metrics to Monitoring.
Node.js
To install the required OpenTelemetry and Google Cloud exporter dependencies, run the following commands in your terminal:
npm install redis@^4.6.0 @opentelemetry/api@^1.9.0 @opentelemetry/sdk-trace-node@^2.1.0 @opentelemetry/sdk-trace-base@^2.1.0 @opentelemetry/sdk-metrics@^2.1.0 @opentelemetry/instrumentation@^0.205.0 @opentelemetry/instrumentation-redis@^0.67.0 @google-cloud/opentelemetry-cloud-trace-exporter@^3.0.0 @google-cloud/opentelemetry-cloud-monitoring-exporter@^0.21.0 @opentelemetry/resources@^2.1.0
To enable the client-side metrics, create a
server.jsfile and add the following code to it:Run your application for at least a minute to give the exporter enough time to batch and send the published metrics to Monitoring.
Python
To install the required OpenTelemetry and Google Cloud exporter dependencies, run the following commands in your terminal:
pip install redis==7.0.1 opentelemetry-api==1.39.1 opentelemetry-sdk==1.39.1 opentelemetry-instrumentation-redis==0.60b1 opentelemetry-exporter-gcp-trace==1.11.0 opentelemetry-exporter-gcp-monitoring==1.11.0a0
To enable the client-side metrics, create a
main.pyfile and add the following code to your application:Run your application for at least a minute to give the exporter enough time to batch and send the published metrics to Monitoring.
View metrics in Monitoring
After you enable client-side metrics and run your application for at least a minute to give the exporter enough time to batch and send metrics to Monitoring, use Monitoring to visualize your metrics, group them by operation or instance, and apply aggregators to monitor your application's performance.
To view metrics in Monitoring, do the following:
In the Google Cloud console, go to the Metrics explorer page.
Select your Google Cloud project.
Click Select a metric.
Search for
workload.googleapis.com/redis.Select a client-side metric. Group the data by
operationandinstanceas needed, and pick an aggregator. To explore more options, see Select metrics when using Metrics Explorer.
View distributed traces in Trace
After your application begins exporting data, you can use Trace to visualize the full request-response cycle of your Redis commands. Viewing your distributed traces in Trace lets you diagnose bottlenecks so that you can quickly isolate the exact source of latency in your application.
To view distributed traces in Trace, do the following:
In the Google Cloud console, go to the Trace explorer page.
Select a recent trace represented by a dot on the scatter plot.
Examine the waterfall view to isolate the source of latency by identifying the following bottlenecks:
Total request duration: the top-level (parent) bar shows the total time that you must wait for the operation to finish.
Network and server latency (RTT): the child bars (such as those labeled
GETorSET) show the time the command spent traveling across the network and running on the Memorystore for Redis server.Client connection blocking: if there's a large, empty horizontal gap before the Redis child span begins, then the application thread is stuck waiting for an available TCP connection from the connection pool.
Application parsing blocking: if there's a large, empty horizontal gap after the Redis child span ends, then the application struggles to parse or process the returned payload. This often happens with multi-megabyte JSON strings.
Retries: if you see multiple, short child spans for the same command occurring sequentially within the same parent trace, then your client might experience network packet loss and has to trigger its exponential backoff retry loop.
Troubleshoot
This section lists common performance issues that you can identify using client-side metrics, explains their root causes, and provides guidance on troubleshooting the issues.
| Issue | Cause | Troubleshoot |
|---|---|---|
Your application experiences a sudden latency spike, but Memorystore for Redis appears completely healthy.
|
The bottleneck is strictly inside your application. Your
threads attempt to run Redis commands, but the connection pool is fully
exhausted. The high redis_client_blocking_latency represents
the time your code spends waiting for an available TCP socket before the
command is sent to the network. |
To handle the higher concurrent traffic, increase the
connection pool size limits in your Redis client configuration (for example,
MaxActive for Go, MaxTotal for Java, or
max_connections for Node.js and Python). |
The request completes, but the endpoint takes significantly longer than expected. There aren't issues associated with the health of your network or server.
|
Memorystore for Redis runs the command and the network transfers the
payload quickly (low RTT). However, the payload that returns is large (for
example, a 15-MB JSON string). Your application experiences a high
redis_application_blocking_latency because the application
consumes excessive resources while allocating memory and deserializing that
large string into an object. |
Optimize your data model. Don't store massive JSON blobs in single keys.
Break the data down using Redis hashes (HSET) and use
HGET or HMGET to retrieve only the specific fields
that you need.
|
Your user-facing application latency spikes, but your Redis metrics report a low server latency and typical connection pool checkouts.
|
Because redis_client_rtt only captures the RTT of
successful requests, it doesn't reflect the timeout duration of a failed
packet. When your application experiences transient packet drops or TCP
resets, your instrumented client's retry logic increments the
redis_retry_count and triggers its exponential backoff loop.
This introduces a sleep time between attempts (for example,
100ms, 200ms, or 400ms). The user
experiences high total latency, but the underlying root cause is a network
packet loss, which triggers client-side sleep delays. |
Check your VPC Flow Logs for dropped packets, bandwidth throttling,
or cross-region routing anomalies. If you experience aggressive timeouts,
then ensure your client connection timeouts (socket_timeout or
connect_timeout) are greater than the expected RTT to account
for transient network jitter. |
Everything stops and all layers of the telemetry pipeline report high latency.
|
Redis is single-threaded. When you run an O(N)
time-complexity command—such as KEYS *, SMEMBERS
on a massive set, or HGETALL on a hash with millions of
fields—the Redis engine pauses to fulfill that request. While that command
runs, every other application request queues, causing a system-wide latency
spike. Because your custom redis_client_rtt matches the
server's latency (commands/usec_per_call), the server that runs
the command is the bottleneck. |
Open Trace and look at the Redis commands on the slow spans to identify which query causes the blockage. Replace blocking commands with non-blocking ones in your code. To iterate through large datasets incrementally without locking the
server thread, use |
Your application reports a consistent, elevated baseline latency for all Redis commands, even when traffic is low.
|
The Redis server runs commands instantly, but your application and your
instance are deployed in different regions (for example,
us-central1 and us-east1). Every network packet
must travel across the physical Google Cloud infrastructure between these
geographical data centers. This results in a mandatory speed-of-light
cross-region latency penalty for every round trip. |
To reduce latency, deploy your application to reside in the same region and zone as your instance. To view the region of your application and instance, use the Google Cloud console. |
What's next
- Learn more about client-side metrics.
- Learn about the client-side metrics that are available for Memorystore for Redis.