Reduce Azure Cache for Redis costs by 30-55% through right-sizing, reservation commitments, architectural reassessment, and TLS security hardening before the 2028 service retirement.
An MSP managing 30 Azure tenants discovered that 18 of their clients' Redis instances were using less than 40% of provisioned memory -- yet every one was running on Premium tier. After right-sizing and applying reservations, monthly spend dropped from $45,000 to $22,000.
Azure Cache for Redis is one of the most widely deployed caching services on Azure, but it is also one of the most commonly over-provisioned. Organizations select Premium tier "just in case," size instances for peak traffic that occurs a few hours per week, and leave non-SSL ports open because "that's how it was set up."
With Microsoft announcing the retirement of Azure Cache for Redis by 2028 in favour of Azure Managed Redis, there is an urgent window to optimize current spend, harden security, and build a clean baseline for migration.
Most Azure Cache for Redis deployments suffer from one or more of the following cost and security anti-patterns:
This guide provides a systematic approach to each of these problems, with specific Azure CLI commands, cost models, and implementation sequences.
Before optimizing, you need a clear view of what each tier provides and what it costs. The following table summarizes the current Azure Cache for Redis and Azure Managed Redis tiers.
| Tier | Memory Range | Key Features | Status |
|---|---|---|---|
| Basic | 250 MB - 53 GB | Single node, no SLA, dev/test only | Retiring 2028 |
| Standard | 250 MB - 53 GB | Replicated, 99.9% SLA, automatic failover | Retiring 2028 |
| Premium | 6 GB - 120 GB | Clustering, geo-replication, VNET, persistence, zone redundancy | Retiring 2028 |
| Enterprise | 12 GB - 100 GB | Redis Enterprise modules, active geo-replication, 99.999% SLA | Retiring 2028 |
| Enterprise Flash | 300 GB - 4.5 TB | NVMe flash storage, cost-effective large datasets | Retiring 2028 |
| Azure Managed Redis | 1 GB - 4.5 TB+ | Valkey-based, flexible tiers, active geo-replication, modern architecture | GA (Replacement) |
Migration constraint: There is no in-place upgrade path from Azure Cache for Redis to Azure Managed Redis. Migration requires a new resource deployment and data transfer. This makes it even more important to right-size and optimize your current deployment first -- you want to migrate the right workload, not the over-provisioned one.
Right-sizing is the single highest-impact optimization for Azure Cache for Redis. The decision process follows a clear flowchart:
Right-Sizing Decision Flowchart
================================
[Start] Does the workload use clustering, geo-replication, or VNET injection?
|
+-- YES --> Premium tier required. Right-size the SKU within Premium.
| |
| +-- Check: Is memory utilization consistently < 50%?
| |
| +-- YES --> Downsize to next smaller Premium SKU
| +-- NO --> Current SKU is appropriate
|
+-- NO --> Does the workload require an SLA?
|
+-- YES --> Standard tier. Right-size the SKU within Standard.
| |
| +-- Check: Is memory utilization consistently < 50%?
| |
| +-- YES --> Downsize to next smaller Standard SKU
| +-- NO --> Current SKU is appropriate
|
+-- NO --> Basic tier (dev/test only).
|
+-- Check: Is this a production workload?
|
+-- YES --> Move to Standard (SLA required)
+-- NO --> Basic is acceptable for dev/testTier memory limits for reference:
Use Azure Monitor to query actual memory and CPU usage over the past 30 days. The following query returns the peak and average memory utilization:
# Query Azure Monitor metrics for Redis memory utilization (last 30 days)
az monitor metrics list \
--resource "/subscriptions/{sub-id}/resourceGroups/{rg}/providers/Microsoft.Cache/redis/{name}" \
--metric "usedmemorypercentage" \
--interval PT1H \
--start-time $(date -u -d '30 days ago' +%Y-%m-%dT%H:%M:%SZ) \
--end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
--aggregation Maximum Average \
--output tableIf the maximum memory utilization over 30 days is below 50%, the instance is a strong candidate for downsizing. Audit Premium feature usage before downgrading tier:
# Audit Premium feature usage across all Redis instances
az redis list --output json | jq -r '
.[] | select(.sku.family == "P") |
{
name: .name,
resourceGroup: .resourceGroup,
sku: .sku.name,
shardCount: .shardCount,
subnetId: (.subnetId // "none"),
linkedServers: (.linkedServers | length),
persistence: (if .redisConfiguration.rdbBackupEnabled == "true" then "enabled" else "disabled" end)
}' | jq -s '.'If shardCount is 0 or 1, subnetId is "none," linkedServers is 0, and persistence is "disabled," the instance is not using any Premium-exclusive features and can be downgraded to Standard tier.
Key insight: In the MSP scenario at the top of this article, 14 of 18 over-provisioned instances had zero Premium feature usage. Moving them to Standard tier saved 40% before any further optimization.
Azure Reservations provide the second-largest cost lever for Redis. The discount structure is straightforward:
The decision framework should consider both the immediate savings and the service retirement timeline:
Reservation Decision Tree
=========================
[Start] Is the Redis instance expected to run for 12+ months?
|
+-- NO --> Pay-as-you-go (no commitment)
|
+-- YES --> Is the workload stable (no planned migration in < 12 months)?
|
+-- NO --> Pay-as-you-go or short-term savings plan
|
+-- YES --> Consider retirement timeline:
|
+-- Current date + 1 year < retirement date (2028)?
| |
| +-- YES --> 1-year reservation (up to 35% savings)
| +-- NO --> Pay-as-you-go (migration imminent)
|
+-- Current date + 3 years < retirement date?
|
+-- YES --> 3-year reservation (up to 55% savings)
+-- NO --> 1-year reservation maximum
Note: As of Feb 2026, a 1-year reservation still provides
~22 months of discounted usage before the 2028 retirement.
A 3-year reservation extends beyond the retirement window
and would require careful evaluation of Microsoft's refund/
transfer policy for retired services.Important: Always right-size before purchasing reservations. Buying a reservation on an over-provisioned instance locks in the waste for 1-3 years. Optimize first, commit second.
For workloads with predictable daily or weekly traffic patterns, scheduled scaling can reduce costs by scaling down during off-peak hours. Azure Cache for Redis supports tier and SKU changes via the management API, though the operation takes several minutes and involves a brief connectivity interruption.
The following PowerShell runbook can be deployed as an Azure Automation runbook with a recurring schedule:
# Azure Automation Runbook: Scheduled Redis Scaling
# Schedule: Scale down at 20:00 UTC, scale up at 06:00 UTC
param(
[string]$ResourceGroupName = "rg-production",
[string]$CacheName = "redis-app-prod",
[string]$Action = "ScaleDown" # ScaleDown or ScaleUp
)
Connect-AzAccount -Identity
$cache = Get-AzRedisCache -ResourceGroupName $ResourceGroupName -Name $CacheName
if ($Action -eq "ScaleDown") {
# Scale from C3 (6 GB) to C2 (2.5 GB) during off-peak
if ($cache.Sku -eq "Standard" -and $cache.Size -eq "C3") {
Set-AzRedisCache -ResourceGroupName $ResourceGroupName \
-Name $CacheName -Size C2
Write-Output "Scaled down $CacheName from C3 to C2"
}
}
elseif ($Action -eq "ScaleUp") {
# Scale from C2 (2.5 GB) to C3 (6 GB) before business hours
if ($cache.Sku -eq "Standard" -and $cache.Size -eq "C2") {
Set-AzRedisCache -ResourceGroupName $ResourceGroupName \
-Name $CacheName -Size C3
Write-Output "Scaled up $CacheName from C2 to C3"
}
}Failure mode: Redis scaling operations can take 10-30 minutes and may cause brief connection drops. Do not schedule scaling during business-critical processing windows. Always test the scaling path in non-production first and confirm that your application handles transient connection failures gracefully.
Sometimes the most effective cost optimization is eliminating the Redis instance entirely. Two patterns are especially common:
Pattern 1: Redis Duplicating Cosmos DB
Many applications cache Cosmos DB results in Redis to reduce latency. But Cosmos DB with a properly tuned indexing policy and partition key strategy often delivers sub-10ms reads natively. The Redis layer adds cost, complexity, and a cache invalidation problem.
Before: App --> Redis Cache (P2, $650/mo) --> Cosmos DB ($400/mo)
Total: $1,050/mo
Latency: 2-5ms (cache hit), 15-25ms (cache miss)
After: App --> Cosmos DB with optimized indexing ($450/mo)
Total: $450/mo
Latency: 5-10ms (consistent)
Savings: $600/mo (57% reduction)
Trade-off: Slightly higher p50 latency, but more consistent p99Pattern 2: Premium Tier for Simple Caching
A common anti-pattern is deploying Premium P2 (13 GB, ~$650/mo) for a workload that stores 800 MB of session data with no clustering, persistence, or VNET requirements. Standard C3 (6 GB, ~$135/mo) provides identical functionality at 80% lower cost.
Before: Premium P2 (13 GB) --> $650/mo
Actual usage: 800 MB session data
Premium features used: none
After: Standard C3 (6 GB) --> $135/mo
Headroom: 5.2 GB available
SLA: 99.9% (same as Premium for non-clustered)
Savings: $515/mo (79% reduction)Failure mode warning: Do not downgrade from Premium to Standard if the application relies on Redis persistence (RDB/AOF), VNET injection, or clustering. These features are exclusive to Premium tier and the application will break if removed. Always audit feature usage with the CLI commands above before changing tiers.
Redis is frequently used as a lightweight message broker via Pub/Sub or list-based queues. While this works, it lacks durability guarantees -- if the Redis instance restarts, in-flight messages are lost. Azure Service Bus provides a more robust alternative:
If Redis is used exclusively for messaging (no caching), migrating to Service Bus can eliminate the Redis instance entirely.
| Recommendation | Typical Savings | Complexity | Risk |
|---|---|---|---|
| Right-size SKU within tier | 20-50% | Low | Low (reversible) |
| Downgrade Premium to Standard | 40-80% | Medium | Medium (requires new resource) |
| 1-year reservation | Up to 35% | Low | Low (commitment risk) |
| 3-year reservation | Up to 55% | Low | Medium (long commitment + retirement) |
| Scheduled scaling | 15-30% | Medium | Medium (connectivity interruption) |
| Eliminate redundant cache layer | 50-100% | High | High (architecture change) |
| Replace Redis messaging with Service Bus | 80-95% | High | Medium (code changes required) |
Azure Cache for Redis exposes two ports: 6380 (TLS/SSL) and 6379 (non-SSL). Port 6379 transmits data and authentication credentials in cleartext. Despite being a known security risk, many production instances still have this port enabled because it was the default in early deployments.
The remediation sequence is:
ssl=true# Step 2: Enforce TLS 1.2 minimum
az redis update \
--name <cache-name> \
--resource-group <rg-name> \
--set minimumTlsVersion=1.2
# Step 3: Disable non-SSL port
az redis update \
--name <cache-name> \
--resource-group <rg-name> \
--set enableNonSslPort=false
# Step 4: Rotate access keys (regenerate primary key)
az redis regenerate-key \
--name <cache-name> \
--resource-group <rg-name> \
--key-type Primary
# Verify the configuration
az redis show \
--name <cache-name> \
--resource-group <rg-name> \
--query "{name:name, nonSslPort:enableNonSslPort, tlsVersion:minimumTlsVersion}" \
--output tableTo enforce this across all subscriptions, deploy an Azure Policy that denies Redis instances with the non-SSL port enabled:
{
"mode": "All",
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Cache/redis"
},
{
"field": "Microsoft.Cache/redis/enableNonSslPort",
"equals": "true"
}
]
},
"then": {
"effect": "deny"
}
},
"parameters": {},
"displayName": "Azure Cache for Redis should disable non-SSL port",
"description": "Denies creation or update of Azure Cache for Redis instances with non-SSL port (6379) enabled. All connections must use TLS on port 6380."
}Failure mode warning: Disabling the non-SSL port will immediately break any client connections using port 6379 without TLS. Before making this change, audit all connection strings in application configurations, Key Vault references, and any hardcoded references in legacy code. The key rotation in Step 4 will also invalidate existing primary keys -- ensure all consuming applications are updated to use the new key before rotating.
Scaling within the same tier (e.g., Standard C3 to C2) does not cause data loss -- Azure migrates the data to the new instance. However, the operation takes 10-30 minutes and may cause brief connectivity interruptions. Scaling between tiers (Premium to Standard) requires creating a new resource and migrating data manually.
Yes, but choose your term carefully. A 1-year reservation purchased in early 2026 will still provide ~22 months of discounted usage before the 2028 retirement. A 3-year reservation extends beyond the retirement window, so you would need to confirm Microsoft's refund or transfer policy for retired services. Generally, 1-year reservations are the safer choice given the retirement timeline.
Run the Premium feature audit CLI command provided above. If shardCount is 0 or 1, subnetId is "none," linkedServers is 0, and persistence is disabled, the instance is not using Premium-exclusive features. Verify with the application team that no planned features depend on Premium capabilities before downgrading.
Azure Managed Redis reached General Availability (GA) and is supported for production workloads. However, it uses the Valkey engine rather than Redis, so application compatibility should be validated. The migration is not in-place -- it requires a new resource and data transfer, making it a project rather than a simple upgrade.
The risk is that any client connecting on port 6379 without TLS will immediately fail. The mitigation is to audit all connection strings before making the change. Modern Redis client libraries (StackExchange.Redis, Lettuce, redis-py) all support TLS natively. The configuration change itself is instant and does not require a Redis restart.
Yes. MSPs can script the audit and right-sizing recommendations across all tenants using Azure Lighthouse or by iterating over subscriptions with the Azure CLI. The policy enforcement for non-SSL port can be applied at the Management Group level to cover all subscriptions at once.
For a typical workload that is idle 12 hours per day and on weekends, scheduled scaling can reduce costs by 15-30%. The exact savings depend on the SKU difference and the scaling schedule. Note that scaling operations themselves take time and may cause brief interruptions, so this approach works best for workloads with clear off-peak windows.
Optimize your current deployment first. Migrating an over-provisioned, misconfigured deployment to Azure Managed Redis just transfers the waste to a new platform. Right-size, apply reservations for the remaining service life, harden security, and then migrate a lean, well-understood workload. This approach reduces both cost and migration risk.
Microsoft has historically allowed reservation exchanges or refunds when services are retired, but this is not guaranteed. Check the current Azure reservation exchange policy before purchasing long-term commitments on services with announced retirement dates. A 1-year reservation is generally safe; a 3-year reservation should be discussed with your Microsoft account team.
Spotto continuously monitors your Azure Cache for Redis instances and identifies right-sizing opportunities, reservation savings, security gaps (like open non-SSL ports), and redundant cache layers. Rather than running one-off audits, Spotto provides ongoing visibility and alerts when instances drift from optimal configuration -- especially valuable for MSPs managing many tenants.
Before
$45,000/mo
30 tenants, mostly Premium tier, no reservations
After
$22,000/mo
Right-sized tiers + 1-year reservations
Actions taken: 14 instances moved from Premium to Standard (no Premium features in use). 4 instances downsized within Premium tier. 1-year reservations applied to all 30 instances. Non-SSL port disabled across all tenants via Azure Policy.
Before
$8,200/mo
Premium P3 caching Cosmos DB product catalog
After
$0/mo (Redis eliminated)
Cosmos DB indexing optimized, Redis removed
Actions taken: Analysis showed Cosmos DB with optimized partition keys and composite indexes delivered 8ms reads natively. Redis was adding latency on cache misses (25ms round trip) and creating cache invalidation bugs during product updates. Redis instance eliminated entirely, Cosmos DB RU allocation increased slightly.
Before
$162/mo
Standard C1 used exclusively as message broker
After
$5/mo
Migrated to Azure Service Bus Standard
Actions taken: Redis was used solely for list-based job queuing with no caching. Messages were lost during Redis restarts, requiring manual re-processing. Migrated to Azure Service Bus with dead-letter queues and message durability. Redis instance decommissioned.
Before
$12,000/mo
8 Premium P1 instances running 24/7 across dev, QA, staging, UAT
After
$3,200/mo
Downgraded to Standard, scheduled scaling, weekend shutdown
Actions taken: All 8 instances moved from Premium P1 to Standard C3 (no Premium features needed in non-production). Automated shutdown on weekends and after 20:00 UTC on weekdays via Azure Automation. UAT instances kept running only during sprint review weeks.
The following diagram shows how optimization flows into eventual migration:
Optimization-to-Migration Path
===============================
Phase 1: Audit (Week 1-2)
[Inventory] --> [Metrics Collection] --> [Feature Audit] --> [Security Scan]
| | | |
v v v v
Instance list Usage data Premium features Non-SSL ports
in use/unused open/closed
Phase 2: Optimize (Week 3-6)
[Right-Size SKU] --> [Downgrade Tier] --> [Apply Reservations] --> [Harden Security]
| | | |
v v v v
Smaller SKU Premium-->Standard 1-year commitment TLS 1.2 + key rotation
within tier where possible on stable workloads + policy enforcement
Phase 3: Reassess Architecture (Week 7-10)
[Cache necessity audit] --> [Messaging audit] --> [Eliminate/Replace]
| | |
v v v
Remove redundant Redis Pub/Sub --> Decommission
Redis-over-Cosmos Service Bus unused instances
Phase 4: Prepare for Migration (Week 11+)
[Optimized baseline] --> [Compatibility testing] --> [Azure Managed Redis POC]
| | |
v v v
Lean, right-sized Valkey engine Migration plan with
deployment validation known-good configevictedkeys metric closely for 48 hours after any resize.Every optimization should have a clear rollback path:
az redis update --set enableNonSslPort=true. This takes effect within minutes. Remove the Azure Policy deny rule if it blocks the change.The 2028 retirement of Azure Cache for Redis is coming regardless of whether you optimize now. But the organizations that right-size, secure, and rationalize their Redis deployments today will have a massive advantage when migration time arrives:
Start with a simple inventory command to see the scope of your optimization opportunity:
# Inventory all Azure Cache for Redis instances across all subscriptions
az account list --query "[].id" -o tsv | while read sub; do
az redis list --subscription "$sub" --output json 2>/dev/null | jq -r '
.[] | [.name, .resourceGroup, .sku.name, .sku.family, .sku.capacity,
(.enableNonSslPort // false), .minimumTlsVersion, .provisioningState] |
@tsv'
done | column -t -s $'\t' -N "Name,ResourceGroup,SKU,Family,Capacity,NonSSL,TLS,State"That single command will tell you which instances are over-provisioned, which have open non-SSL ports, and where to focus your optimization effort. From there, follow the decision flowcharts and implementation sequences in this guide to systematically reduce cost and harden security across your entire Redis estate.
The challenges outlined in this article — cache right-sizing, reservation planning, TLS compliance — are the same ones our customers work through across their Azure environments. The difference is they use Spotto to surface these opportunities automatically, rather than running the analysis by hand.
Spotto continuously analyzes your Azure Cache for Redis instances to identify right-sizing opportunities, reservation savings, and security gaps — giving you a lean, compliant baseline for your Azure Managed Redis migration.
Free TrialDisclaimer: This article is provided for informational purposes only and does not constitute professional advice. Azure pricing, features, and service behavior may have changed since publication. Always validate recommendations against your specific environment and consult Microsoft's official documentation before making changes to production infrastructure. Spotto is not liable for any actions taken based on the content of this article.