> ## Documentation Index
> Fetch the complete documentation index at: https://resources.devweekends.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Storage Solutions

> Master Azure Storage: Blob, Files, Disks, and data management strategies

# Storage Solutions

This chapter will teach you everything about storing data in Azure, starting from absolute basics. We'll explain what storage actually is, why different types exist, and how to choose and use them effectively.

## What You'll Learn

By the end of this chapter, you'll understand:

* What "storage" means in cloud computing (explained from scratch)
* The difference between storage types (Blob, Files, Disks, Queues, Tables)
* How to choose the right storage for your needs
* Storage tiers and how they save money (Hot, Cool, Archive)
* Replication strategies for durability and disaster recovery
* Security best practices (encryption, access control, private endpoints)
* Performance optimization techniques
* Cost management strategies

***

## What is Storage? (Start Here if You're New)

Let's start with the absolute basics.

### The Simple Explanation

**Storage = Where you save your data permanently**

When you write a document, take a photo, or save data from an app, it needs to be stored SOMEWHERE. That "somewhere" is storage.

**Key Difference from Memory (RAM):**

* **Memory (RAM)**: Temporary. Lost when computer turns off. Fast.
* **Storage (Disk)**: Permanent. Survives computer restart. Slower than RAM.

**Analogy:**

* **RAM** = Your desk (work in progress, cleared at end of day)
* **Storage** = Your filing cabinet (permanent records, survives overnight)

### Why Do You Need Storage?

Every application needs to store data:

**Example 1: Blog Website**

```
What needs storage:
- Blog posts (text, titles, dates)
- Images you upload
- User comments
- User profile pictures
- Website code itself

Without storage: Every time you restart the website, everything is GONE.
```

**Example 2: E-Commerce Site**

```
What needs storage:
- Product catalog (names, prices, descriptions)
- Product images
- Customer orders
- User accounts
- Payment history
- Inventory levels

Without storage: You'd lose all customer orders every time server restarts!
```

### Storage in the Old Days (Before Cloud)

**Traditional Way: Buy Hard Drives**

```
Problems:
1. Upfront cost ($500-2000 per drive)
2. Limited capacity (once full, must buy more drives)
3. No redundancy (drive fails = data lost)
4. Your responsibility:
   - Physical security (theft, fire)
   - Backups (manual, time-consuming)
   - Hardware failures (drive breaks, you replace it)
```

**Real Example:**

```
Company stores customer data
- Buy 10 hard drives ($10,000)
- Store in office closet
- Fire destroys building
- ALL DATA LOST
- Company goes bankrupt

This happened thousands of times before cloud storage.
```

### Storage in Azure (The Cloud Way)

**Azure Storage Benefits:**

```
1. No upfront cost (pay per GB per month)
2. Unlimited capacity (need more? Just use more)
3. Built-in redundancy (Azure keeps 3+ copies automatically)
4. Microsoft's responsibility:
   - Physical security (datacenters with guards)
   - Hardware maintenance (replace failed drives)
   - Automatic backups (built-in)
5. Global availability (access from anywhere)
```

**Cost Comparison:**

```
Traditional (1 TB storage):
- Buy 2 TB hard drive: $100
- Backup drive: $100
- Total upfront: $200
- Risk: Still lose data if both drives fail

Azure (1 TB storage):
- $18-50/month depending on tier
- $216-600/year
- Zero upfront cost
- Microsoft keeps 3-6 copies automatically
- Risk: Virtually zero (99.999999999% durability)

For most businesses: Azure is cheaper AND safer
```

### Understanding "Durability" (How Likely You Are to Lose Data)

Azure advertises "11 nines of durability" (99.999999999%). What does this mean?

**Translation:**

* If you store 10 million files for 10 million seconds (116 days)
* You might lose ONE file
* That's how reliable Azure storage is

**Comparison:**

* Single hard drive: \~99% durability (lose 1 in 100 files over time)
* Azure LRS (3 copies): 99.999999999% durability
* Azure GRS (6 copies): 99.99999999999999% durability (16 nines!)

***

## Why Multiple Storage Types?

Azure has different storage types because different data has different needs.

### The Core Principle: "Different Data, Different Needs"

**Analogy: Your Home Storage**

You don't store everything the same way at home:

* **Important documents** → Fireproof safe
* **Books** → Bookshelf
* **Clothes** → Closet on hangers
* **Photos** → Photo album or digital cloud
* **Food** → Refrigerator or pantry

Why different storage? Because they have different:

* **Access patterns** (how often you need them)
* **Size** (books vs documents)
* **Value** (important documents vs old magazines)

**Azure Storage Works the Same Way:**

```
Different Types of Data:

1. Large Files (images, videos, backups)
   → Use: Blob Storage
   → Why: Optimized for large objects

2. Shared Files (documents, configs)
   → Use: Azure Files
   → Why: Can mount like a network drive

3. VM Hard Drives
   → Use: Managed Disks
   → Why: High performance, attached to VMs

4. Application Messages (job queues)
   → Use: Queue Storage
   → Why: Reliable message passing

5. Structured Data (user profiles, logs)
   → Use: Table Storage or Databases
   → Why: Query and search capabilities
```

### Real-World Scenario: Photo Sharing App

Let's see how you'd use multiple storage types:

```
Photo Sharing App Architecture:

1. User Photos (original uploads)
   Storage: Blob Storage
   Why: Large files (images), need to serve billions
   Tier: Hot (frequently viewed)
   Cost: $18/month per TB

2. Thumbnails (small preview images)
   Storage: Blob Storage
   Why: Millions of small files
   Tier: Hot (shown on every page)
   Cost: $18/month per TB

3. Old Photos (not viewed in 6 months)
   Storage: Blob Storage
   Why: Same as original, but moved to cheaper tier
   Tier: Archive (rarely accessed)
   Cost: $1/month per TB (18x cheaper!)

4. Application Code & Static Files
   Storage: Blob Storage
   Why: HTML, CSS, JavaScript files
   Tier: Hot
   Size: Usually &lt;1 GB

5. User Metadata (username, email, likes)
   Storage: Azure SQL Database or Cosmos DB
   Why: Need to query (find user by email)
   Note: NOT just storage, this is a database

6. Background Job Queue (resize images)
   Storage: Queue Storage
   Why: Reliable message passing between servers
   Cost: $0.0004 per 10K operations (basically free)

Total Storage Cost Breakdown:
- 100 TB original photos: $1,800/month
- 10 TB thumbnails: $180/month
- 500 TB archived photos: $500/month
- App code: $0.18/month (tiny)
- Queue: ~$1/month
Total: ~$2,481/month for massive scale app
```

### The Storage Decision Tree

How do you choose which storage type to use?

```
Question 1: What kind of data?
├─ Large files (images, videos, documents)
│   └─> Blob Storage
│
├─ Need to mount as drive (like Z: or /mnt)
│   └─> Azure Files
│
├─ VM hard drive
│   └─> Managed Disks
│
├─ Application messages/jobs
│   └─> Queue Storage
│
└─ Structured data with queries
    └─> Table Storage or Database

Question 2: How often accessed?
├─ Constantly (website images)
│   └─> Hot Tier ($18/TB/month)
│
├─ Sometimes (monthly reports)
│   └─> Cool Tier ($10/TB/month)
│
└─ Rarely (old backups, compliance)
    └─> Archive Tier ($1/TB/month)

Question 3: How important is the data?
├─ Critical (lose it = business ends)
│   └─> GRS or GZRS (6 copies, multiple regions)
│
├─ Important (lose it = bad, but recoverable)
│   └─> ZRS (3 copies, 3 availability zones)
│
└─ Okay to lose (dev/test, temporary)
    └─> LRS (3 copies, same datacenter)
```

<img src="https://mintcdn.com/devweeekends/sTu6A4whRFPJo0_g/images/azure/05-storage-types.svg?fit=max&auto=format&n=sTu6A4whRFPJo0_g&q=85&s=6f0ad1e3392ed13158e77c387ef1b5b9" alt="Azure Storage Types" width="1080" height="1080" data-path="images/azure/05-storage-types.svg" />

### Key Storage Concepts Explained Simply

Before diving into specific services, let's define essential terms:

**Blob (Binary Large Object)**

> Just a fancy name for "file." Any file—image, video, document, zip file, anything—is a "blob" in Azure.
>
> **Why the weird name?** Historical computer science term. Just think "blob = file."

**Container**

> A folder that holds blobs. Like a folder on your computer.
>
> **Example**: Container named "profile-pictures" contains all user profile picture blobs.

**Storage Account**

> The top-level resource that contains all your storage (blobs, files, queues, tables).
>
> **Analogy**: Like your "Documents" folder that contains many subfolders.

**Access Tier**

> How "hot" or "cold" your data is (how often it's accessed). Hotter = more expensive storage, cheaper access. Colder = cheaper storage, more expensive access.
>
> **Analogy**: Storing winter clothes in the attic (archive) vs. keeping everyday clothes in your closet (hot).

**Replication**

> How many copies Azure keeps and where.
>
> **LRS**: 3 copies in one building
> **ZRS**: 3 copies in 3 buildings (same city)
> **GRS**: 3 copies here + 3 copies 1000+ miles away

**Redundancy vs. Backup**

> **Redundancy**: Multiple copies to prevent hardware failure (automatic)
> **Backup**: Point-in-time copies to prevent human error (you configure)
>
> **Example**: Delete a file by accident
>
> * Redundancy: Doesn't help (all copies deleted)
> * Backup: Can restore from yesterday's backup

> \[!WARNING]
> **Gotcha: Changing Access Tiers**
> Moving data from **Hot to Cool** is free, but moving data from **Cool to Hot** incurs an "Early Deletion" or "Retrieval" fee. Don't use Archive tier for backups you might need to restore instantly -- it can take up to 15 hours to "rehydrate" data from Archive at standard priority ($0.02/GB), or 1 hour at high priority ($0.10/GB). A real-world example: a company archived their database backups to save money, then spent 12 hours waiting to restore from Archive during an outage, costing \$180,000 in downtime. The fix is simple: keep your most recent backup in Cool tier (accessible in milliseconds) and only archive backups older than 30 days.

> \[!TIP]
> **Jargon Alert: Replication**
> **LRS (Locally Redundant)**: 3 copies in one building (Good enough for non-critical dev).
> **GRS (Geo-Redundant)**: 3 copies here + 3 copies in a different region (Essential for Disaster Recovery).

### The CAP Theorem in Storage: Consistency vs. Availability

When choosing a replication strategy, you are making a fundamental architectural choice.

1. **Local (LRS/ZRS)**: Provides **CP (Consistency + Partition Tolerance)**. Because the 3 copies are written synchronously, you are guaranteed to read the latest data, but if all 3 zones go down, the storage is unavailable.
2. **Global (GRS/GZRS)**: Provides **AP (Availability + Partition Tolerance)** across regions.
   * The primary region is updated synchronously (3 copies).
   * The secondary region (1000+ miles away) is updated **asynchronously**.
   * **The Trade-off**: In a "failover" scenario to the secondary region, you might lose the last few seconds/minutes of data. This is called **RPO (Recovery Point Objective)**.

> \[!IMPORTANT]
> **Pro Tip: RA-GRS (Read-Access GRS)**
> Standard GRS is "Passive"—you can't touch the secondary region unless a failover occurs. **RA-GRS** gives you a read-only endpoint in the secondary region at all times. Use this to handle traffic spikes by offloading read-requests to the other side of the world!

***

***

## 1. Azure Storage Services Overview

<CardGroup cols={2}>
  <Card title="Blob Storage" icon="cube">
    **Unstructured object storage**

    * Images, videos, documents
    * Backups, logs, archives
    * Data lakes
    * Hot, Cool, Archive tiers
  </Card>

  <Card title="Azure Files" icon="folder">
    **Fully managed file shares**

    * SMB/NFS protocols
    * Lift-and-shift migrations
    * Shared app data
    * Replace on-premises file servers
  </Card>

  <Card title="Queue Storage" icon="list">
    **Message queuing**

    * Asynchronous processing
    * Decoupling components
    * Up to 64 KB per message
    * Simple, reliable messaging
  </Card>

  <Card title="Table Storage" icon="table">
    **NoSQL key-value store**

    * Schema-less
    * Fast queries
    * Cost-effective
    * Structured non-relational data
  </Card>
</CardGroup>

***

## Under the Hood: The Anatomy of a Storage Request

How does Azure handle trillions of requests per second without losing data? The secret lies in the **Storage Stamp** architecture.

### 1. The Storage Stamp

A "Stamp" is a cluster of roughly 10-20 racks of storage servers. Each rack has its own power and network.

* When you create a storage account, it is assigned to a Stamp.
* **LRS (Local Replication)** ensures your data is written to three different disks on **three different racks** within that single stamp. Even if a whole rack's power supply fails, your data is safe.

**Real-World Analogy**: A Storage Stamp is like a bank vault with three separate lockboxes in three different rooms. When you deposit a document, the bank makes three copies and places each in a different room with independent locks, power, and climate control. If one room floods, your document survives in the other two. Upgrading to GRS is like having three copies in a second bank across town -- even a city-wide disaster cannot destroy all copies.

### 2. The Partition Layer (The Scalability Secret)

Azure doesn't just store files as names. It uses a **Partition Key** system.

* Every blob belongs to a partition.
* Azure's **Front-End Layer** looks at the requested blob name, determines which Partition Server owns it, and routes the request there.
* **Pro Tip**: If you name your blobs with a sequential prefix (like `2024-01-01-log1`, `2024-01-01-log2`), they might all end up on the same Partition Server, causing a "Hot Partition" bottleneck. Using a random prefix or hash helps distribute the load across the entire stamp.

### 3. The Stream Layer (The Durability Secret)

When your app sends a "Write" request:

1. The request hits the **Partition Layer**.
2. It is passed to the **Stream Layer**.
3. Replicated synchronously to 3 different nodes.
4. **The ACK**: Your app only receives a "Success" message when the data is safely written to the physical disks of all 3 replicas. This is why Azure Storage is **Strongly Consistent**.

***

## 2. Blob Storage Deep Dive

**Blob Storage** stores massive amounts of unstructured data.

### Blob Types

<Tabs>
  <Tab title="Block Blobs">
    **Optimized for streaming and cloud storage**

    ```
    Use cases:
    - Documents (PDF, Word, Excel)
    - Media (images, audio, video)
    - Logs and telemetry
    - Backups

    Characteristics:
    - Up to 190.7 TB per blob
    - Composed of blocks (up to 4.75 TB each)
    - Can update individual blocks
    - Most common blob type (95% of use cases)
    ```

    **Upload block blob**:

    ```bash theme={null}
    az storage blob upload \
      --account-name mystorageaccount \
      --container-name mycontainer \
      --name mydocument.pdf \
      --file ./local-file.pdf \
      --auth-mode key
    ```
  </Tab>

  <Tab title="Page Blobs">
    **Optimized for random read/write**

    ```
    Use cases:
    - Azure VM disks (VHD files)
    - Database files
    - Random access scenarios

    Characteristics:
    - Up to 8 TB per blob
    - Optimized for frequent read/write
    - 512-byte page alignment
    - Higher cost than block blobs
    ```

    **Most users never directly use page blobs** (Azure manages them for VM disks).
  </Tab>

  <Tab title="Append Blobs">
    **Optimized for append operations**

    ```
    Use cases:
    - Logging and auditing
    - Time-series data
    - IoT telemetry

    Characteristics:
    - Up to 195 GB per blob
    - Append-only (no update/delete of blocks)
    - Efficient for log aggregation
    ```

    **Append to blob**:

    ```bash theme={null}
    az storage blob append \
      --account-name mystorageaccount \
      --container-name logs \
      --name application.log \
      --file ./new-logs.txt
    ```
  </Tab>
</Tabs>

### Storage Tiers

<Tabs>
  <Tab title="Hot Tier">
    **Frequently accessed data**

    ```
    Pricing:
    Storage: $0.018/GB/month
    Read: $0.0004/10K operations
    Write: $0.05/10K operations

    Use for:
    - Active website images
    - Recently uploaded files
    - Frequently accessed documents

    Min storage duration: None
    ```
  </Tab>

  <Tab title="Cool Tier">
    **Infrequently accessed (30+ days)**

    ```
    Pricing:
    Storage: $0.01/GB/month (44% cheaper)
    Read: $0.01/10K operations (25x more expensive)
    Write: $0.10/10K operations (2x more expensive)

    Use for:
    - Short-term backups
    - Older media content
    - 30-90 day retention

    Min storage duration: 30 days
    Early deletion penalty: Pro-rated charge
    ```
  </Tab>

  <Tab title="Archive Tier">
    **Rarely accessed (180+ days)**

    ```
    Pricing:
    Storage: $0.00099/GB/month (98% cheaper!)
    Read: $0.02/10K operations
    Rehydration: $0.02/GB (to hot) or $0.01/GB (to cool)

    Use for:
    - Long-term backups
    - Compliance archives
    - Rarely accessed data

    Min storage duration: 180 days
    Rehydration time: Up to 15 hours
    ```

    **Rehydrate blob**:

    ```bash theme={null}
    # Rehydrate to hot tier
    az storage blob set-tier \
      --account-name mystorageaccount \
      --container-name archives \
      --name backup-2020.zip \
      --tier Hot \
      --rehydrate-priority High
    ```
  </Tab>
</Tabs>

### Lifecycle Management

**Automatically transition blobs between tiers** to optimize costs. This is one of the highest-ROI configurations in all of Azure -- a single JSON policy can save thousands of dollars per month by moving stale data to cheaper tiers without any application changes.

**Real-World Analogy**: Think of lifecycle management like your closet strategy. Current season clothes stay in the closet (Hot). Last season's clothes go to the attic (Cool). Clothes from 5 years ago go into long-term storage (Archive). Clothes you will never wear again get donated (Deleted). You do not manually move every item -- you set rules and follow them on a schedule.

```json theme={null}
{
  "rules": [
    {
      // This rule automatically manages backup blobs through their lifecycle.
      // Without this policy, old backups sit in Hot tier forever, costing
      // $18/TB/month when they could be in Archive at $1/TB/month.
      "name": "MoveToArchive",
      "enabled": true,
      "type": "Lifecycle",
      "definition": {
        "filters": {
          "blobTypes": ["blockBlob"],
          // prefixMatch targets only the "backups/" folder -- you probably
          // do NOT want to archive your active website images or user uploads.
          // Always scope lifecycle rules to specific prefixes.
          "prefixMatch": ["backups/"]
        },
        "actions": {
          "baseBlob": {
            // After 30 days: Move from Hot ($18/TB) to Cool ($10/TB).
            // Saves 44% on storage, but reads cost 25x more -- fine for backups
            // that are rarely accessed after the first month.
            "tierToCool": {
              "daysAfterModificationGreaterThan": 30
            },
            // After 90 days: Move from Cool ($10/TB) to Archive ($1/TB).
            // Archive is 94% cheaper but takes up to 15 hours to access.
            // Only use for data you can afford to wait hours to retrieve.
            "tierToArchive": {
              "daysAfterModificationGreaterThan": 90
            },
            // After 365 days: Delete entirely.
            // Set this based on your compliance requirements -- some industries
            // (healthcare, finance) require 7-year retention.
            "delete": {
              "daysAfterModificationGreaterThan": 365
            }
          }
        }
      }
    }
  ]
}
```

**Cost Impact Example**:

```
Without lifecycle management (1 year of daily backups, 10 GB each):
365 backups x 10 GB = 3.65 TB in Hot tier = $65.70/month

With lifecycle management:
30 backups in Hot (0.3 TB) = $5.40/month
60 backups in Cool (0.6 TB) = $6.00/month
275 backups in Archive (2.75 TB) = $2.72/month
Total: $14.12/month (78% savings!)
Annual savings: ~$618
```

**Common Pitfall**: Setting Archive tier on data you need to access quickly. Rehydrating data from Archive takes up to 15 hours (standard priority) and costs $0.02/GB. If you accidentally archive 1 TB of data you need tomorrow, that is a $20 rehydration fee plus a day of waiting. Use Cool tier for data you might need within hours.

```bash theme={null}
# Apply lifecycle policy
az storage account management-policy create \
  --account-name mystorageaccount \
  --policy @lifecycle-policy.json \
  --resource-group rg-storage
```

### Blob Versioning and Soft Delete

<CardGroup cols={2}>
  <Card title="Blob Versioning" icon="clock-rotate-left">
    **Keep all versions of a blob**

    ```bash theme={null}
    # Enable versioning
    az storage account blob-service-properties update \
      --account-name mystorageaccount \
      --enable-versioning true

    # Every modification creates new version
    # Old versions accessible by version ID
    # Protects against accidental overwrites
    ```

    **Use case**: Track document changes, audit trail
  </Card>

  <Card title="Soft Delete" icon="trash-arrow-up">
    **Recoverable deletion**

    ```bash theme={null}
    # Enable soft delete (7 days)
    az storage account blob-service-properties update \
      --account-name mystorageaccount \
      --enable-delete-retention true \
      --delete-retention-days 7

    # Deleted blobs retained for 7 days
    # Can undelete within retention period
    ```

    **Use case**: Protect against accidental deletion
  </Card>
</CardGroup>

### Blob Storage Security

<Tabs>
  <Tab title="Access Control">
    **Three levels of access**:

    1. **Storage Account Keys** (avoid in production):

    ```bash theme={null}
    # Full access to entire storage account
    # Rotate regularly (90 days)
    az storage account keys list \
      --account-name mystorageaccount
    ```

    2. **Shared Access Signature (SAS)**:

    ```bash theme={null}
    # Time-limited, scoped access
    az storage blob generate-sas \
      --account-name mystorageaccount \
      --container-name mycontainer \
      --name myblob.txt \
      --permissions r \
      --expiry 2026-12-31T23:59:59Z

    # Result: URL with token
    # Expires automatically
    ```

    3. **Azure AD (Recommended)**:

    ```bash theme={null}
    # Use managed identity or user identity
    # RBAC roles: Storage Blob Data Reader/Contributor
    az role assignment create \
      --role "Storage Blob Data Contributor" \
      --assignee <identity-id> \
      --scope /subscriptions/.../storageAccounts/mystorageaccount
    ```
  </Tab>

  <Tab title="Encryption">
    **Encryption at Rest**:

    ```
    Default: Microsoft-managed keys (automatic)
      ✅ No configuration needed
      ✅ Free
      ❌ Microsoft controls keys

    Customer-managed keys (CMK):
      ✅ You control key rotation
      ✅ Audit key access
      ⚠️  Requires Azure Key Vault
    ```

    **Enable CMK**:

    ```bash theme={null}
    # Create Key Vault and key
    az keyvault create \
      --name myvault \
      --resource-group rg-storage

    az keyvault key create \
      --vault-name myvault \
      --name storage-key \
      --protection software

    # Configure storage to use CMK
    az storage account update \
      --name mystorageaccount \
      --resource-group rg-storage \
      --encryption-key-source Microsoft.Keyvault \
      --encryption-key-vault https://myvault.vault.azure.net \
      --encryption-key-name storage-key
    ```
  </Tab>

  <Tab title="Network Security">
    **Restrict network access**:

    ```bash theme={null}
    # 1. Disable public access
    az storage account update \
      --name mystorageaccount \
      --resource-group rg-storage \
      --public-network-access Disabled

    # 2. Use Private Endpoints
    az network private-endpoint create \
      --name pe-storage \
      --resource-group rg-storage \
      --vnet-name vnet-prod \
      --subnet snet-data \
      --private-connection-resource-id /subscriptions/.../storageAccounts/mystorageaccount \
      --group-ids blob \
      --connection-name storage-private

    # 3. Or use firewall (less secure)
    az storage account network-rule add \
      --account-name mystorageaccount \
      --vnet-name vnet-prod \
      --subnet snet-web

    az storage account update \
      --name mystorageaccount \
      --default-action Deny
    ```
  </Tab>
</Tabs>

***

## 3. Azure Files

**Azure Files** provides fully managed cloud file shares accessible via SMB/NFS.

### When to Use Azure Files

<Tabs>
  <Tab title="✅ Use Azure Files For">
    * **Lift-and-shift**: Replace on-premises file servers
    * **Shared configuration**: App servers need shared config files
    * **Diagnostic logs**: Centralized log storage
    * **Dev/Test**: Shared development environments
    * **User home directories**: Roaming profiles

    **Example**: Multiple VMs need access to same files
  </Tab>

  <Tab title="❌ Don't Use Azure Files For">
    * **Object storage**: Use Blob Storage instead (cheaper, more scalable)
    * **Database files**: Use managed disks (better performance)
    * **High IOPS**: Use Premium Files or Ultra Disk

    **Example**: Storing millions of images → Blob Storage
  </Tab>
</Tabs>

### File Share Tiers

<Tabs>
  <Tab title="Standard (HDD)">
    ```
    Performance: Up to 60 MB/s throughput, 1,000 IOPS
    Pricing: $0.06/GB/month
    Minimum: None

    Use for: General-purpose file shares, dev/test
    ```
  </Tab>

  <Tab title="Premium (SSD)">
    ```
    Performance: Up to 10,000 IOPS, 200 MB/s per TB provisioned
    Pricing: $0.20/GB/month (provisioned, not consumed)
    Minimum: 100 GB

    Use for: High-performance, low-latency workloads
    ```

    **Example**: SQL Server needs high IOPS
  </Tab>
</Tabs>

### Mount Azure File Share

<Tabs>
  <Tab title="Windows">
    ```powershell theme={null}
    # Get storage account key
    $storageKey = (az storage account keys list `
      --account-name mystorageaccount `
      --query "[0].value" -o tsv)

    # Mount file share
    net use Z: \\mystorageaccount.file.core.windows.net\myshare `
      /user:AZURE\mystorageaccount $storageKey

    # Persistent mount (survives reboot)
    cmdkey /add:mystorageaccount.file.core.windows.net `
      /user:AZURE\mystorageaccount /pass:$storageKey

    # Add to Windows startup
    ```
  </Tab>

  <Tab title="Linux">
    ```bash theme={null}
    # Install cifs-utils
    sudo apt-get install cifs-utils

    # Create mount point
    sudo mkdir /mnt/myshare

    # Create credentials file
    sudo bash -c 'echo "username=mystorageaccount" >> /etc/smbcredentials'
    sudo bash -c 'echo "password=STORAGE_KEY" >> /etc/smbcredentials'
    sudo chmod 600 /etc/smbcredentials

    # Mount share
    sudo mount -t cifs //mystorageaccount.file.core.windows.net/myshare /mnt/myshare -o credentials=/etc/smbcredentials,dir_mode=0777,file_mode=0777

    # Add to /etc/fstab for persistent mount
    //mystorageaccount.file.core.windows.net/myshare /mnt/myshare cifs credentials=/etc/smbcredentials,dir_mode=0777,file_mode=0777 0 0
    ```
  </Tab>
</Tabs>

### Azure File Sync

**Sync on-premises file servers with Azure Files**.

<div className="flex justify-center my-4">
  <div className="w-full max-w-4xl">
    ```mermaid theme={null}
    graph TB
        OnPrem1[On-Premises Server 1<br/>NYC Office]
        OnPrem2[On-Premises Server 2<br/>SF Office]
        Azure[Azure Files<br/>Cloud Storage]

        OnPrem1 <-.Sync.-> Azure
        OnPrem2 <-.Sync.-> Azure
        OnPrem1 -.Replicated.-> OnPrem2

        style Azure fill:#0078D4
    ```
  </div>
</div>

**Benefits**:

* Multi-site access to same files
* Cloud tiering (free up on-premises space)
* Centralized backup (Azure Backup)
* Disaster recovery (files in cloud)

***

## 4. Managed Disks

**Managed Disks** are block-level storage for Azure VMs.

### Disk Types Comparison

| Type               | IOPS    | Throughput | Latency | Use Case                    | Cost     |
| ------------------ | ------- | ---------- | ------- | --------------------------- | -------- |
| **Ultra Disk**     | 160,000 | 4,000 MB/s | \<1ms   | Mission-critical (SAP HANA) | \$\$\$\$ |
| **Premium SSD v2** | 80,000  | 1,200 MB/s | \<2ms   | High-performance databases  | \$\$\$   |
| **Premium SSD**    | 20,000  | 900 MB/s   | \~3ms   | Production databases        | \$\$     |
| **Standard SSD**   | 6,000   | 750 MB/s   | \~10ms  | Web servers, dev/test       | \$       |
| **Standard HDD**   | 500     | 60 MB/s    | \~20ms  | Backups, archives           | ¢        |

### Disk Sizing Strategy

<Tabs>
  <Tab title="SQL Server">
    ```
    OS Disk: Premium SSD P30 (1 TB)
      - ReadWrite cache
      - Operating system and SQL binaries

    Data Files: 4x Premium SSD P30 (4 TB total)
      - Striped (RAID 0) using Storage Spaces
      - ReadOnly cache
      - Combined: 20,000 IOPS

    Log Files: Premium SSD P20 (512 GB)
      - None cache (write-heavy)
      - Separate disk for sequential writes

    TempDB: Local NVMe SSD (D: drive)
      - Ephemeral, ultra-fast
      - Free, no persistence needed
    ```
  </Tab>

  <Tab title="Web Application">
    ```
    OS Disk: Premium SSD P10 (128 GB)
      - ReadWrite cache
      - Sufficient for web server

    Data Disk: Standard SSD E15 (256 GB)
      - ReadOnly cache
      - Application data, logs

    Total Cost: ~$30/month
    ```
  </Tab>
</Tabs>

### Disk Snapshots and Backups

```bash theme={null}
# Create snapshot
az snapshot create \
  --resource-group rg-prod \
  --name snapshot-data-$(date +%Y%m%d) \
  --source /subscriptions/.../disks/disk-data

# Create disk from snapshot
az disk create \
  --resource-group rg-prod \
  --name disk-restored \
  --source snapshot-data-20260121

# Incremental snapshots (cost-effective)
az snapshot create \
  --resource-group rg-prod \
  --name snapshot-data-incremental \
  --source disk-data \
  --incremental true
```

**Backup Strategy**:

* Daily snapshots (7-day retention)
* Weekly snapshots (4-week retention)
* Monthly snapshots (12-month retention)
* Use Azure Backup for automated management

***

## 5. Data Lake Storage Gen2

**ADLS Gen2** combines Blob Storage with hierarchical namespace for big data analytics.

### When to Use Data Lake

<CardGroup cols={2}>
  <Card title="Use Data Lake For" icon="chart-bar">
    * Big data analytics (Spark, Databricks)
    * Data warehousing (Synapse)
    * Machine learning pipelines
    * Hierarchical folder structures
    * POSIX permissions
  </Card>

  <Card title="Use Blob Storage For" icon="cube">
    * Simple object storage
    * Flat namespace
    * Lower cost (no hierarchical namespace)
    * Traditional backups
    * Media files
  </Card>
</CardGroup>

### Enable Hierarchical Namespace

```bash theme={null}
# Create storage account with Data Lake Gen2
az storage account create \
  --name mydatalake \
  --resource-group rg-analytics \
  --kind StorageV2 \
  --hierarchical-namespace true \
  --access-tier Hot

# Result: Blob Storage + filesystem semantics
# /folder1/subfolder/file.csv
```

### POSIX Permissions

```bash theme={null}
# Set ACLs (Access Control Lists)
az storage fs access set \
  --account-name mydatalake \
  --file-system mycontainer \
  --path /data/sales \
  --acl "user::rwx,group::r-x,other::---"

# Grant user read access
az storage fs access set \
  --account-name mydatalake \
  --file-system mycontainer \
  --path /data/sales \
  --acl "user:alice@company.com:r-x"
```

***

## 6. Storage Performance Optimization

### Blob Storage Optimization

<AccordionGroup>
  <Accordion title="1. Use CDN for Static Content" icon="rocket">
    ```bash theme={null}
    # Create CDN profile
    az cdn profile create \
      --name mycdn \
      --resource-group rg-storage \
      --sku Standard_Microsoft

    # Create CDN endpoint
    az cdn endpoint create \
      --name mycdn-endpoint \
      --profile-name mycdn \
      --resource-group rg-storage \
      --origin mystorageaccount.blob.core.windows.net \
      --origin-host-header mystorageaccount.blob.core.windows.net

    # Result: Global edge caching, faster access
    ```
  </Accordion>

  <Accordion title="2. Optimize Blob Naming" icon="tag">
    **Avoid hotspots with random prefixes**:

    ```
    ❌ Bad (hotspot on same partition):
    /images/2024/01/01/image1.jpg
    /images/2024/01/01/image2.jpg
    /images/2024/01/01/image3.jpg

    ✅ Good (distributed across partitions):
    /ab/images/2024/01/01/image1.jpg
    /cd/images/2024/01/01/image2.jpg
    /ef/images/2024/01/01/image3.jpg

    Use first 2 characters of hash as prefix
    ```
  </Accordion>

  <Accordion title="3. Parallel Uploads" icon="arrows-split-up-and-left">
    ```python theme={null}
    from azure.storage.blob import BlobServiceClient

    blob_service = BlobServiceClient(account_url="...", credential="...")
    blob_client = blob_service.get_blob_client("mycontainer", "largefile.zip")

    # Upload in parallel (default: 4 MB chunks)
    with open("largefile.zip", "rb") as data:
        blob_client.upload_blob(
            data,
            max_concurrency=10,  # 10 parallel uploads
            overwrite=True
        )

    # 10x faster for large files
    ```
  </Accordion>

  <Accordion title="4. Use Appropriate Tier" icon="layer-group">
    ```
    Hot Tier: Frequently accessed (< 30 days)
    Cool Tier: Infrequently accessed (30-90 days)
    Archive Tier: Rarely accessed (180+ days)

    Example:
    - Website images: Hot
    - 60-day backup: Cool
    - 1-year compliance archive: Archive

    Savings: Up to 98% for Archive vs Hot
    ```
  </Accordion>
</AccordionGroup>

***

## 7. Interview Questions

### Beginner

<AccordionGroup>
  <Accordion title="Q1: What's the difference between Blob Storage and Azure Files?">
    **Blob Storage**:

    * Object storage (REST API)
    * Unstructured data (images, videos, logs)
    * Accessible via HTTP/HTTPS
    * No file system semantics
    * More scalable, cheaper

    **Azure Files**:

    * File shares (SMB/NFS protocol)
    * Structured data (documents, configs)
    * Mount as drive (Z:, /mnt)
    * File system semantics (folders, permissions)
    * Lift-and-shift from file servers

    **Rule of thumb**: Use Blob for apps, Azure Files for VMs/users
  </Accordion>

  <Accordion title="Q2: Explain storage tiers and when to use each">
    **Hot Tier**:

    * Frequently accessed data
    * Lowest access cost, highest storage cost
    * Use for: Active website content, recent data

    **Cool Tier**:

    * Infrequently accessed (30+ days)
    * Medium storage cost, higher access cost
    * Use for: Short-term backups, 30-90 day retention

    **Archive Tier**:

    * Rarely accessed (180+ days)
    * Lowest storage cost, highest access cost
    * Rehydration required (up to 15 hours)
    * Use for: Long-term backups, compliance

    **Cost Example**:

    * 1 TB for 1 year:
      * Hot: \$216
      * Cool: \$120 (44% cheaper)
      * Archive: \$12 (94% cheaper!)
  </Accordion>
</AccordionGroup>

### Intermediate

<AccordionGroup>
  <Accordion title="Q3: Design a cost-effective backup strategy">
    ```
    Backup Strategy for 100 GB database:

    1. Daily Backups (7 days):
       - Store in Cool tier
       - Cost: 7 × 100 GB × $0.01 = $7/month

    2. Weekly Backups (4 weeks):
       - Store in Cool tier
       - Cost: 4 × 100 GB × $0.01 = $4/month

    3. Monthly Backups (12 months):
       - Store in Archive tier
       - Cost: 12 × 100 GB × $0.001 = $1.20/month

    Total: $12.20/month (vs $43 if all Hot)

    Lifecycle Policy:
    - Daily: Cool immediately
    - After 30 days: Move to Archive
    - After 365 days: Delete

    Incremental Backups:
    - Only changed data backed up daily
    - Reduces storage by 80-90%
    - Final cost: ~$2-3/month
    ```
  </Accordion>

  <Accordion title="Q4: Optimize storage for a media streaming app">
    ```
    Architecture:

    1. Video Storage:
       - Original files: Archive tier (rarely accessed)
       - Transcoded versions: Hot tier (frequently streamed)
       - Use CDN (Azure Front Door) for global distribution

    2. Thumbnail Storage:
       - Hot tier (displayed on every page)
       - Small files, high access frequency
       - CDN caching (90%+ cache hit rate)

    3. User Uploads:
       - Start in Hot tier (recently uploaded, often viewed)
       - After 30 days: Move to Cool (older content)
       - After 180 days: Move to Archive (historical)

    4. CDN Configuration:
       - Cache thumbnails: 7 days
       - Cache videos: 1 day (balance freshness and cost)
       - Purge cache on content update

    5. Performance:
       - Parallel video chunk uploads (10 concurrent)
       - Adaptive bitrate streaming (HLS/DASH)
       - Geo-replication (LRS → GRS for critical content)

    Cost Savings:
    - Without optimization: $5,000/month
    - With optimization: $1,200/month (76% reduction)

    Optimizations:
    - Lifecycle policies: $2,000 savings
    - CDN (reduced blob reads): $1,500 savings
    - Incremental backups: $300 savings
    ```
  </Accordion>
</AccordionGroup>

### Advanced

<AccordionGroup>
  <Accordion title="Q5: Implement global data replication with conflict resolution">
    ````
    Global Replication Strategy:

    1. Use GRS (Geo-Redundant Storage):
       - Primary: East US
       - Secondary: West US (read-only)
       - Automatic failover on regional outage

    2. Or use multi-region architecture:
       - Storage accounts in each region
       - Azure Traffic Manager routes to closest
       - Application-level replication

    3. Conflict Resolution:
       Option A: Last Write Wins (LWW)
         - Use blob versioning
         - Latest timestamp wins
         - Simple, may lose data

       Option B: Application-Level Merge
         - Store conflict versions separately
         - Manual resolution
         - Complex, but no data loss

    4. Implementation:
       ```python
       from azure.storage.blob import BlobServiceClient

       # Primary storage
       primary = BlobServiceClient(account_url="https://storage-eastus...")
       secondary = BlobServiceClient(account_url="https://storage-westus...")

       def upload_with_replication(blob_name, data):
           # Upload to primary
           primary_blob = primary.get_blob_client("mycontainer", blob_name)
           primary_blob.upload_blob(data, overwrite=True)

           # Replicate to secondary
           secondary_blob = secondary.get_blob_client("mycontainer", blob_name)
           secondary_blob.upload_blob(data, overwrite=True)

           # Or use change feed for async replication
       ```

    5. Monitoring:
       - Alert on replication lag > 15 minutes
       - Monitor blob change feed
       - Test failover monthly
    ````
  </Accordion>

  <Accordion title="Q6: Secure storage with zero-trust architecture">
    ````
    Zero-Trust Storage Security:

    1. Network Isolation:
       - Disable public access entirely
       - Use Private Endpoints only
       - Traffic never leaves Azure backbone

    2. Identity-Based Access:
       - No shared keys (disable storage account keys)
       - Azure AD authentication only
       - RBAC with least privilege
       - Managed identities for applications

    3. Encryption:
       - Customer-managed keys (Azure Key Vault)
       - Key rotation every 90 days
       - Separate keys per container

    4. Data Protection:
       - Blob versioning enabled
       - Soft delete (30 days)
       - Immutable storage (WORM compliance)
       - Legal hold for litigation

    5. Monitoring:
       - Storage Analytics logs → Log Analytics
       - Alert on:
         - Anonymous access attempts
         - Failed authentication
         - Key access from Key Vault
         - Blob deletion

    6. Implementation:
       ```bash
       # 1. Disable public access
       az storage account update \
         --name mystorageaccount \
         --public-network-access Disabled

       # 2. Create private endpoint
       az network private-endpoint create \
         --name pe-storage \
         --vnet-name vnet-prod \
         --subnet snet-data \
         --private-connection-resource-id /subscriptions/.../storageAccounts/mystorageaccount \
         --group-ids blob

       # 3. Disable shared key access
       az storage account update \
         --name mystorageaccount \
         --allow-shared-key-access false

       # 4. Enable customer-managed keys
       az storage account update \
         --name mystorageaccount \
         --encryption-key-source Microsoft.Keyvault \
         --encryption-key-vault https://myvault.vault.azure.net \
         --encryption-key-name storage-key

       # 5. Enable versioning and soft delete
       az storage account blob-service-properties update \
         --account-name mystorageaccount \
         --enable-versioning true \
         --enable-delete-retention true \
         --delete-retention-days 30

       # 6. Configure immutable storage (WORM)
       az storage container immutability-policy create \
         --account-name mystorageaccount \
         --container-name compliance \
         --period 2555  # 7 years in days
       ```
    ````
  </Accordion>
</AccordionGroup>

***

## Troubleshooting: Common Storage Failures

When production storage breaks, it usually falls into one of these three buckets.

### 1. The "403 Forbidden" Nightmare

This is the #1 support ticket. If your app can't access a blob:

* **Client IP**: Is your Storage Account Firewall blocking the code's IP? Check if you have a **Private Endpoint** but the code is trying to use the **Public Endpoint**.
* **SAS Token Expiry**: If using SAS tokens, check the clock! Is the system time on your server out of sync with Azure?
* **RBAC Propagation**: Did you just grant the "Storage Blob Data Contributor" role? RBAC changes can take up to **10 minutes** to propagate.

### 2. The "AuthorizationPermissionMismatch"

You have the "Reader" role on the storage account, but you can't see the files in the portal.

* **Why**: "Reader" is a Management Plane role. To see **data** (blobs), you need a Data Plane role like **Storage Blob Data Reader**.

### 3. Capacity and Throughput Bottlenecks

* **Storage Limit**: Standard accounts have a limit of **5 PB**. If you hit this, you need a second account.
* **Egress Limits**: Standard accounts are limited to roughly **50 Gbps** of outbound traffic. If you are serving massive videos to millions of users, you must use a **Content Delivery Network (CDN)** to offload the traffic.

> \[!TIP]
> **Pro Tool: Storage Explorer**
> Don't rely solely on the Azure Portal. Use **Azure Storage Explorer** (desktop app). It provides much better visibility into hidden metadata, lease statuses, and large-scale migrations.

***

## 8. Key Takeaways

<CardGroup cols={2}>
  <Card title="Choose Right Storage Type" icon="database">
    Blob for objects, Files for shares, Disks for VMs. Each optimized for specific use cases.
  </Card>

  <Card title="Use Storage Tiers" icon="layer-group">
    Hot/Cool/Archive can save 90%+ on storage costs. Automate with lifecycle policies.
  </Card>

  <Card title="Enable Data Protection" icon="shield">
    Soft delete, versioning, and snapshots protect against accidents and attacks.
  </Card>

  <Card title="Secure with Private Endpoints" icon="lock">
    Disable public access. Use Azure AD authentication. No shared keys in production.
  </Card>

  <Card title="Optimize Performance" icon="rocket">
    CDN for static content, parallel uploads, proper disk caching, disk striping for IOPS.
  </Card>

  <Card title="Plan for Disaster Recovery" icon="life-ring">
    GRS for critical data, backup strategy with retention policies, test restores regularly.
  </Card>
</CardGroup>

***

## Interview Deep-Dive

<AccordionGroup>
  <Accordion title="Your company stores 500 TB in Blob Storage Hot tier at $9,000/month. The CFO wants to cut costs by 60%. Design a lifecycle management strategy.">
    **Strong Candidate Answer:**

    * **Analyze access patterns first:** Enable Storage Analytics metrics. In my experience, 70-80% of stored data has not been accessed in 90+ days.
    * **Lifecycle management policy:** Move blobs to Cool after 30 days of no access ($5/TB vs $18/TB), Archive after 90 days ($1/TB). For 500 TB typical split: 100 TB Hot ($1,800), 200 TB Cool ($1,000), 200 TB Archive ($200) = \$3,000/month -- 67% reduction.
    * **Archive tier gotcha:** Rehydration takes 1-15 hours. If compliance requires 4-hour access, use Cool instead. Archive also has a 180-day early deletion penalty.
    * **Hidden cost: blob versioning.** Teams enable versioning but forget every version consumes storage at the current tier. I have seen 500 TB of real data with 1,500 TB of versions at Hot pricing. Delete old versions after 30 days.

    **Follow-up: Legal says some data must be retained 7 years and be immutable. How does this affect your strategy?**

    Use immutable blob storage with time-based retention (7 years). Immutable blobs can still change access tiers, so move them to Archive on day 1. Cost for 200 TB compliance data: $200/month for 7 years = $16,800 total, versus \$25,200/year in Hot tier.
  </Accordion>

  <Accordion title="Explain LRS, ZRS, GRS, and RA-GRS. A startup asks which replication to use for their only database backup.">
    **Strong Candidate Answer:**

    * **LRS:** 3 copies in one datacenter. Does NOT survive datacenter-level disasters.
    * **ZRS:** 3 copies across 3 Availability Zones. Survives datacenter failure, not regional disasters.
    * **GRS:** 3 local copies + 3 copies in paired region 300+ miles away. Secondary is NOT readable until Microsoft initiates failover.
    * **RA-GRS:** Same as GRS but secondary is always readable via -secondary endpoint.
    * **For the startup's only backup: GRS minimum.** If the backup is LRS and the datacenter fails catastrophically, both database and backup are lost. Cost difference for 100 GB: $0.80/month (GRS $2/month vs LRS $1.20/month). Losing your entire database to save $0.80/month is indefensible.
    * **Async replication caveat:** GRS has \~15 minute RPO. Combine with Azure SQL geo-replication (5-second RPO) for the live database.

    **Follow-up: They back up nightly. If the primary region fails at 3 PM, they lose the day's data regardless of replication. Acceptable?**

    No. Replication protects against infrastructure failure, not data loss between backups. Use Azure SQL auto-failover groups (RPO \~5 seconds) for the live database, plus nightly GRS backups for logical corruption protection (accidental table drops). These solve different problems and both are needed.
  </Accordion>

  <Accordion title="A developer uploads 10 million small files (1 KB each) to Blob Storage and it takes 8 hours. Total data is 10 GB. Why is it slow?">
    **Strong Candidate Answer:**

    * **The bottleneck is per-request overhead, not bandwidth.** Each upload is a REST API call: TLS handshake, HTTP headers, auth validation, partition lookup, 3-replica write. At 50ms per request sequentially, 10M files = 138 hours. The developer has \~17x concurrency to get 8 hours.
    * **Fix 1 -- Increase parallelism to 200-500 concurrent connections.** Storage accounts support 20,000 requests/second.
    * **Fix 2 -- Use AzCopy.** Optimized for bulk transfers with automatic parallelism and retry. Typically completes this in 1-2 hours.
    * **Fix 3 -- Partition key distribution.** If blobs share a prefix ("data/2024/01/..."), they create a partition hotspot. Prefix with random hash to distribute across partitions.
    * **Fix 4 -- For initial bulk loads of 100M+ files,** use Azure Data Box (physical device shipped to Azure). Faster than any network upload.

    **Follow-up: After optimization, you get 503 Server Busy errors at peak concurrency. What is happening?**

    You are hitting the storage account's \~20,000 requests/second limit. Combined with application traffic on the same account, the total exceeds the ceiling. Fix: use a separate storage account for bulk uploads, or implement exponential backoff with jitter. For sustained high throughput, use Premium Block Blob storage accounts.
  </Accordion>
</AccordionGroup>

***

## Next Steps

<Card title="Continue to Chapter 6" icon="arrow-right" href="/courses/azure-cloud-engineering/06-database-services">
  Master Azure databases: SQL, Cosmos DB, PostgreSQL, and database optimization
</Card>
