---
cuppy_hub: azure
cuppy_path: reference/redis/managed-redis.md
cuppy_section: docs
cuppy_doc: 39J7-4RFF
cuppy_doc_uuid: 29c6f33e-4a5a-4f4b-9845-cc8f3b7c6098
cuppy_permalink: https://cuppy.io/azure/d/39J7-4RFF
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/azure/docs/reference/redis/managed-redis
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: 351a8321ef45634b221090811acfab0ceecf2d4dfcd61eda05fae4c6575323d7
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Azure Managed Redis

## Retirement: move off Azure Cache for Redis

| Azure Cache for Redis tier | Retires | Instances disabled from |
|---|---|---|
| Basic, Standard, Premium | **September 30, 2028** | October 1, 2028 |
| Enterprise, Enterprise Flash | **March 31, 2027** | April 1, 2027 |

The replacement is **Azure Managed Redis**: resource type `Microsoft.Cache/redisEnterprise` (with a `databases/default` child), Redis 7.4, host `<name>.<region>.redis.azure.net`, **port 10000**, TLS 1.2 or 1.3. New work should target it.

## Tiers and clustering

- Tiers (memory : vCPU): **Memory Optimized** 8:1, **Balanced** 4:1, **Compute Optimized** 2:1, **Flash Optimized** (cold keys on NVMe; no Search, Bloom or TimeSeries). SKUs look like `Balanced_B1`, `MemoryOptimized_M10`, `ComputeOptimized_X5`.
- **High availability** (on by default) keeps replicas across zones where available; turning it off loses data on failure: dev/test only.

| `clusteringPolicy` | Clients | Notes |
|---|---|---|
| **`OSSCluster`** (default) | Must be **cluster-aware**: first connection on 10000, then shards on 85xx ports found with `CLUSTER NODES` (don't hard-code them) | Best throughput; multi-key commands need keys in the same hash slot (else `CROSSSLOT`); no RediSearch |
| `EnterpriseCluster` | Any client: one endpoint, a proxy routes | Required for RediSearch; only `DEL`, `MSET`, `MGET`, `EXISTS`, `UNLINK`, `TOUCH` may span slots |
| `NoCluster` | Any client | Caches of 25 GB or less only |

**The policy can't change once it's `OSSCluster` or `EnterpriseCluster`** without deleting the database (only `NoCluster` can change), and not at all with geo-replication.

## Entra authentication

- User name = the **object ID** of the managed identity or service principal; password = a token for `https://redis.azure.com/.default`. **Entra groups aren't supported**; TLS is required; some commands are blocked.
- Grant access with an **access policy assignment** (`accessPolicyName: 'default'`, the only one) per principal, or the portal's **Authentication** blade. Test with the `redisenterprise` CLI extension (not in core CLI): its `test-connection` command with `--auth entra` signs in as your `az login` identity.
- Clients must **re-send `AUTH` with a new token at least three minutes before expiry**, with jitter: `@redis/entraid` does this when configured.
- Then set **`accessKeysAuthentication: 'Disabled'`**. Changing it **drops every existing connection**, Entra ones included; geo-replicated caches must be unlinked first.

## Bicep

```bicep
// Azure Managed Redis (Balanced B1) with access keys off and Entra access for an app identity
param location string = resourceGroup().location
param name string
param appPrincipalId string // object (principal) ID of the app's managed identity

resource cluster 'Microsoft.Cache/redisEnterprise@2025-07-01' = {
  name: name
  location: location
  sku: {
    name: 'Balanced_B1'
  }
  properties: {
    minimumTlsVersion: '1.2'
    publicNetworkAccess: 'Disabled' // required in this API version; reach it through a private endpoint
    highAvailability: 'Enabled' // Disabled is for dev/test only: no replication
  }
}

resource db 'Microsoft.Cache/redisEnterprise/databases@2025-07-01' = {
  parent: cluster
  name: 'default'
  properties: {
    clientProtocol: 'Encrypted'
    port: 10000
    clusteringPolicy: 'OSSCluster' // the default; changing OSS or Enterprise later means deleting the database
    evictionPolicy: 'VolatileLRU'
    accessKeysAuthentication: 'Disabled'
  }
}

resource appAccess 'Microsoft.Cache/redisEnterprise/databases/accessPolicyAssignments@2025-07-01' = {
  parent: db
  name: 'app${uniqueString(appPrincipalId)}'
  properties: {
    accessPolicyName: 'default' // the only policy supported
    user: {
      objectId: appPrincipalId
    }
  }
}

output endpoint string = '${cluster.properties.hostName}:10000'
```

`publicNetworkAccess` is **required** on create in API 2025-07-01 (Bicep warns BCP035 without it). Private endpoint: `groupId` `redisEnterprise`, zone `privatelink.redis.azure.net`.

## Node.js (node-redis 6 with Entra)

```ts
import { isIP } from "node:net";
import { DefaultAzureCredential } from "@azure/identity";
import { EntraIdCredentialsProviderFactory, REDIS_SCOPE_DEFAULT } from "@redis/entraid";
import { createCluster } from "redis";

// REDIS_ENDPOINT looks like "<name>.<region>.redis.azure.net:10000"
const endpoint = process.env.REDIS_ENDPOINT ?? "";
const [host] = endpoint.split(":");

const credentialsProvider = EntraIdCredentialsProviderFactory.createForDefaultAzureCredential({
  credential: new DefaultAzureCredential(),
  scopes: REDIS_SCOPE_DEFAULT, // https://redis.azure.com/.default
  tokenManagerConfig: { expirationRefreshRatio: 0.8 }, // re-authenticate before the token expires
});

// OSSCluster (the default clustering policy) needs a cluster-aware client.
export const redis = createCluster({
  rootNodes: [{ url: `rediss://${endpoint}` }],
  defaults: { credentialsProvider, socket: { tls: true, connectTimeout: 15_000 } },
  // Shards announce IP addresses; map them back to the host name so TLS validation passes.
  nodeAddressMap(address: string) {
    const [h, port] = address.split(":");
    return { host: isIP(h ?? "") !== 0 ? host ?? "" : h ?? "", port: Number(port) };
  },
});

export async function main(): Promise<void> {
  redis.on("error", (e) => console.error("redis", e));
  await redis.connect();
  await redis.set("greeting", "hello", { EX: 60 });
  console.log(await redis.get("greeting"));
  await redis.close();
}
```

For `EnterpriseCluster` or `NoCluster`, use `createClient({ url, credentialsProvider, socket })` instead of `createCluster`. Microsoft's sample maps shard addresses back to the host name with `nodeAddressMap`; the hub's reading is that without it an OSS-cluster client connects to shard IPs and TLS host-name checks fail.


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 107 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/azure/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
