Skip to content

Azure Storage

Key Points

  • Four services in Azure Storage account: Blobs (objects), Queues (simple messages), Tables (NoSQL key-value), Files (SMB share).
  • Blob types: Block (general), Append (logs), Page (VHDs/random write).
  • Access tiers: Hot, Cool, Cold, Archive — cost vs retrieval latency tradeoff. Lifecycle policies auto-move.
  • Authentication: Managed Identity (preferred), SAS tokens (delegated, time-limited), Account keys (avoid).
  • .NET SDK: Azure.Storage.Blobs, Azure.Storage.Queues, Azure.Data.Tables, Azure.Storage.Files.Shares. All async; DefaultAzureCredential for auth.

Concepts (deep dive)

What Azure Storage is

Azure Storage is one account, four data services. A storage account is a namespace (myacct.{blob|queue|table|file}.core.windows.net) with a shared RBAC surface, shared encryption settings, and shared redundancy choice. Inside it sit four independent services solving four different storage shapes:

            ┌───────────────────────────────────────────┐
            │       storage account: myacct             │
            │   redundancy, encryption, network rules   │
            └──────────────────┬────────────────────────┘
              ┌────────┬───────┴────────┬────────┐
              ▼        ▼                ▼        ▼
          ┌──────┐ ┌──────┐         ┌──────┐ ┌──────┐
          │Blobs │ │Queues│         │Tables│ │Files │
          │unstr.│ │simple│         │NoSQL │ │SMB   │
          │object│ │msgs  │         │KV    │ │share │
          └──────┘ └──────┘         └──────┘ └──────┘
  • Blobs — unstructured object storage. Photos, PDFs, backups, parquet files, static websites, ML datasets. The headline service; everything else is niche.
  • Queues — simple FIFO-ish message queue. Small payloads, no sessions, no DLQ. Use Service Bus for anything richer.
  • Tables — schemaless key-value rows keyed by PartitionKey + RowKey. Cheap, scales to billions of rows, limited query model. Cosmos DB Table API is the global-scale evolution.
  • Files — SMB / NFS file share. Mount as a network drive; mostly for lift-and-shift of legacy apps that expect a filesystem.

Blob types (and why three of them)

Block, Append, and Page blobs are three distinct internal data structures, each tuned for a different write pattern. The structure determines what operations are efficient and what's not allowed at all.

  • Block blobs are made of independently-uploaded 4 MiB–4000 MiB blocks committed in order. You can replace, reorder, or stage blocks before committing — the model behind multipart upload. This is the right answer for almost every "store a file" use case.
  • Append blobs are write-append-only — efficient for log streams and audit trails where every writer just adds to the tail. Reads are normal; in-place edits are not allowed.
  • Page blobs are 512-byte aligned random-access blobs sized in advance. Made for VHDs and similar block-device emulation. App code rarely creates these directly.

Authentication: managed identity vs SAS vs account keys

Three ways to prove you're allowed to call the data plane, and the differences matter a lot for security posture:

  • Managed identity — the app's Azure-assigned identity, granted an RBAC role on the storage account. No secret stored anywhere. The default for new code.
  • Shared Access Signature (SAS) — a time-limited, scope-limited token in the URL itself. Useful when the caller isn't an Azure resource (a browser uploading directly, an external partner). User-Delegation SAS is the modern variant: signed by an AAD identity instead of the account key, so it's auditable and revocable.
  • Account keys — two long-lived shared secrets that grant full access to the entire account. Convenient and dangerous. Avoid in code; rotate immediately if leaked.

Access tiers (and why they exist)

Azure offers four price/latency points for the same blob. Hot is fast to read and cheap to query but expensive to store; Archive is nearly free to store but takes hours to retrieve and costs real money to read. The point is that most data gets cold fast — a file uploaded today is hot, the same file in two years is almost never accessed. Lifecycle policies are the automation that moves data through tiers without app code.

Blob storage

var client = new BlobServiceClient(
    new Uri("https://myacct.blob.core.windows.net/"),
    new DefaultAzureCredential());

var container = client.GetBlobContainerClient("photos");
await container.CreateIfNotExistsAsync();

var blob = container.GetBlobClient("user-1/avatar.png");
await blob.UploadAsync(stream, overwrite: true);

var data = await blob.DownloadContentAsync();

Blob types

Type Use
Block General-purpose; big files; uploaded as blocks
Append Append-only; logs
Page 512-byte aligned random write; VM disks

For app code, Block is what you want 99% of the time.

Access tiers

Tier Storage cost Retrieval cost Latency
Hot High Low Low
Cool Mid Mid Low
Cold Lower Higher Low
Archive Lowest High Hours (rehydrate)
await blob.SetAccessTierAsync(AccessTier.Cool);

Lifecycle management

{
  "rules": [{
    "name": "MoveToArchive",
    "type": "Lifecycle",
    "definition": {
      "filters": { "blobTypes": ["blockBlob"], "prefixMatch": ["logs/"] },
      "actions": {
        "baseBlob": {
          "tierToCool":    { "daysAfterModificationGreaterThan": 30 },
          "tierToArchive": { "daysAfterModificationGreaterThan": 180 },
          "delete":         { "daysAfterModificationGreaterThan": 365 }
        }
      }
    }
  }]
}

Auto-move blobs across tiers; eventually delete.

SAS tokens

Time-limited URLs:

var sas = blob.GenerateSasUri(BlobSasPermissions.Read, DateTimeOffset.UtcNow.AddHours(1));
// Browser/client uses sas URL directly; no creds needed

Use for direct browser uploads/downloads (CDN-friendly).

User Delegation SAS (preferred): signed by AAD, not account key. Audit trail.

var udk = await client.GetUserDelegationKeyAsync(start, end);
var sasBuilder = new BlobSasBuilder(...);
var sas = sasBuilder.ToSasQueryParameters(udk, accountName).ToString();

Static website hosting

az storage blob service-properties update --account-name myacct \
  --static-website --404-document 404.html --index-document index.html

Blob storage serves static SPA at $web container. Pair with Azure Front Door / CDN.

Queues

var queue = new QueueClient(uri, new DefaultAzureCredential());
await queue.SendMessageAsync(json);
QueueMessage[] msgs = await queue.ReceiveMessagesAsync(maxMessages: 10);
foreach (var m in msgs)
{
    Process(m.Body.ToString());
    await queue.DeleteMessageAsync(m.MessageId, m.PopReceipt);
}

Simple FIFO-ish; up to 64 KB messages. Service Bus is richer for most use cases — Queue Storage for simple ones.

Tables

var table = new TableClient(connStr, "Users");
await table.CreateIfNotExistsAsync();

var entity = new TableEntity("partition1", "rowkey1") { ["Name"] = "Alice" };
await table.AddEntityAsync(entity);

var items = table.Query<TableEntity>(filter: "PartitionKey eq 'partition1'");

Cheap NoSQL key-value (PartitionKey + RowKey). Good for high-volume telemetry. Cosmos DB Table API has same model + global distribution.

Files

var share = new ShareClient(connStr, "myshare");
var dir = share.GetRootDirectoryClient();
var file = dir.GetFileClient("data.csv");
await file.UploadAsync(stream);

SMB-mountable file share. Common for lift-and-shift.

Storage account types

Type Use
Standard general-purpose v2 Default
Premium (Block Blob) Low-latency Blobs
Premium (File) High-perf SMB
Premium (Page Blob) High-IOPS VHDs

Redundancy

Azure replicates your data automatically; the redundancy setting controls how many copies and how geographically spread. Each tier survives a strictly larger failure mode than the one before — LRS survives disk failure but not a DC fire; ZRS survives a DC outage; GRS survives losing a whole region. You pay for the spread.

  • LRS: Locally redundant (3 copies in same DC).
  • ZRS: Zone-redundant (across AZs in region).
  • GRS: Geo-redundant (LRS + async replica in paired region).
  • RA-GRS: Read-access GRS.
  • GZRS: Geo + zone (highest).

Cost increases up the list.

Encryption

Encrypted at rest by default (Microsoft-managed keys). Customer-managed keys (BYOK) via Key Vault for compliance.

In transit: HTTPS-only (default).

Immutable storage

await container.SetImmutabilityPolicyAsync(period: 30);

WORM (Write Once, Read Many). For compliance — can't delete or modify.

Soft delete

az storage blob service-properties update --enable-delete-retention true --delete-retention-days 7

Deleted blobs kept for N days; restorable.

Versioning

Each modification = new version. Roll back to previous.

Network access

  • Public endpoint (default).
  • Service endpoint (VNet allowlist).
  • Private endpoint (VNet-only access; preferred for security).
var client = new BlobServiceClient(new Uri("https://myacct.privatelink.blob.core.windows.net/"), credential);

CDN integration

Front Door / CDN in front of Blob storage for global distribution + caching.

Storage Explorer

GUI tool for browsing containers, queues, tables, files. Great for debugging.


Code: correct vs wrong

❌ Wrong: account key in code

new BlobServiceClient(connStr);   // contains AccountKey=...

✅ Correct: managed identity

new BlobServiceClient(new Uri("https://myacct.blob.core.windows.net/"), new DefaultAzureCredential());

❌ Wrong: SAS without expiry

sas.ExpiresOn = DateTimeOffset.MaxValue;

✅ Correct: short-lived SAS

sas.ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(15);

Design patterns for this topic

Pattern 1 — "Managed identity over keys"

  • Intent: zero-secret access.

Pattern 2 — "Lifecycle policies for cost"

  • Intent: auto-tiering; auto-delete.

Pattern 3 — "User delegation SAS"

  • Intent: AAD-signed; auditable.

Pattern 4 — "Direct upload via SAS"

  • Intent: offload bandwidth; bypass app server.

Pattern 5 — "Private endpoint for prod"

  • Intent: no public access.

Pros & cons / trade-offs

Service Pros Cons
Blob Cheap; tiers Eventually consistent for some ops
Queue Simple Limited features
Table Cheap NoSQL Limited query
Files SMB Not cloud-native

When to use / when to avoid

  • Use Blob for binary objects, backups, static sites.
  • Use Queue for simple work distribution.
  • Use Table for high-volume key-value telemetry.
  • Use Files for lift-and-shift.
  • Avoid account keys; use managed identity.

Interview Q&A

Q1. Four services in Storage Account? Blobs, Queues, Tables, Files.

Q2. Block vs Append vs Page Blob? Block: general. Append: logs. Page: VHDs/random IO.

Q3. Access tiers? Hot/Cool/Cold/Archive. Cost vs retrieval latency.

Q4. Lifecycle policy? Auto-tier or delete based on age, prefix.

Q5. SAS vs Managed Identity? SAS: time-limited URL; share with clients. MI: app-side; no token in client.

Q6. User delegation SAS benefit? Signed by AAD; auditable; revocable via AAD.

Q7. Private endpoint? VNet-only access to storage; no public.

Q8. Soft delete? Deleted items retained for N days; restorable.

Q9. WORM? Immutable storage; compliance.

Q10. GRS vs LRS? GRS replicates async to paired region; survives regional outage.

Q11. Storage Queue vs Service Bus? Storage Queue: simple, cheap. Service Bus: richer (sessions, DLQ, transactions, topics).

Q12. Table Storage vs Cosmos Table API? Same data model. Cosmos: global distribution, multi-master, predictable perf, SLAs.


Gotchas / common mistakes

  • ⚠️ Account key in source.
  • ⚠️ SAS forever.
  • ⚠️ Public access in prod.
  • ⚠️ Hot tier for archival data — wasted money.
  • ⚠️ No lifecycle — costs grow forever.

Further reading