> ## Documentation Index
> Fetch the complete documentation index at: https://docs-xcor.paloaltonetworks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Redis

> Redis server health and performance metrics, including memory, clients, commands, keyspace, persistence, replication, and cluster state.

The Redis integration requires CXDOT Collector 1.12.0 or greater.

[Redis](https://redis.io/) is an in-memory data store that applications use as a
database, cache, and message broker. Use the Redis integration to collect memory,
client, command, key, persistence, replication, cluster, and slow log metrics from
Redis servers running in your environment.

The Redis integration supports Redis Open Source 7.0 or greater.

## Supported telemetry types

The Redis integration supports these telemetry types:

| Type | Supported |
| - | - |
| Logs | No |
| Metrics | Yes |
| Traces | No |
| Events | No |

## Prerequisites

The Redis integration has the following prerequisites:

* Make port `6379`, or your custom Redis port, reachable from the CXDOT Collector over
  TCP. The integration doesn't support Unix domain sockets.

* If your Redis servers require authentication, prepare credentials for the CXDOT
  Collector. On a server protected only by the `requirepass` password, the Collector
  authenticates with that password, so you don't need to create a user. On a server
  that uses an
  [access control list](https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl/)
  (ACL), connect with `redis-cli` as a user that can manage users, and create a user
  that can run only the commands the Collector sends:

  ```shell theme={null}
  redis-cli ACL SETUSER cxdot on '>PASSWORD' -@all +ping +info '+cluster|info' '+slowlog|get'
  ```

  Replace `PASSWORD` with a password for this user. The examples on this page use the
  username `cxdot`. If you choose another username, use it in the configuration too.
  To keep the user after the server restarts, run `ACL SAVE` if the server loads its
  users from an ACL file, or `CONFIG REWRITE` if it loads them from its configuration
  file.

  The optional collections in the Configure section use more commands. Collecting
  connections per client name needs `+client|list`. Collecting key lengths needs
  `+type +llen +scard +zcard +hlen +xlen`, `+scan` when `keys` contains a glob
  pattern, read access to the keys you list (for example, `'%R~queue:*'`), and
  `+select` when the keys are in databases other than `0`. A key that the user can't
  read doesn't report a length. Per-command statistics come from `INFO` and need no
  extra permission.

  On Redis 7.2 or greater, the `redis.acl.denied` metric counts the requests that ACL
  rules deny, including requests from the Collector. Each collection that reads a key
  the user can't read counts a denial with `redis.acl.denied.reason` set to `key`. Each
  time the Collector connects, it sends `CLIENT SETINFO` to report its client library
  name. The Collector doesn't depend on this command, but each denied `CLIENT SETINFO`
  counts with the `cmd` reason and appears in the ACL log, so that count climbs on every
  connection. To keep these denials out of `redis.acl.denied` and the ACL log, also
  grant `+client|setinfo`. Redis versions before 7.2 reject `+client|setinfo`, so omit
  it on those versions.

## Configure

The Redis integration is enabled by default. It collects from each Redis server
independently, whether the server is a standalone server, a primary, or a replica,
and whether or not it runs in cluster mode. The Collector doesn't follow cluster
redirects or discover other nodes from the servers it finds. Make sure that the
Collector discovers each node that you want to monitor, or list the node as a static
target.

### Configure on Kubernetes

To configure the Redis integration in Kubernetes, follow these steps:

1. Choose how the CXDOT Collector finds your Redis pods. For more information, see
   [autodiscovery](https://docs-xcor.paloaltonetworks.com/ingest/xcor/collector/discover/kubernetes.md).

   * For Redis pods that listen on port `6379`, add the
     `app.kubernetes.io/name: redis` label to the pod template. The Collector uses the
     same credentials, which you set in the next step, for every pod that it finds by
     label.
   * For Redis pods and Services that use another port, or that need their own
     credentials or TLS settings, provide the address, credentials, and TLS settings
     through autodiscovery annotations for Redis. A pod with annotations uses its
     annotation settings, even if it also carries the label. Annotate a Service only
     when it routes to a single Redis server. If a Service balances traffic across
     several Redis pods, its metrics mix readings from different servers, because the
     Collector holds more than one connection to each target and can reconnect at any
     time. For more than one server, annotate each pod instead.

   Metrics from discovered pods arrive with that pod's Kubernetes metadata attached.

2. Optional: Set the credentials for Redis pods that you label and that require a
   password, and provide the password through your deployment's secret management. The
   node Collector on each pod's node collects from the pods that it finds by label, so
   provide the password through `nodeCollector.extraEnv`. For more information about
   Collector tiers, see
   [architecture](https://docs-xcor.paloaltonetworks.com/ingest/xcor/collector/install/kubernetes/architecture.md).
   For example, the following Helm values read the password from a Kubernetes secret
   into the `REDIS_PASSWORD` environment variable:

   ```yaml theme={null}
   nodeCollector:
     extraEnv:
       - name: REDIS_PASSWORD
         valueFrom:
           secretKeyRef:
             name: redis-credentials
             key: password

   config:
     integrations:
       redis:
         username: cxdot
         password: "${env:REDIS_PASSWORD}"
   ```

   Omit `username` when the servers use only the `requirepass` password. A
   password-protected server that the Collector finds by label reports as unreachable
   until these credentials match it. Give a server with different credentials its own
   annotations, or list it as a static target in a second integration instance with
   its own credentials.

3. Optional: Configure static targets for Redis servers that the Collector doesn't
   discover, such as servers outside your Kubernetes cluster. For example, add the
   following to the Helm values file for your CXDOT Collector:

   ```yaml theme={null}
   config:
     integrations:
       redis:
         instances:
           - endpoint: redis-1.example.com:6379
           - endpoint: redis-2.example.com:6379
   ```

   When you configure static targets, this integration instance collects from exactly
   those targets instead of discovered targets. Static targets use the integration's
   `username`, `password`, and `tls` settings. The cluster Collector collects from
   static targets, so provide any password environment variable through
   `clusterCollector.extraEnv`.

4. Optional: Collect per-command statistics, open connections per client name, or the
   lengths of specific keys. These collections are off by default. For example, add the
   following to the Helm values file for your CXDOT Collector:

   ```yaml theme={null}
   config:
     integrations:
       redis:
         command_stats: true
         collect_client_metrics: true
         keys:
           - "queue:*"
           - jobs
   ```

   Each of these options adds work for the Redis server at every collection interval.
   A glob pattern in `keys`, such as `queue:*`, scans every key in each database that
   holds keys, so on a server with many keys, list key names rather than patterns where
   you can. Servers that the Collector finds by annotation use the settings in their
   annotations instead.

5. Optional: Configure a second integration instance to collect from both discovered
   and static targets, or to use different credentials for some static targets. For
   example, add the following to the Helm values file for your CXDOT Collector:

   ```yaml theme={null}
   config:
     integrations:
       redis: {}
       redis/external:
         username: cxdot
         password: "${env:EXTERNAL_REDIS_PASSWORD}"
         instances:
           - endpoint: redis-1.example.com:6379
   ```

   The `redis/external` key defines a named instance for the static targets, with its
   own credentials. The bare `redis` key continues to collect from discovered targets.
   Provide `EXTERNAL_REDIS_PASSWORD` through `clusterCollector.extraEnv`.

6. Optional: Disable the integration. For example, add the following to the Helm values
   file for your CXDOT Collector:

   ```yaml theme={null}
   config:
     integrations:
       redis:
         enabled: false
   ```

### Configure on a host

To configure the Redis integration on a host outside Kubernetes, such as a virtual
machine, [install the CXDOT Collector on Linux](https://docs-xcor.paloaltonetworks.com/ingest/xcor/collector/install/linux.md)
on each Redis host in host mode and list the local server. For example, add the
following to the Collector configuration file:

```yaml theme={null}
cxdot:
  mode: host
  integrations:
    redis:
      username: cxdot
      password: "${env:REDIS_PASSWORD}"
      instances:
        - endpoint: localhost:6379
```

The example reads the password from the `REDIS_PASSWORD` environment variable of the
Collector process. On a host, the integration collects only from the servers in
`instances`. The Collector adds the host's `host.name` attribute to every metric. When
every endpoint is `localhost`, `host.name` identifies the server. To collect from more
than one server on a host, such as several cluster nodes on different ports, list each
one.

### Validate

To validate the Redis integration, follow these steps:

1. In Live Telemetry Analyzer, filter for `__name__=cxdot.integration.target.health`
   and `cxdot.integration.name=redis`. Confirm that each expected target reports `1`.
   A value of `0` means that the Collector couldn't connect to the server,
   authenticate, or run `PING` and `INFO`. Use the `server.address` and `server.port`
   attributes, and `host.name` on hosts, to identify each target.

2. In Metrics Explorer, run the following query:

   ```text theme={null}
   count by ("host.name", "server.address", "server.port") ({"redis.uptime"})
   ```

   Confirm that the query returns one time series per target.

### Troubleshooting

* A target reports `0` and the Collector logs `NOAUTH Authentication required` or
  `WRONGPASS`: The server requires credentials that the Collector didn't send or that
  don't match. Static targets and servers that the Collector finds by label use the
  integration's `username` and `password`. Servers that the Collector finds by
  annotation use the credentials in their annotations.

* Some metrics are missing from a [Valkey](https://valkey.io/) server: The integration
  collects from Valkey, a fork of Redis, on a best-effort basis. Metrics that Valkey
  reports differently from Redis might be missing.

* A target reports `0` for a while after the Redis server starts: A server that loads
  its dataset from disk at startup rejects `PING` until loading finishes, so the
  Collector reports it as unreachable until then.

* Metrics don't carry the server's primary or replica role: The Collector reports the
  role once per server, as the `redis.role` metric with a `role` attribute, so
  promoting a replica doesn't start new time series for every metric. To filter by
  role, join on the server's identity. For example, the following query returns
  memory use for primaries only:

  ```text theme={null}
  {"redis.memory.used"} and on ("host.name", "server.address", "server.port") {"redis.role", role="primary"}
  ```

* Slow log metrics don't include entries from before the Collector started: The
  `redis.slowlog.duration` histogram counts each slow log entry once. It starts from
  the newest slow log entry when the Collector first reads the slow log, and starts
  again after the Redis server restarts or the Collector reaches a different server.
  Each collection reads at most the newest 128 entries, so the histogram counts only
  part of a burst of more than 128 slow commands within one collection interval.

## Configuration reference

Configure one Redis integration instance with the following settings. In Helm values, place
these settings under `config.integrations.redis`. In a Collector configuration file, place them
under `cxdot.integrations.redis`.

### Optional settings

* **`enabled`**
  Type: `boolean`. Optional. Default: `true`.
  Whether to run the Redis integration. If true, the Collector collects Redis metrics. If false,
  the Collector doesn't run this integration.

* **`username`**
  Type: `string`. Optional. Default: empty string.
  Redis ACL username for connections to static targets and targets that the Collector finds by
  label. Leave empty to authenticate as the Redis `default` user. Targets that the Collector
  finds by annotation use the credentials in their annotations instead.

* **`password`**
  Type: `string`. Optional.
  Redis password for connections to static targets and targets that the Collector finds by
  label: the `requirepass` password, or the ACL user's password when `username` is set. A target
  that requires a password the Collector doesn't send reports as unreachable. Targets that the
  Collector finds by annotation use the credentials in their annotations instead. The Collector
  masks this value in diagnostic output, logs, and errors.

* **`collection_interval`**
  Type: `duration`. Optional. Default: `10s`.
  Time between metric collections from each static target and each target that the Collector
  finds by label. Targets that the Collector finds by annotation use the collection interval
  their annotations set.

* **`timeout`**
  Type: `duration`. Optional. Default: `10s`.
  Maximum time allowed to collect metrics from one Redis target. The value must not exceed
  `collection_interval`.

* **`instances`**
  Type: `array of object`. Optional. Default: `[]`.
  Static Redis targets. Each entry's `endpoint` is `host:port`, for example,
  `redis.default.svc:6379`. When this list isn't empty, the integration collects from exactly
  these targets instead of discovered targets. On a host, the integration collects only from
  this list. In a Redis Cluster, list every node: each node reports only its own state, and the
  Collector doesn't discover other nodes from the one you list.

* **`instances[].endpoint`**
  Type: `string`. Required.
  Redis target in `host:port` format.

* **`command_stats`**
  Type: `boolean`. Optional. Default: `false`.
  Whether to collect per-command statistics from the `INFO commandstats` section: the number of
  calls to each command and the CPU time spent running it. If true, the Collector reports
  `redis.cmd.calls` and `redis.cmd.usec`, with one time series for each command that the server
  has run. If false, the Collector doesn't report them. Targets discovered through annotations
  use the `command_stats` setting in their annotations instead.

* **`collect_client_metrics`**
  Type: `boolean`. Optional. Default: `false`.
  Whether to count the open connections to each target by the name that clients set with
  `CLIENT SETNAME`. If true, the Collector runs `CLIENT LIST` at each collection and reports
  `redis.clients.connection.count`, counting connections without a name as `unknown`. If false,
  the Collector doesn't run `CLIENT LIST`. The `CLIENT LIST` reply grows with the number of
  connections. Targets that the Collector finds by annotation use the `collect_client_metrics`
  setting in their annotations instead.

* **`keys`**
  Type: `array of string`. Optional. Default: `[]`.
  Keys whose lengths the Collector reports as `redis.key.length`. Each entry is a key name or a
  glob pattern. An entry that contains `*`, `?`, or `[` without a preceding backslash is a glob
  pattern. The length is the number of elements in a list, set, sorted set, hash, or stream, and
  `1` for a string. Each collection reads every listed key in every database that holds keys, or
  only in `db` when it's set. A glob pattern scans every key in each database that the Collector
  reads, so its cost grows with the number of keys on the server. When the reads don't finish
  within `timeout`, that collection reports no key lengths. A listed key that has no elements in
  any database reports `0`. Targets that the Collector finds by annotation use the `keys`
  setting in their annotations instead.

* **`db`**
  Type: `integer`. Optional. Minimum: `0`.
  Number of the database to read `keys` from. If omitted, the Collector reads every database
  that holds keys. If this database holds no keys, the Collector reports no key lengths. Only
  `keys` uses this setting, because every other metric covers the whole server.

* **`warn_on_missing_keys`**
  Type: `boolean`. Optional. Default: `true`.
  Whether to log a warning for each entry in `keys` that has no elements in any database that
  the Collector reads. If true, the Collector logs the warning at each collection. If false, the
  Collector reports a length of `0` for the entry without logging a warning.

* **`tls`**
  Type: `object`. Optional.
  TLS settings for connections to static targets and targets that the Collector finds by label.
  TLS is on when `insecure` is `false` or the block sets `ca_file` or `ca_pem`. With TLS on, the
  Collector verifies the server certificate unless `insecure_skip_verify` is `true`. Targets
  that the Collector finds by annotation use the TLS settings in their annotations instead.

* **`tls.ca_file`**
  Type: `string`. Optional.
  Path to a PEM-encoded certificate authority (CA) certificate file used to verify the Redis
  server certificate. If omitted, the Collector uses the system certificate authority pool.

* **`tls.ca_pem`**
  Type: `string`. Optional.
  PEM-encoded certificate authority certificate content used to verify the Redis server
  certificate.

* **`tls.cert_file`**
  Type: `string`. Optional.
  Path to the PEM-encoded client certificate file to present to the Redis server. A Redis server
  with TLS enabled requires a client certificate unless its `tls-auth-clients` setting is `no`
  or `optional`.

* **`tls.cert_pem`**
  Type: `string`. Optional.
  PEM-encoded client certificate content to present to the Redis server, in place of
  `cert_file`.

* **`tls.cipher_suites`**
  Type: `array of string`. Optional.
  TLS 1.0 through 1.2 cipher suites that the Collector can use. The order of the list doesn't
  matter, and TLS 1.3 cipher suites aren't configurable. If omitted, the Collector uses the
  secure defaults from the Go TLS library. For supported names, see
  [https://go.dev/src/crypto/tls/cipher\_suites.go](https://go.dev/src/crypto/tls/cipher_suites.go).

* **`tls.curve_preferences`**
  Type: `array of string`. Optional.
  Key exchange mechanisms that the Collector can use in the TLS handshake: the elliptic curves
  `P256`, `P384`, `P521`, and `X25519`, and `X25519MLKEM768`, a hybrid post-quantum key
  exchange. The order of the list doesn't matter: the Collector chooses among the listed
  mechanisms by its own preference. If omitted, the Collector uses the Go TLS library defaults.

* **`tls.include_system_ca_certs_pool`**
  Type: `boolean`. Optional.
  Whether to add certificates from the system certificate authority pool to the configured
  certificate authorities. If true, the Collector trusts both sources. If false, the Collector
  trusts only the configured certificate authorities.

* **`tls.insecure`**
  Type: `boolean`. Optional. Default: `true`.
  Whether to connect to Redis without TLS. If true and neither `ca_file` nor `ca_pem` is set,
  the Collector uses an unencrypted connection. If false, or if `ca_file` or `ca_pem` is set,
  the Collector connects over TLS.

* **`tls.insecure_skip_verify`**
  Type: `boolean`. Optional.
  Whether to skip verification of the Redis server certificate. If true, the connection is
  encrypted but isn't authenticated and is vulnerable to machine-in-the-middle attacks. If
  false, the Collector verifies the certificate. Applies only when TLS is on.

* **`tls.key_file`**
  Type: `string`. Optional.
  Path to the PEM-encoded client private key file used with `cert_file` for mutual TLS
  authentication.

* **`tls.key_pem`**
  Type: `string`. Optional.
  PEM-encoded client private key content used with `cert_pem` for mutual TLS authentication.

* **`tls.max_version`**
  Type: `string`. Optional.
  Maximum TLS protocol version the Collector can use. If omitted, the Collector uses the maximum
  version supported by the Go TLS library.

* **`tls.min_version`**
  Type: `string`. Optional.
  Minimum TLS protocol version the Collector can use. If omitted, the minimum version is TLS
  1.2.

* **`tls.reload_interval`**
  Type: `duration`. Optional.
  How often the Collector reloads certificate and key files. If omitted, the Collector doesn't
  reload the files.

* **`tls.server_name_override`**
  Type: `string`. Optional.
  Server name to verify in the Redis server certificate instead of the endpoint hostname. Use
  this setting when the certificate name differs from the endpoint hostname.

* **`tls.tpm`**
  Type: `object`. Optional.
  Trusted platform module settings for the TLS private key.

* **`tls.tpm.auth`**
  Type: `string`. Optional.
  Authorization value for the trusted platform module key.

* **`tls.tpm.enabled`**
  Type: `boolean`. Optional.
  Whether to use a trusted platform module for the TLS private key. If true, the Collector loads
  the key from the configured device or socket. If false, the Collector uses the configured key
  file or in-memory key.

* **`tls.tpm.owner_auth`**
  Type: `string`. Optional.
  Owner authorization value for the trusted platform module.

* **`tls.tpm.path`**
  Type: `string`. Optional.
  Path to the trusted platform module device or Unix domain socket, such as `/dev/tpm0` or
  `/dev/tpmrm0`.


## Related topics

- [Azure metrics available in Palo Alto Networks Cortex XCOR](https://docs-xcor.paloaltonetworks.com/ingest/xcor/integrations/server/azure/azure-metrics.md)
- [CXDOT Collector integrations](https://docs-xcor.paloaltonetworks.com/ingest/xcor/integrations/collector.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.