Azure Storage is a highly durable, scalable, and secure cloud storage solution. In 2026, it has evolved significantly into an AI-ready foundational layer, optimized not just for simple files, but for the massive datasets required for training AI models and serving AI agents.
The platform is divided into several specialized “data services” depending on the type of data you are storing.
1. The Core Data Services
| Service | Data Type | Best For |
| Blob Storage | Unstructured (Objects) | Images, videos, backups, and AI training data lakes. |
| Azure Files | File Shares (SMB/NFS) | Replacing on-premise file servers; “Lift and Shift” for legacy apps. |
| Azure Disks | Block Storage | Persistent storage for Virtual Machines (OS and data disks). |
| Azure Tables | NoSQL Key-Value | Large scale, schema-less structured data (e.g., user profiles). |
| Azure Queues | Messaging | Reliable messaging between different parts of an application. |
2. Modern Tiers (Cost vs. Speed)
You don’t pay the same price for data you use every second versus data you keep for 10 years. You choose an Access Tier to optimize your bill:
- Premium: SSD-backed. Ultra-low latency for high-performance apps and AI inference.
- Hot: For data you access frequently. Lower access cost, higher storage cost.
- Cool (30 days): For data like short-term backups. Lower storage cost, higher access cost.
- Cold (90 days): New in the 2020s—optimized for “infrequent” but immediate access.
- Archive (180 days): Lowest cost, but data is “offline.” Rehydrating it takes hours.
3. Redundancy: Protecting Your Data
Azure keeps multiple copies of your data to protect against hardware failure or entire data center disasters.
- LRS (Locally Redundant): 3 copies in a single data center. Protects against disk failure.
- ZRS (Zone-Redundant): 3 copies across 3 different data centers in one region. Protects against a data center fire/outage.
- GRS (Geo-Redundant): Copies data to a secondary region hundreds of miles away. Protects against a major regional disaster.
🚀 What’s New in 2026?
- Agentic Scale: Blob storage can now handle millions of small objects per second to support AI Agents that need to “remember” long-term context or retrieve data from RAG (Retrieval-Augmented Generation) stores.
- Elastic SAN: A fully managed Storage Area Network (SAN) service that lets you pool block storage for different workloads, making it easier to migrate heavy SQL or Oracle databases to the cloud.
- AI Integration: Native “hooks” for frameworks like LangChain and Microsoft Foundry, allowing AI models to read directly from your storage with minimal setup.
Choosing the right storage in 2026 depends on two main factors: the structure of your data and how your application (or AI agent) needs to access it.
Here is the 2026 decision framework to help you choose the right tool for the job.
🚦 The “Quick Decision” Tree
| If your project needs to… | The Winner is… |
| Store millions of files for AI training or Data Lakes. | Blob Storage (Data Lake Gen2) |
| Replace an on-premise file server (SMB/NFS). | Azure Files |
| Provide high-speed block storage for Virtual Machines. | Managed Disks |
| Pool storage across many VMs/Containers like a Cloud SAN. | Elastic SAN |
| Send messages between different microservices. | Queue Storage |
| Store simple Key-Value data (User profiles, logs). | Table Storage |
🟦 1. Blob Storage: The AI & Big Data King
In 2026, Blob storage is no longer just for “backups.” It is the central engine for Agentic Scale—supporting AI agents that need to read massive amounts of context quickly.
- Best For: Unstructured data (PDFs, Images, Parquet files).
- Key Feature: Data Lake Storage Gen2. This adds a “Hierarchical Namespace” (real folders) to your blobs, which makes big data analytics and AI processing 10x faster.
- 2026 Strategy: Use Cold Tier for data you only touch once a quarter but need available instantly for AI “Reasoning” tasks.
📂 2. Azure Files: The “Lift-and-Shift” Hero
If you have an existing application that expects a “Drive Letter” (like Z:\), use Azure Files.
- Best For: Shared folders across multiple VMs or local office computers.
- New in 2026: Elastic ZRS (Zone Redundant Storage). This provides ultra-high availability for mission-critical file shares without the complexity of managing your own cluster.
- Performance: Use Premium Files if you are running active databases or high-transaction apps; use Standard for simple office document sharing.
💽 3. Managed Disks vs. Elastic SAN
This is the “local” vs “network” storage debate for your servers.
- Managed Disks (The Individual): Use Premium SSD v2. It’s the modern standard because it allows you to scale IOPS and Throughput separately, so you don’t have to buy a “huge disk” just to get “high speed.”
- Elastic SAN (The Pool): If you are migrating a massive environment from an on-premise SAN (like Dell EMC or NetApp), Elastic SAN lets you buy one large “pool” of performance and share it across all your VMs and Kubernetes clusters.
🔍 4. Specialized: Tables & Queues
These are “developer” storage types.
- Azure Tables: Use this if Cosmos DB is too expensive for your needs. It’s a “no-frills” NoSQL database for billions of small, structured rows.
- Azure Queues: Use this to decouple your app. If a user uploads a photo, put a message in the Queue. A “Worker” then sees that message and processes the photo. This prevents your app from crashing under heavy load.
💡 Pro-Tip for 2026: The “Cost First” Choice
If you are still unsure, start with Blob Storage. It is the most flexible, has the best API support for modern AI frameworks (like LangChain), and offers the most aggressive cost-saving tiers (Cool, Cold, and Archive).
What is the “main action” your application will take? (e.g., “Scanning documents for AI,” “Hosting a website,” or “Running a heavy SQL database?”) I can give you the specific configuration for that.
Cost optimization in Azure is no longer just about “turning things off.” In 2026, it is a continuous lifecycle known as FinOps, focusing on three distinct phases: Inform (Visibility), Optimize (Rightsizing & Rates), and Operate (Governance).
Here is the strategic blueprint for optimizing your Azure spend today.
1. Inform: Get Full Visibility
You cannot optimize what you cannot see.
- Tagging Enforcement: Use Azure Policy to require tags like
Environment,Owner, andCostCenter. This allows you to group costs by department or project in Azure Cost Management. - Budget Alerts: Set thresholds at 50%, 80%, and 100% of your predicted monthly spend.
- Azure Advisor Score: Check your “Cost Score” in Azure Advisor. It provides a “to-do list” of unused resources, such as unattached Managed Disks or idle ExpressRoute circuits.
2. Optimize: The Two-Pronged Approach
Optimization is divided into Usage (buying less) and Rate (paying less for what you use).
A. Usage Optimization (Rightsizing)
- Shut Down Idle Resources: Azure Advisor flags VMs with <3% CPU usage. For Dev/Test environments, use Auto-shutdown or Azure Automation to turn VMs off at 7:00 PM and on at 7:00 AM.
- Storage Tiering: Move data that hasn’t been touched in 30 days to the Cool tier, and data older than 180 days to the Archive tier. This can save up to 90% on storage costs.
- B-Series VMs: For workloads with low average CPU but occasional spikes (like small web servers), use the B-Series (Burstable) instances to save significantly.
B. Rate Optimization (Commitment Discounts)
In 2026, you choose your discount based on how much flexibility you need.
| Discount Type | Savings | Best For… |
| Reserved Instances (RI) | Up to 72% | Static workloads. You commit to a specific VM type in a specific region for 1 or 3 years. |
| Savings Plan for Compute | Up to 65% | Dynamic workloads. A flexible $ /hour commitment that applies across VM families and regions. |
| Azure Hybrid Benefit | Up to 85% | Using your existing Windows/SQL licenses in the cloud so you don’t pay for them twice. |
| Spot Instances | Up to 90% | Interruptible workloads like batch processing or AI model training. |
3. Operate: Modern 2026 Strategies
- AI Cost Governance: With the rise of Generative AI, monitor your Azure OpenAI and AI Agent token usage. Use Rate Limiting on your APIs to prevent a runaway AI bot from draining your budget in a single night.
- FinOps Automation: Use Azure Resource Graph to find “orphaned” resources (like Public IPs not attached to anything) and delete them automatically via Logic Apps.
- Sustainability & Carbon Optimization: Use the Azure Carbon Optimization tool. Often, the most “green” resource (lowest carbon footprint) is also the most cost-efficient one.
✅ The “Quick Wins” Checklist
- [ ] Delete Unattached Disks: When you delete a VM, the disk often stays behind and keeps billing you.
- [ ] Switch to Savings Plans: If your RIs are expiring, move to a Savings Plan for easier management.
- [ ] Check for “Zombies”: Idle Load Balancers, VPN Gateways, and App Service Plans with zero apps.
- [ ] Rightsize your SQL: Switch from “DTU” to the vCore model for more granular scaling and Hybrid Benefit savings.
Pro Tip: Never buy a Reserved Instance (RI) for a server that hasn’t been rightsized first. If you buy a 3-year reservation for an oversized 16-core VM, you are “locking in” waste for 36 months!
To find the “low-hanging fruit” in your Azure environment, you can use Azure Resource Graph Explorer and Log Analytics.
Here are the specific KQL (Kusto Query Language) scripts to identify common waste areas.
1. Identify Orphaned Resources (Quickest Savings)
These resources are costing you money every hour but aren’t attached to anything. Run these in the Azure Resource Graph Explorer.
A. Unattached Managed Disks
Code snippet
Resources| where type has "microsoft.compute/disks"| extend diskState = tostring(properties.diskState)| where managedBy == "" and diskState == "Unattached"| project name, resourceGroup, subscriptionId, location, diskSizeGB = properties.diskSizeGB| order by diskSizeGB desc
B. Unattached Public IPs
Code snippet
Resources| where type == "microsoft.network/publicipaddresses"| where properties.ipConfiguration == "" and properties.natGateway == ""| project name, resourceGroup, subscriptionId, location, ipAddress = properties.ipAddress
2. Identify Underutilized VMs (Rightsizing)
To run this, your VMs must be sending performance data to a Log Analytics Workspace. Use this to find VMs that are consistently running below 5% CPU.
KQL for Underutilized VMs (Last 7 Days):
Code snippet
Perf| where TimeGenerated > ago(7d)| where ObjectName == "Processor" and CounterName == "% Processor Time" and InstanceName == "_Total"| summarize AvgCPU = avg(CounterValue), MaxCPU = max(CounterValue) by Computer, _ResourceId| where AvgCPU < 5| order by AvgCPU asc
- Action: If
MaxCPUis also low, consider “Downsizing” the VM (e.g., from a D4 to a D2) or switching it to a B-series.
3. Find Idle App Service Plans
App Service Plans cost money even if they have zero apps running on them. Run this in Resource Graph Explorer.
Code snippet
resources| where type =~ "microsoft.web/serverfarms"| where properties.numberOfSites == 0| project name, resourceGroup, subscriptionId, Sku = sku.name, Tier = sku.tier
4. Search for “Zombie” Network Interfaces
These don’t cost money directly, but they clutter your environment and use up IP addresses in your subnets.
Code snippet
Resources| where type =~ 'microsoft.network/networkinterfaces'| where isnull(properties.virtualMachine)| project name, resourceGroup, subscriptionId, location
💡 How to Automate This in 2026
Instead of running these manually, use Azure Workbooks.
- Search for “Workbooks” in the Azure Portal.
- Click Add > New.
- Add a “Query” cell and paste any of the KQL scripts above.
- Save the Workbook as “Monthly Cost Cleanup.”
Now, you can open this dashboard once a month and see exactly what needs to be deleted!
Setting up an automated alert for “Unattached Disks” is a brilliant move for cost governance. In Azure, this is handled by monitoring the Activity Log for a specific event: the “Delete Virtual Machine” action (which leaves the disk behind) or the “Detach Disk” action.
Here is the 2026 step-by-step guide to setting this up.
Step 1: Create an Action Group (The “Who” to notify)
Before you create the alert, you need to tell Azure how to contact you.
- Search for Monitor in the Azure Portal.
- Click Alerts > Action groups > + Create.
- Basics: Give it a name like
CostAlertTeam. - Notifications: Select Email/SMS message/Push/Voice.
- Enter your email address and name the notification
EmailDevOps. - Click Review + create.
Step 2: Create the Activity Log Alert (The “When”)
Now, we create the trigger that watches for disks being left alone.
- In Monitor, click Alerts > + Create > Alert rule.
- Scope: Select your Subscription.
- Condition: This is the most important part. Click + Add condition and search for:
- Signal Name:
Detach Disk (Microsoft.Compute/disks) - Alternative: You can also alert on
Delete Virtual Machine, but “Detach Disk” is more accurate for catching orphaned resources.
- Signal Name:
- Refine the Logic: Under “Event initiated by,” you can leave it as “Any” or specify a specific automation service principal if you only want to catch manual detaches.
Step 3: Connect and Save
- Actions: Click Select action groups and choose the
CostAlertTeamgroup you created in Step 1. - Details: Name the rule
Alert-Disk-Unattached. - Severity: Set it to Informational (Sev 4) or Warning (Sev 3).
- Click Review + create.
💡 The “Pro” Way (2026 Strategy): Use Log Analytics
The method above tells you when a disk is detached, but it won’t tell you about disks that are already unattached. To catch those, use a Log Search Alert with a KQL query.
The KQL Query:
Code snippet
// Run this every 24 hours to find any disk with a "ManagedBy" state of NULLresources| where type has "microsoft.compute/disks"| extend diskState = tostring(properties.diskState)| where managedBy == "" and diskState == "Unattached"| project name, resourceGroup, subscriptionId
Why this is better:
- Activity Log Alerts are “reactive” (they fire only at the moment of the event).
- Log Search Alerts are “proactive” (they scan your environment every morning and email you a list of every unattached disk, even if it was detached months ago).
✅ Summary of the Workflow
- Detach/Delete Event happens in the VNet.
- Activity Log captures the event.
- Azure Monitor sees the event matches your rule.
- Action Group sends you an email immediately.
While an immediate alert is great for a “fire-drill” response, a Weekly Summary Report is the gold standard for long-term cost governance. It keeps your inbox clean and ensures your team stays accountable for “disk hygiene.”
In 2026, the best way to do this without writing custom code is using Azure Logic Apps.
🛠️ The Architecture: “The Monday Morning Cleanup”
We will build a simple 3-step workflow that runs every Monday at 9:00 AM, queries for unattached disks, and sends you a formatted HTML table.
Step 1: Create the Logic App (Recurrence)
- Search for Logic Apps and create a new one (select Consumption plan for lowest cost).
- Open the Logic App Designer and select the Recurrence trigger.
- Set it to:
- Interval: 1
- Frequency: Week
- On these days: Monday
- At these hours: 9
Step 2: Run the KQL Query
- Add a new step and search for the Azure Monitor Logs connector.
- Select the action: Run query and visualize results.
- Configure the connection:
- Subscription/Resource Group: Select your primary management group.
- Resource Type: Log Analytics Workspace.
- The Query: Paste the “Orphaned Disk” query from earlier:Code snippet
Resources | where type has "microsoft.compute/disks" | extend diskState = tostring(properties.diskState) | where managedBy == "" and diskState == "Unattached" | project DiskName = name, ResourceGroup = resourceGroup, SizeGB = properties.diskSizeGB, Location = location - Chart Type: Select HTML Table.
Step 3: Send the Email
- Add a final step: Office 365 Outlook – Send an email (V2).
- To: Your team’s email.
- Subject:
⚠️ Weekly Action: Unattached Azure Disks found - Body:
- Type some text like: “The following disks are currently unattached and costing money. Please delete them if they are no longer needed.”
- From the Dynamic Content list, select Attachment Content (this is the HTML table from Step 2).
📊 Why this is the “Pro” Move
- Zero Maintenance: Once it’s running, you never have to check the portal manually.
- Low Cost: A Logic App running once a week costs roughly $0.02 per month.
- Formatted for Humans: Instead of a raw JSON blob, you get a clean table that you can forward to project owners.
✅ Bonus: Add a “Delete” Link
If you want to be a 2026 power user, you can modify the KQL to include a “Deep Link” directly to each disk in the Azure Portal:
Code snippet
| extend PortalLink = strcat("https://portal.azure.com/#@yourtenant.onmicrosoft.com/resource", id)| project DiskName, SizeGB, PortalLink
Now, you can click the link in your email and delete the disk in seconds.
Combining the different “zombie” resources into one report is the most efficient way to manage your Azure hygiene.
By using the union operator in KQL, we can create a single list of various resource types that are currently costing you money without providing value.
1. The “Ultimate Zombie” KQL Query
Copy and paste this query into your Logic App or Azure Resource Graph Explorer. It looks for unattached disks, unassociated IPs, and empty App Service Plans all at once.
Code snippet
// Query for Orphaned DisksResources| where type has "microsoft.compute/disks"| extend diskState = tostring(properties.diskState)| where managedBy == "" and diskState == "Unattached"| project Name = name, Type = "Orphaned Disk", Detail = strcat(properties.diskSizeGB, " GB"), ResourceGroup, SubscriptionId| union ( // Query for Unassociated Public IPs Resources | where type == "microsoft.network/publicipaddresses" | where properties.ipConfiguration == "" and properties.natGateway == "" | project Name = name, Type = "Unattached IP", Detail = tostring(properties.ipAddress), ResourceGroup, SubscriptionId)| union ( // Query for Empty App Service Plans (Costly!) resources | where type =~ "microsoft.web/serverfarms" | where properties.numberOfSites == 0 | project Name = name, Type = "Empty App Service Plan", Detail = strcat(sku.tier, " - ", sku.name), ResourceGroup, SubscriptionId)| union ( // Query for Idle Load Balancers (No Backend Pool members) resources | where type == "microsoft.network/loadbalancers" | where array_length(properties.backendAddressPools) == 0 | project Name = name, Type = "Idle Load Balancer", Detail = "No Backend Pools", ResourceGroup, SubscriptionId)| order by Type asc
2. Updating Your Logic App Report
To make this work in your weekly email:
- Open your Logic App and update the “Run query” step with the new combined KQL above.
- Update the HTML Table: Since the new query uses consistent column names (
Name,Type,Detail), your HTML table will now neatly list the different types of waste side-by-side.
3. Advanced 2026 Tip: Add “Potential Savings”
If you want to get your manager’s attention, you can add a “Estimated Monthly Waste” column. While KQL doesn’t know your exact billing, you can hardcode estimates:
Code snippet
| extend MonthlyWaste = case( Type == "Orphaned Disk", 5.00, // Estimate $5 per month Type == "Unattached IP", 4.00, // Estimate $4 per month Type == "Empty App Service Plan", 50.00, // Estimate $50+ for Standard+ 0.00)
✅ Your “Monday Morning” Checklist
When you receive this email every Monday, follow this triage:
- Disks: Delete immediately unless you specifically kept it as a “manual backup” (though you should use Azure Backup for that).
- Public IPs: Delete. Unused Public IPs are charged by the hour in Azure.
- App Service Plans: If you aren’t using them, scale them to the Free (F1) tier or delete them. These are often the biggest hidden costs.
To turn this report into a powerful leadership tool, we need to calculate the “Total Potential Monthly Savings.” This changes the conversation from “We have a few loose disks” to “We can save $800/month by clicking these buttons.”
Here is how to update your Logic App and KQL to include a summary total.
1. Updated “Master Zombie” Query (With Estimated Costs)
We will add a hidden cost value to every “zombie” found, then summarize the total at the very end.
Code snippet
let RawData = Resources| where type has "microsoft.compute/disks"| extend diskState = tostring(properties.diskState)| where managedBy == "" and diskState == "Unattached"| project Name = name, Type = "Orphaned Disk", Detail = strcat(properties.diskSizeGB, " GB"), MonthlyWaste = 10.00, ResourceGroup| union ( Resources | where type == "microsoft.network/publicipaddresses" | where properties.ipConfiguration == "" and properties.natGateway == "" | project Name = name, Type = "Unattached IP", Detail = tostring(properties.ipAddress), MonthlyWaste = 4.00, ResourceGroup)| union ( resources | where type =~ "microsoft.web/serverfarms" | where properties.numberOfSites == 0 | project Name = name, Type = "Empty App Service Plan", Detail = strcat(sku.tier, " - ", sku.name), MonthlyWaste = 55.00, ResourceGroup);// This part creates the final listRawData| order by Type asc| union ( RawData | summarize Name = "TOTAL POTENTIAL SAVINGS", Type = "---", Detail = "---", MonthlyWaste = sum(MonthlyWaste), ResourceGroup = "---")
2. Formatting the Logic App Email
Since KQL doesn’t easily format currency, we’ll use the Logic App “Compose” action to make the final total stand out in your email.
- Run the Query: Use the
Run query and list resultsaction in Logic Apps with the KQL above. - Add a “Compose” Step: Between the Query and the Email, add a
Data Operations - Composeaction. - The HTML Body: Use this template in the email body to make it look professional:
HTML
<h3>Azure Monthly Hygiene Report</h3><p>The following resources are identified as waste. Cleaning these up will result in the estimated savings below.</p>@{body('Create_HTML_table')}<br><div style="background-color: #e1f5fe; padding: 15px; border-radius: 5px; border: 1px solid #01579b;"> <strong>💡 Quick Win Tip:</strong> Deleting these resources today will save your department approx <strong>$@{outputs('Total_Waste_Sum')}</strong> per month.</div>
3. Why This Works in 2026
- The “Nudge” Effect: By showing the total dollar amount at the bottom, you create a psychological incentive for resource owners to clean up.
- Customizable Pricing: You can adjust the
MonthlyWastenumbers in the KQL to match your specific Enterprise Agreement (EA) pricing. - Single Pane of Glass: You now have one query that covers Compute, Network, and Web services.
✅ Final Triage Steps
- Review: If you see a “TOTAL POTENTIAL SAVINGS” of $0.00, congratulations! Your environment is clean.
- Action: For the “Empty App Service Plans,” check if they are in a Free (F1) or Shared (D1) tier first—those don’t cost money, but they will still show up as “Empty.”