Azure Table Storage is a NoSQL datastore that provides a flexible, scalable, and cost-effective solution for storing structured, non-relational data in the cloud. With its schema-less design and ability to scale horizontally, it offers unique advantages for many modern application scenarios. This guide walks you through everything you need to know to effectively implement and leverage Azure Table Storage in your projects.
Azure Table Storage is a service that stores structured NoSQL data in the cloud, providing a key-attribute store with a schema-less design. Unlike traditional relational databases that require predefined schemas, Table Storage allows you to store heterogeneous data structures, making it exceptionally flexible for evolving application needs.
Note: Azure offers two services for table-based storage: Azure Table Storage and Cosmos DB Table API. While Azure Table Storage remains cost-effective for many use cases, Microsoft recommends Cosmos DB Table API for new projects due to its enhanced features, global distribution, and stronger SLAs.
Before diving into implementation, it's important to understand the core components of Azure Table Storage:
The combination of PartitionKey and RowKey forms a unique identifier for each entity within a table.
Azure Table Storage is ideal for:
Note: Use General-purpose v2 accounts to ensure Table service support.
Click + Add Table, enter a name, and create it
Read our other Azure articles:
Azure Automation: A Complete Guide
Azure Cost Management
Azure Cost Optimization
Install the SDK:
Install-Package Azure.Data.Tables
Connect and create the table:
var serviceClient = new TableServiceClient(
new Uri("https://<yourstorageaccount>.table.core.windows.net"),
new TableSharedKeyCredential("<account-name>", "<account-key>"));
var tableClient = serviceClient.GetTableClient("customers");
await tableClient.CreateIfNotExistsAsync();
Use the Azure.Data.Tables package. The older Microsoft.Azure.Cosmos.Table SDK is deprecated.
GET https://<account>.table.core.windows.net/Customers
x-ms-date: Tue, 13 May 2025 08:00:00 GMT
x-ms-version: 2020-06-12
Authorization: SharedKey <account>:<signature>
Accept: application/json;odata=nometadata
Entities must include a PartitionKey and RowKey. Here's an example:
var entity = new TableEntity("Seattle", "001")
{
["FirstName"] = "John",
["LastName"] = "Doe",
["Email"] = "john.doe@example.com"
};
await tableClient.AddEntityAsync(entity);
Design tip:
var entity = await tableClient.GetEntityAsync<TableEntity>("Seattle", "001");
var results = tableClient.Query<TableEntity>(filter: $"PartitionKey eq 'Seattle'");
var results = tableClient.Query<TableEntity>(filter: $"Email ne null and endswith(Email, 'gmail.com')");
var entity = await tableClient.GetEntityAsync<TableEntity>("Seattle", "001");
entity["PhoneNumber"] = "555-123-4567";
await tableClient.UpdateEntityAsync(entity, ETag.All);
await tableClient.DeleteEntityAsync("Seattle", "001");
var batch = new List<TableTransactionAction>();
for (int i = 1; i <= 5; i++)
{
var entity = new TableEntity("Seattle", $"00{i}")
{
["Name"] = $"Customer {i}",
["Status"] = "Active"
};
batch.Add(new TableTransactionAction(TableTransactionActionType.Add, entity));
}
await tableClient.SubmitTransactionAsync(batch);
var query = tableClient.Query<TableEntity>(
filter: $"PartitionKey eq 'Seattle'",
maxPerPage: 100);
await foreach (var page in query.AsPages())
{
foreach (var entity in page.Values)
{
Console.WriteLine($"{entity["FirstName"]} {entity["LastName"]}");
}
}
Azure Table Storage is a lightweight, scalable NoSQL solution best suited for structured data without relational constraints. With proper partitioning, efficient querying, and simple SDK integration, it becomes a powerful component in cloud-native applications—especially when cost, flexibility, and scale matter most.