✓Azure subscription, Azure CLI installed (version 2.40+), basic knowledge of Redis data structures, familiarity with a programming language (C# or Python), understanding of caching concepts.
✦ Definition~90s read
What is Microsoft Azure?
Microsoft Azure — Azure Cache for Redis is a core Azure service that handles cache redis in the Microsoft cloud ecosystem.
Azure is Microsoft's cloud computing platform offering over 200 services. This article covers azure cache for redis with production-ready configurations, best practices, and hands-on examples.
Why Azure Cache for Redis?
In production, every millisecond of latency and every database query counts. Azure Cache for Redis provides an in-memory data store that offloads backend databases, reduces latency, and handles high-throughput workloads. It's not just a cache—it's a distributed, low-latency key-value store that supports data structures like lists, sets, sorted sets, and streams. For DevOps engineers, it's a critical component for scaling applications without rewriting architecture. Common use cases include session stores, API response caching, real-time leaderboards, and message brokering via Redis Pub/Sub. Azure manages the infrastructure, patching, and high availability, but you still need to configure it correctly to avoid pitfalls like data loss, connection storms, and memory pressure. This section sets the stage: understand the 'why' before the 'how'.
Standard SKU offers 99.9% SLA with replication. For production, never use Basic (no SLA, no replication). Premium adds data persistence, clustering, and zone redundancy.
📊 Production Insight
We once saw a team use Basic tier for a production session store. A node reboot wiped all sessions, causing a full logout storm. Always use Standard or Premium for production.
🎯 Key Takeaway
Azure Cache for Redis is a managed in-memory store that reduces latency and database load, but requires proper SKU and configuration for production.
Connection Management and Retry Logic
Connecting to Redis from your application is straightforward, but naive connection code will fail under load. Azure Cache for Redis uses TLS on port 6380 (recommended) or non-TLS on 6379. Use StackExchange.Redis (C#) or redis-py (Python) with connection multiplexing—one connection shared across threads. Never create a new connection per request; that exhausts ports and causes timeouts. Implement retry logic with exponential backoff for transient failures like timeouts or connection drops. Azure's load balancer may reset idle connections after 10 minutes, so keep-alive is essential. Also, configure AbortOnConnectFail=false to avoid crashing on startup if Redis is temporarily unreachable. This section provides production-ready connection code.
// No direct output; connection is established on first use.
⚠ Don't Leak Connections
Each ConnectionMultiplexer instance uses a TCP socket. Creating one per request will exhaust ephemeral ports. Always use a singleton or Lazy<T> pattern.
📊 Production Insight
In a production incident, a misconfigured connection pool caused port exhaustion on the app server. The fix: switch to multiplexing and reduce idle timeout. Monitor connection counts with netstat.
🎯 Key Takeaway
Use a single, multiplexed connection with retry logic and AbortOnConnectFail=false to handle transient failures gracefully.
Data Expiration and Eviction Policies
Redis is memory-bound. Without an eviction policy, writes fail when memory is full. Azure Cache for Redis defaults to volatile-lru, which evicts keys with TTL set. For production, choose a policy that matches your use case: allkeys-lru for general caching, allkeys-lfu for hot-key protection, or noeviction for critical data (but then you must monitor memory). Set TTL on all cache entries to prevent stale data and allow eviction to work. Use maxmemory-reserved to reserve memory for system operations—Azure recommends 10% of maxmemory. This section explains policies and shows how to set them via Azure CLI or portal. Also, use the INFO command to monitor evictions and memory usage.
set-eviction.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Set eviction policy and reserved memory via AzureCLI
az redis update \
--name myCache \
--resource-group myResourceGroup \
--set redisConfiguration.maxmemory-policy="allkeys-lru" \
--set redisConfiguration.maxmemory-reserved="100"
# Verify with redis-cli
redis-cli -h myCache.redis.cache.windows.net -p 6380 -a <access-key> --tls CONFIGGET maxmemory-policy
# Output: 1) "maxmemory-policy"2) "allkeys-lru"
# Monitor evictions
redis-cli -h myCache.redis.cache.windows.net -p 6380 -a <access-key> --tls INFO stats | grep evicted_keys
# Output: evicted_keys:0
Output
{
"evicted_keys": 0
}
💡Set TTL on Everything
Without TTL, keys live forever. Even with LRU, old data may persist. Always set an expiration (e.g., 3600 seconds) unless the data must never expire.
📊 Production Insight
A client used noeviction and hit memory limit. Writes failed, causing cascading failures. We switched to allkeys-lru and added monitoring on used_memory. Now we get alerts at 80% usage.
🎯 Key Takeaway
Choose an eviction policy that matches your data access pattern and always set TTL to control memory usage and data freshness.
Caching Strategies: Cache-Aside, Read-Through, and Write-Through
The most common caching pattern is cache-aside: on a read, check cache first; on miss, load from database and populate cache. For writes, update database and invalidate cache (or update cache). This pattern is simple and works for most apps. Read-through and write-through are less common because they require custom logic in the cache library. Azure Cache for Redis doesn't natively support these; you implement them in your application. For high consistency, consider write-through (update cache synchronously on write) but beware of increased write latency. For eventual consistency, cache-aside with TTL is sufficient. This section shows a cache-aside implementation in Python with retry and TTL. Also discuss stampeding herd problem and how to mitigate with locking or early recomputation.
cache_aside.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import redis
import json
import time
r = redis.Redis(
host='myCache.redis.cache.windows.net',
port=6380,
password='your-access-key',
ssl=True,
socket_connect_timeout=5,
socket_timeout=5,
retry_on_timeout=True,
health_check_interval=30
)
defget_user(user_id):
cache_key = f"user:{user_id}"# Try cache
cached = r.get(cache_key)
if cached:
return json.loads(cached)
# Cache miss: load from DB (simulated)
user = query_database(user_id)
if user:
# Set with TTL 1 hour
r.setex(cache_key, 3600, json.dumps(user))
return user
defquery_database(user_id):
# Simulate DB call
time.sleep(0.1)
return {"id": user_id, "name": "Alice"}
# Usage
user = get_user(42)
print(user)
Output
{'id': 42, 'name': 'Alice'}
⚠ Stampeding Herd
When a popular key expires, multiple requests may hit the database simultaneously. Mitigate with locking (SETNX) or early recomputation (refresh before TTL ends).
📊 Production Insight
During a flash sale, a hot key expired and 10k requests hit the DB. We added a distributed lock (Redis SETNX) so only one request recomputes the cache. Response times dropped from 5s to 10ms.
🎯 Key Takeaway
Cache-aside is the simplest and most reliable pattern; implement it with TTL and handle cache misses gracefully to avoid database overload.
High Availability and Failover with Replication
Azure Cache for Redis Standard and Premium tiers provide a primary-replica pair. On primary failure, Azure automatically promotes the replica. However, this failover is not instantaneous—it can take 10-30 seconds. During that time, writes fail and reads may return stale data (if using replica reads). Your application must handle these transient errors with retry logic. Also, after failover, the new primary may have a cold cache (if persistence is not enabled). For Premium tier, you can enable data persistence (RDB or AOF) to minimize data loss. This section explains the failover process, how to test it (via Azure portal reboot), and how to configure your app to reconnect gracefully. Also discuss connection string changes: the endpoint remains the same, but the underlying IP changes.
// No direct output; connection is resilient to failover.
🔥Test Failover Regularly
Azure portal allows you to reboot a node to simulate failover. Do this in non-production to verify your app's behavior. Monitor connection errors and recovery time.
📊 Production Insight
We scheduled a failover test and discovered our app's connection pool didn't recover. The fix: implement a health check and reconnect logic. Now we run failover tests quarterly.
🎯 Key Takeaway
Standard/Premium tiers provide automatic failover, but your app must handle transient errors and reconnect gracefully.
Monitoring and Alerting with Azure Metrics and Insights
You can't fix what you don't measure. Azure Cache for Redis exposes metrics via Azure Monitor: cache hits/misses, evicted keys, server load, memory usage, connected clients, and operations per second. Set up alerts for high memory usage (>80%), high evictions (>0), and server load (>80%). Also use Redis's INFO command for deeper diagnostics: keyspace hits/misses, connected clients, and replication lag. For Premium tier, enable Redis Insights for slow log and latency monitoring. This section shows how to configure alerts via Azure CLI and how to query metrics programmatically. Also discuss using Application Insights to correlate Redis performance with application performance.
setup-alerts.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Create metric alert for high memory usage
az monitor metrics alert create \
--name "RedisHighMemory" \
--resource-group myResourceGroup \
--scopes /subscriptions/.../resourceGroups/myResourceGroup/providers/Microsoft.Cache/Redis/myCache \
--condition "used_memory_percentage > 80" \
--description "Alert when Redis memory usage exceeds 80%" \
--evaluation-frequency 5m \
--window-size 15m \
--severity 2 \
--action-groups /subscriptions/.../resourceGroups/myResourceGroup/providers/microsoft.insights/actionGroups/myActionGroup
# Query cache hits ratio
az monitor metrics list \
--resource /subscriptions/.../resourceGroups/myResourceGroup/providers/Microsoft.Cache/Redis/myCache \
--metric "cachehits""cachemisses" \
--interval PT5M \
--output table
Output
Timestamp CacheHits CacheMisses
----------------- ---------- -----------
2026-07-12T10:00Z 1500 50
2026-07-12T10:05Z 1600 45
💡Set Up Action Groups
Action groups define who gets notified (email, SMS, webhook). Create one before setting alerts. Use webhooks to trigger auto-scaling or incident response.
📊 Production Insight
A sudden spike in evictions indicated a misconfigured TTL. We added an alert on evicted_keys > 0 and caught it early. Now we review eviction trends weekly.
🎯 Key Takeaway
Monitor cache hits, memory, and evictions. Set alerts for high memory and evictions to prevent performance degradation.
Scaling and Clustering for High Throughput
When a single Redis instance isn't enough, scale up (larger SKU) or scale out (clustering). Azure Cache for Redis Premium tier supports clustering, which shards data across multiple nodes using hash slots. This increases throughput linearly with shard count. However, clustering has limitations: multi-key operations (e.g., transactions, unions) only work if keys are in the same slot. Use hash tags to force related keys into the same slot. Scaling a cluster requires careful planning—Azure supports scaling up/down and adding/removing shards, but it's a long-running operation with potential data movement. This section explains how to enable clustering, choose shard count, and handle slot migration. Also discuss geo-replication for cross-region disaster recovery.
enable-clustering.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Create a Premium cluster with 3 shards
az redis create \
--resource-group myResourceGroup \
--name myClusterCache \
--location eastus \
--sku Premium \
--vm-size P1 \
--shard-count 3 \
--redis-configuration "cluster-enabled true"
# Scale cluster to 5shards (update operation)
az redis update \
--name myClusterCache \
--resource-group myResourceGroup \
--set shardCount=5
# Connect to cluster with redis-cli (use -c for cluster mode)
redis-cli -h myClusterCache.redis.cache.windows.net -p 6380 -a <access-key> --tls -c SET user:123"Alice"
# Output: OK
redis-cli -h myClusterCache.redis.cache.windows.net -p 6380 -a <access-key> --tls -c GET user:123
# Output: "Alice"
Output
OK
"Alice"
⚠ Multi-Key Operations in Clusters
Operations like SUNION or transactions fail if keys are on different shards. Use hash tags (e.g., {user:123}.name) to co-locate keys. Test your application with clustering enabled.
📊 Production Insight
We migrated a monolithic Redis to a 6-shard cluster. Initially, many operations failed due to cross-slot keys. We refactored to use hash tags and saw 5x throughput improvement.
🎯 Key Takeaway
Clustering scales throughput linearly but requires application awareness of sharding. Use hash tags for multi-key operations.
Security: Access Keys, Firewall, and VNet Integration
Azure Cache for Redis uses access keys for authentication. Rotate them regularly and store them in Azure Key Vault, not in code. For network security, use firewall rules to restrict access to specific IP ranges or Azure services. For highest security, use VNet injection (Premium tier) to place the cache in your virtual network, accessible only from within the VNet. This prevents exposure to the public internet. Also enable TLS 1.2+ and disable non-SSL port. This section shows how to configure firewall rules and VNet integration via CLI. Discuss managed identity for passwordless access (preview). Also cover auditing via Azure Activity Logs.
secure-redis.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Add firewall rule to allow only your app's IP
az redis firewall-rules create \
--resource-group myResourceGroup \
--name myCache \
--rule-name allowAppIP \
--start-ip 203.0.113.1 \
--end-ip 203.0.113.1
# EnableVNetintegration (requires PremiumSKU and existing subnet)
az redis update \
--name myCache \
--resource-group myResourceGroup \
--set subnet.id="/subscriptions/.../resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVNet/subnets/mySubnet" \
--set static-ip="10.0.0.4"
# Rotate access key
az redis regenerate-key \
--name myCache \
--resource-group myResourceGroup \
--key-type Primary
# Store key in KeyVault
az keyvault secret set \
--vault-name myVault \
--name RedisPrimaryKey \
--value $(az redis list-keys --name myCache --resource-group myResourceGroup --query primaryKey -o tsv)
Output
{
"primaryKey": "new-key-value",
"secondaryKey": "old-key-value"
}
🔥Use Managed Identity (Preview)
Azure Cache for Redis now supports managed identity for authentication. This eliminates the need for access keys in code. Check Azure updates for availability in your region.
📊 Production Insight
A compromised access key led to data exfiltration. We now enforce VNet injection for all production caches and rotate keys every 90 days. Audit logs helped trace the breach.
🎯 Key Takeaway
Secure Redis with firewall rules, VNet injection, and key rotation. Store keys in Key Vault and use managed identity when possible.
Performance Tuning: Pipelining, Batching, and Compression
To maximize throughput, use pipelining to send multiple commands without waiting for each response. StackExchange.Redis supports this natively via async operations. For bulk data loads, use batching (e.g., MSET) instead of individual SETs. Also compress large values (e.g., JSON) before storing to reduce memory and network overhead. Use Redis's built-in compression? No—compress client-side with GZip or Snappy. This section provides code for pipelining and compression. Also discuss connection tuning: increase sync timeout for slow operations, but avoid long timeouts that mask issues. Use the SLOWLOG command to identify slow commands.
pipeline_compress.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import redis
import json
import gzip
r = redis.Redis(
host='myCache.redis.cache.windows.net',
port=6380,
password='your-access-key',
ssl=True,
socket_connect_timeout=5,
socket_timeout=5,
retry_on_timeout=True,
health_check_interval=30
)
defcompress_data(data):
return gzip.compress(json.dumps(data).encode('utf-8'))
defdecompress_data(compressed):
return json.loads(gzip.decompress(compressed).decode('utf-8'))
# Pipeline example
pipe = r.pipeline()
for i inrange(1000):
pipe.setex(f"key:{i}", 3600, compress_data({"index": i, "value": "x" * 100}))
pipe.execute() # Sends all commands at once# Retrieve with pipeline
pipe = r.pipeline()
for i inrange(1000):
pipe.get(f"key:{i}")
results = pipe.execute()
for compressed in results:
data = decompress_data(compressed)
# process dataprint("Done")
Output
Done
💡Compress Large Values
Compression reduces memory and network usage. Test with your data: GZip may add CPU overhead. For very large values, consider storing them in blob storage with a Redis pointer.
📊 Production Insight
We reduced Redis memory usage by 60% by compressing JSON payloads. The CPU overhead was negligible. Pipelining cut latency for bulk operations by 10x.
🎯 Key Takeaway
Use pipelining and batching to reduce round trips, and compress large values to save memory and bandwidth.
Disaster Recovery and Geo-Replication
For cross-region disaster recovery, Azure Cache for Redis Premium offers geo-replication, linking two caches as primary and secondary. Data is asynchronously replicated. On regional failure, you can promote the secondary to primary. However, geo-replication has limitations: no clustering support, and failover is manual (or automated with custom scripts). Also, data loss is possible due to async replication. This section explains how to set up geo-replication via CLI and how to handle failover. Discuss backup and restore options: RDB persistence for point-in-time recovery, and export/import for manual backup. For critical data, combine geo-replication with periodic exports to blob storage.
geo-replication.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Create primary cache in EastUS
az redis create --resource-group myResourceGroup --name primaryCache --location eastus --sku Premium --vm-size P1
# Create secondary cache in WestUS
az redis create --resource-group myResourceGroup --name secondaryCache --location westus --sku Premium --vm-size P1
# Link secondary to primary
az redis link create \
--resource-group myResourceGroup \
--name primaryCache \
--server-to-link secondaryCache \
--replication-role Secondary
# Promote secondary to primary (manual failover)
az redis link delete \
--resource-group myResourceGroup \
--name primaryCache \
--server-to-link secondaryCache
# Then update application connection string to secondaryCache
# ExportRDB backup
az redis export \
--resource-group myResourceGroup \
--name primaryCache \
--container "https://mystorageaccount.blob.core.windows.net/backups" \
--prefix "redis-backup" \
--format rdb
Data loss is possible on failover. For critical data, combine with periodic RDB exports. Test failover procedures regularly.
📊 Production Insight
During a regional outage, our geo-replicated cache failed over with 5 minutes of data loss. We now run hourly RDB exports to blob storage and have automated failover scripts.
🎯 Key Takeaway
Geo-replication provides cross-region DR but is async. Use RDB exports for additional safety and test failover processes.
Common Pitfalls and Production Anti-Patterns
Even experienced teams make mistakes. Common pitfalls include: using Redis as a primary database (data loss on failover), storing large objects without compression, ignoring eviction metrics, using too many connections, and not setting TTL. Also, avoid using Redis for complex queries—it's a key-value store, not a relational database. Another anti-pattern is using Redis for transient data that can be regenerated (e.g., computed results) without TTL. This section lists the top 5 anti-patterns with real-world examples and how to fix them. Also discuss the danger of using KEYS command in production (blocking). Use SCAN instead. Finally, emphasize that Redis is not a message queue replacement for high durability—use Azure Service Bus or Event Hubs for that.
avoid-keys.shBASH
1
2
3
4
5
# Bad: KEYS blocks the server
redis-cli -h myCache.redis.cache.windows.net -p 6380 -a <access-key> --tls KEYS user:*
# Good: SCAN is non-blocking
redis-cli -h myCache.redis.cache.windows.net -p 6380 -a <access-key> --tls SCAN0MATCH user:* COUNT100
# Output: 1) "0"2) (empty list or set of keys)
Output
1) "0"
2) (empty list or set of keys)
⚠ Don't Use KEYS in Production
KEYS scans all keys and blocks Redis. Use SCAN with a cursor for iteration. For counting, use DBSIZE or INFO keyspace.
📊 Production Insight
A developer used KEYS on a 10GB cache, blocking writes for 30 seconds. We replaced it with SCAN and added a read-only replica for analytics queries.
🎯 Key Takeaway
Avoid using Redis as a primary database, set TTL on all keys, use SCAN instead of KEYS, and monitor evictions.
Cost Optimization and Right-Sizing
Azure Cache for Redis costs can spiral if not managed. Choose the smallest SKU that meets your throughput and memory needs. Use the Azure Pricing Calculator to estimate costs. For dev/test, use Basic or Standard C0. For production, start with Standard C1 and scale up as needed. Consider reserved instances for 1-3 year terms to save up to 55%. Also, use clustering to scale out instead of scaling up to very large SKUs (which have diminishing returns). Monitor cache metrics to right-size: if server load is below 20%, consider scaling down. If evictions are high, scale up or optimize TTL. This section provides a decision tree for SKU selection and cost-saving tips.
cost-estimate.shBASH
1
2
3
4
5
6
7
8
9
10
# Estimate cost forStandardC1 (1GB) in EastUS
az redis list-skus --location eastus --output table
# Output shows SKU details and prices
# Get current cache metrics for right-sizing
az monitor metrics list \
--resource /subscriptions/.../resourceGroups/myResourceGroup/providers/Microsoft.Cache/Redis/myCache \
--metric "usedmemorypercentage""serverload" \
--interval PT1H \
--output table
If you run Redis 24/7, reserved instances can save 30-55%. Commit to 1 or 3 years. Combine with Azure Hybrid Benefit if you have on-prem licenses.
📊 Production Insight
We were over-provisioned on a P2 SKU with 10% utilization. Downscaled to P1 and saved $500/month. Monitoring server load and evictions guided the decision.
🎯 Key Takeaway
Right-size your cache based on metrics, use reserved instances for savings, and scale out with clustering rather than scaling up indefinitely.
⚙ Quick Reference
12 commands from this guide
File
Command / Code
Purpose
create-redis.sh
az redis create \
Why Azure Cache for Redis?
RedisConnection.cs
using StackExchange.Redis;
Connection Management and Retry Logic
set-eviction.sh
az redis update \
Data Expiration and Eviction Policies
cache_aside.py
r = redis.Redis(
Caching Strategies
FailoverHandling.cs
using StackExchange.Redis;
High Availability and Failover with Replication
setup-alerts.sh
az monitor metrics alert create \
Monitoring and Alerting with Azure Metrics and Insights
enable-clustering.sh
az redis create \
Scaling and Clustering for High Throughput
secure-redis.sh
az redis firewall-rules create \
Security
pipeline_compress.py
r = redis.Redis(
Performance Tuning
geo-replication.sh
az redis create --resource-group myResourceGroup --name primaryCache --location ...
Disaster Recovery and Geo-Replication
avoid-keys.sh
redis-cli -h myCache.redis.cache.windows.net -p 6380 -a --tls KEYS ...
Common Pitfalls and Production Anti-Patterns
cost-estimate.sh
az redis list-skus --location eastus --output table
Cost Optimization and Right-Sizing
Key takeaways
1
Choose the Right Tier
Use Standard or Premium for production; Basic has no SLA and no replication.
2
Set TTL on All Keys
Without expiration, memory fills up and evictions may cause performance issues.
3
Monitor and Alert
Track cache hits, memory usage, and evictions to catch problems early.
4
Secure Your Cache
Use VNet injection, firewall rules, and key rotation to protect data.
FAQ · 6 QUESTIONS
Frequently Asked Questions
01
What is the difference between Basic, Standard, and Premium tiers?
Basic: single node, no SLA, no replication. Standard: two nodes (primary/replica), 99.9% SLA. Premium: adds clustering, data persistence (RDB/AOF), VNet injection, and geo-replication. For production, use Standard or Premium.
Was this helpful?
02
How do I handle Redis failover in my application?
Use a connection library with automatic reconnection (e.g., StackExchange.Redis with AbortOnConnectFail=false). Implement retry logic with exponential backoff. Monitor connection status and reconnect if needed. Test failover by rebooting a node in the Azure portal.
Was this helpful?
03
Can I use Redis as a primary database?
Not recommended. Redis is an in-memory store with limited persistence guarantees. Data can be lost on failover (unless using AOF with fsync). Use it as a cache or for transient data. For durable storage, use a database like Azure SQL or Cosmos DB.
Was this helpful?
04
How do I choose an eviction policy?
For general caching, use allkeys-lru. For hot-key protection, use allkeys-lfu. For data that must never be evicted, use noeviction but monitor memory closely. Always set TTL on keys to allow eviction to work effectively.
Was this helpful?
05
What is the best way to secure Azure Cache for Redis?
Use firewall rules to restrict access, enable TLS 1.2+, disable non-SSL port, and use VNet injection for Premium tier. Store access keys in Azure Key Vault and rotate them regularly. Consider managed identity for passwordless authentication.
Was this helpful?
06
How do I scale Azure Cache for Redis?
Scale vertically by changing SKU (e.g., from C1 to C2). Scale horizontally by enabling clustering (Premium tier) and adding shards. Scaling operations may cause brief downtime or data movement; plan during maintenance windows.