{
  "schema_version": 2,
  "id": "operate/iris/lens/self-managed/operations",
  "title": "Operate self-managed Lens",
  "url": "https://redis.io/docs/latest/operate/iris/lens/self-managed/operations/",
  "summary": "Check health, watch the records database, change retention, connect the console, back up, upgrade, uninstall, and troubleshoot Lens.",
  "tags": [
    "docs",
    "operate",
    "iris"
  ],
  "last_updated": "2026-11-04T01:09:56+02:00",
  "page_type": "content",
  "content_hash": "ca5c2a5bcde68fccb5dac9ec54ff5e315e893609416db9e8af93ceb03de1db26",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "This page covers routine checks and maintenance for self-managed Lens after you [deploy it](https://redis.io/docs/latest/operate/iris/lens/self-managed/deploy). The examples port-forward the data plane to `localhost:9000` and the control plane to `localhost:9300`."
    },
    {
      "id": "check-service-health",
      "title": "Check service health",
      "role": "content",
      "text": "The data plane, worker, and control plane answer `/health/liveness` and `/health/readiness` without a credential:\n\n[code example]\n\nThe worker has no Service. Check it with `kubectl -n <namespace-name> get pods -l app.kubernetes.io/instance=lens`. With `tests.enabled=true`, `helm test lens -n <namespace-name>` runs the readiness checks."
    },
    {
      "id": "watch-the-records-database",
      "title": "Watch the records database",
      "role": "content",
      "text": "Nothing trims the span streams yet, and the `streams` role must use `noeviction`. While ingest is on, the records database grows without bound. Watch its memory, and add memory before it fills. When it fills, writes fail rather than evicting data.\n\nTo stop growth, set `ingest.enabled=false` and run `helm upgrade`. Agents then get `503` and retry, and reads keep working."
    },
    {
      "id": "change-retention",
      "title": "Change retention",
      "role": "content",
      "text": "Read the instance and its current retention with the admin token:\n\n[code example]\n\nRetention lives in two places, so change both together:\n\n1. Set the new windows in `instance.retention` in `lens-values.yaml`, and run `helm upgrade`. The data plane stamps content expiry from `contentTTL` as rendered here.\n1. Send the same windows, in seconds, to the control plane. A supplied `retention` replaces the stored one, so include all three fields:\n\n    [code example]\n\nThe windows must satisfy `streamTrimSeconds` < `contentTtlSeconds` ≤ `indexRetentionSeconds`. The control plane records `instance.retention` only when it creates the instance, so `helm upgrade` never changes what the instance record reports."
    },
    {
      "id": "connect-the-console",
      "title": "Connect the console",
      "role": "content",
      "text": "The Iris console reads Lens through its gateway, which forwards to the data-plane Service root. Add a `lens` entry to the console gateway's `products`, with `instanceId` set to your `instance.id`:\n\n[code example]\n\n\n\nWithout sign-in, the console asks each reader for a read key. With [operator sign-in](https://redis.io/docs/latest/operate/iris/lens/self-managed/authentication#operator-sign-in), it uses the operator's IdP token."
    },
    {
      "id": "update-secrets",
      "title": "Update Secrets",
      "role": "content",
      "text": "When you change a Secret's content, update its `existingSecretChecksum` in the values and run `helm upgrade`, so the pods roll and read it. This applies to the storage, license, CA bundle, and token Secrets. For the tokens both releases share, see [Rotate credentials](https://redis.io/docs/latest/operate/iris/lens/self-managed/authentication#rotate-credentials)."
    },
    {
      "id": "back-up-the-deployment",
      "title": "Back up the deployment",
      "role": "content",
      "text": "Back up the metadata Redis, which holds the instance record, and the records and content databases, which hold your agents' turns. Back up the Identity Service's metadata too, so API keys survive a restore. Keep the Secrets and values files in your secret store and source control."
    },
    {
      "id": "upgrade-the-chart",
      "title": "Upgrade the chart",
      "role": "content",
      "text": "[code example]\n\nThe admin token and instance survive upgrades. Check readiness afterward. If you turned on operator sign-in, the upgrade notes repeat the audience that IdP tokens must carry."
    },
    {
      "id": "uninstall-the-chart",
      "title": "Uninstall the chart",
      "role": "content",
      "text": "[code example]\n\nUninstalling doesn't delete the Redis databases, the Secrets you created, or the Identity Service release. The chart keeps the generated admin token Secret, so delete it yourself if you don't plan to reinstall. Revoke the Lens API keys on the Identity Service."
    },
    {
      "id": "troubleshooting",
      "title": "Troubleshooting",
      "role": "errors",
      "text": "| Symptom | Likely cause and fix |\n| --- | --- |\n| Rendering fails with a named message | A required value is missing or invalid. See [Helm values that stop an install](https://redis.io/docs/latest/operate/iris/lens/self-managed/prerequisites#helm-values-that-stop-an-install). |\n| A pod exits with `redis url list is empty` and a role name | The storage Secret omits that role. Add it to the named file and update `storage.existingSecretChecksum`. |\n| Index creation fails with an error naming the records database | The records database is Redis Flex, or lacks Redis Search or Redis JSON. Use a RAM database with both modules. |\n| A pod doesn't start, or readiness stays false | The license is missing, invalid, or in its grace period. Check the license Secret. |\n| Pods report `ImagePullBackOff` | The image tag doesn't exist or the cluster can't reach the registry. Check the tags and `imagePullSecrets`. |\n| Agents get `503` on ingest | `ingest.enabled` is `false`. |\n| API keys fail with `401`, operator tokens work | The data plane can't reach the Identity Service, or its runtime credential doesn't match. Check `dataplane.identityServiceBaseURL`, the shared Secret, and the data-plane logs. |\n| Creating a key fails grant validation | The Identity Service can't reach the control plane, or the internal token doesn't match. Check `productValidation.products.lens.baseURL` and the shared Secret. |\n| An ingest key gets `403` on reads | Expected. Reads need a `read` or `full` key. |\n| Operator tokens fail, API keys work | The data plane can't reach `jwksURI`, or the token's `iss` or `aud` doesn't match `issuer` or `auth.oidc.audience` (`401`). An unmapped role or another tenant gets `403`. |\n| Operator tokens fail right after the IdP rotated its signing keys | The data plane refreshes keys at most once every 30 seconds. Wait and retry. |\n| An operator token gets `403` on ingest | Expected. Ingest always needs an API key. |"
    }
  ],
  "examples": [
    {
      "id": "check-service-health-ex0",
      "language": "bash",
      "code": "curl -sS http://localhost:9000/health/readiness\ncurl -sS http://localhost:9300/health/readiness",
      "section_id": "check-service-health"
    },
    {
      "id": "change-retention-ex0",
      "language": "bash",
      "code": "curl -sS http://localhost:9300/iris/v1beta1/lens/instance \\\n  -H \"Authorization: Bearer $LENS_ADMIN_TOKEN\"",
      "section_id": "change-retention"
    },
    {
      "id": "change-retention-ex1",
      "language": "bash",
      "code": "curl -sS -X PATCH http://localhost:9300/iris/v1beta1/lens/instance \\\n      -H \"Authorization: Bearer $LENS_ADMIN_TOKEN\" \\\n      -H 'Content-Type: application/json' \\\n      -d '{\"retention\":{\"streamTrimSeconds\":86400,\"contentTtlSeconds\":259200,\"indexRetentionSeconds\":1209600}}'",
      "section_id": "change-retention"
    },
    {
      "id": "connect-the-console-ex0",
      "language": "yaml",
      "code": "products:\n  - key: lens\n    label: Lens\n    product: lens\n    authScheme: bearer\n    healthPath: /health/readiness\n    instanceId: default\n    upstream:\n      host: lens-redis-lens-dataplane.<namespace-name>.svc.cluster.local\n      port: 9000\n      basePath: \"\"\n      scheme: http",
      "section_id": "connect-the-console"
    },
    {
      "id": "upgrade-the-chart-ex0",
      "language": "bash",
      "code": "helm repo update redis-ai\nhelm upgrade lens redis-ai/redis-lens \\\n  --version <chart-version> \\\n  --namespace <namespace-name> \\\n  -f lens-values.yaml \\\n  --wait --timeout 5m",
      "section_id": "upgrade-the-chart"
    },
    {
      "id": "uninstall-the-chart-ex0",
      "language": "bash",
      "code": "helm uninstall lens --namespace <namespace-name>",
      "section_id": "uninstall-the-chart"
    }
  ]
}
