Skip to content

Azure Cache for Redis Integration

This recipe shows how to integrate Azure Cache for Redis with a Node.js Express application for session storage and data caching.

Overview

Redis is an in-memory data store frequently used as a cache or session provider. On Azure App Service, a shared session state (via Redis) is required if you are using multiple instances (scale-out) or need persistent sessions during redeployments.

Architecture

flowchart TD
    Client[Client] --> App[App Service]
    App --> Redis[Azure Cache for Redis]
    App -.-> MI[Managed Identity]
    MI -.-> Entra[Microsoft Entra ID]

How to read this diagram: Solid arrows show runtime data flow. Dashed arrows show identity and authentication.

Prerequisites

  • Azure Cache for Redis instance
  • Azure App Service with Node.js
  • Access key or connection string for the Redis instance

Implementation

1. Install Dependencies

npm install ioredis express-session connect-redis

2. Basic Redis Setup

const Redis = require('ioredis');

// Connect using REDIS_CONNECTION_STRING from App Service configuration
const redisClient = new Redis(process.env.REDIS_CONNECTION_STRING, {
  tls: {
    // Azure Cache for Redis uses valid TLS certificates;
    // the default (rejectUnauthorized: true) is correct and secure.
  },
  // Ensure the connection is kept alive
  keepAlive: 1000,
  retryStrategy: (times) => Math.min(times * 50, 2000)
});

redisClient.on('error', (err) => console.error('Redis Client Error', err));

module.exports = redisClient;

3. Session Storage with express-session

const express = require('express');
const session = require('express-session');
const RedisStore = require('connect-redis').default;
const redisClient = require('./redis-client');

const app = express();

app.use(session({
  store: new RedisStore({ client: redisClient }),
  secret: process.env.SESSION_SECRET || 'keyboard cat',
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: true, // Recommended for App Service (HTTPS by default)
    httpOnly: true,
    maxAge: 86400000 // 1 day
  }
}));

4. Caching Patterns

async function getCachedData(key, fetchFn) {
  const cachedValue = await redisClient.get(key);
  if (cachedValue) {
    return JSON.parse(cachedValue);
  }

  const freshData = await fetchFn();
  await redisClient.set(key, JSON.stringify(freshData), 'EX', 3600); // 1-hour expiration
  return freshData;
}

Verification

Test the integration by logging session data or reading/writing to Redis:

# Set environment variables
az webapp config appsettings set --name $APP_NAME --resource-group $RG --settings REDIS_CONNECTION_STRING="rediss://:<key>@<host>:6380" SESSION_SECRET="super-secret" --output json
Flag Description
--name $APP_NAME Targets the web app that should receive the Redis configuration.
--resource-group $RG Identifies the resource group that contains the web app.
--settings REDIS_CONNECTION_STRING="rediss://:<key>@<host>:6380" SESSION_SECRET="super-secret" Writes the TLS Redis connection string and the session-signing secret into App Service app settings.
--output json Returns the updated app-settings payload as JSON.

Troubleshooting

  • Connection Refused (6380): Ensure you are using rediss:// (with an extra 's') to specify SSL/TLS connection.
  • Session Loss: If your app scales to multiple instances, ensure all instances point to the same Redis instance for session state.
  • Performance: Monitor Redis metrics in the Azure Portal. High latency might indicate a need for a larger Redis SKU or colocating your Redis and App Service in the same region.

Advanced Topics

Run It in the Portal

Portal view: Identity blade (optional Microsoft Entra authentication path)

Identity blade for the `app-test-20251107` Web App showing tabs "System assigned" (selected) and "User assigned". The System assigned panel begins with the description "A system assigned managed identity is restricted to one per resource and is tied to the lifecycle of this resource. You can grant permissions to the managed identity by using Azure role-based access control (Azure RBAC). The managed identity is authenticated with Microsoft Entra ID, so you don't have to store any credentials in code." A command bar with Save, Discard, Refresh, Troubleshoot, and "Got feedback?" sits above a single Status toggle set to "Off" (Off/On) — no Object (principal) ID or Permissions section is shown because the identity is not yet enabled. The left navigation shows Identity selected under the Settings group.

The Identity blade visible here is relevant only if you switch this recipe from the default REDIS_CONNECTION_STRING key-based flow to a Microsoft Entra-authenticated Redis connection. In the visible pre-enable state, System assigned is selected and Status is still Off; turning it On is the Portal step that creates the app identity before any Redis-side Entra mapping can be granted. For the recipe's default flow, keep using the REDIS_CONNECTION_STRING app setting with the ioredis new Redis(process.env.REDIS_CONNECTION_STRING, {...}) configuration shown above.

See Also

Sources