This chapter covers the design considerations for choosing between Azure Table Storage and Azure Cosmos DB for non-relational data storage, a key decision area in the AZ-305 Data Storage domain. Approximately 10-15% of exam questions touch on comparing these two services, focusing on when to use each based on latency, throughput, indexing, global distribution, and cost. Mastering this topic requires understanding the underlying architectures, consistency models, and pricing trade-offs to recommend the right solution for given requirements.
Jump to a section
Azure Table Storage is like a massive warehouse with rows of shelves. Each shelf is a partition, and each item stored has a RowKey and PartitionKey. To find an item, you must know its exact shelf (PartitionKey) and its unique ID (RowKey). If you only know the item’s name, you have to walk every aisle—a full table scan. The warehouse is cheap per square foot but slow for complex searches. Cosmos DB, by contrast, is like an automated library with a computerized catalog. Every book (document) can be found by author, title, subject, or any indexed field—instant lookups via multiple indexes. The library has high-speed robotic retrieval (single-digit millisecond latency) and can automatically replicate its catalog across multiple cities (global distribution). However, the automation comes at a higher cost per query. The warehouse is ideal for storing millions of low-cost items accessed only by a known key, while the library is built for rapid, flexible searches where speed and global access matter more than storage cost.
What Are Azure Table Storage and Cosmos DB?
Azure Table Storage is a NoSQL key-value store that is part of Azure Storage. It offers a schema-less design where each entity is a set of properties (up to 255) with two mandatory keys: PartitionKey and RowKey. It provides high scalability (up to 20 TB per table, 500 TB per storage account) and is cost-effective for large volumes of data accessed by known keys. Table Storage is a fully managed service with automatic failover, geo-redundancy options, and a simple REST API. However, it has limited indexing (only on PartitionKey and RowKey), no secondary indexes, and eventual consistency by default.
Azure Cosmos DB is a globally distributed, multi-model database service that supports document, key-value, graph, and column-family data models via APIs like SQL, MongoDB, Cassandra, Gremlin, and Table. The Table API in Cosmos DB provides a drop-in replacement for Azure Table Storage with significant enhancements: single-digit millisecond latency at any scale, automatic secondary indexing on all properties, multiple consistency levels (strong, bounded staleness, session, consistent prefix, eventual), and global distribution with multi-region writes. Cosmos DB is throughput-provisioned (Request Units per second) or serverless, and can handle up to 10 TB per container (with partitioning) and unlimited storage via partition splits.
Internal Architecture and Mechanism
Azure Table Storage uses a flat namespace of tables within a storage account. Each table is partitioned by PartitionKey, which determines the physical server (partition server) that hosts the data. All entities with the same PartitionKey are stored together, enabling efficient point queries (PartitionKey + RowKey). The service automatically load-balances partitions across servers based on size and throughput. Writes are first committed to a primary region and then asynchronously replicated to secondary regions (if geo-replication is enabled). Reads from the primary are strongly consistent; reads from secondary are eventually consistent. There is no built-in support for automatic failover across regions; manual failover via PowerShell or CLI is required.
Cosmos DB uses a hash-based partitioning scheme. Each container (table) has a partition key; data is distributed across physical partitions based on the hash of the partition key value. Each physical partition is a set of replicas (at least 3) that use a replicated state machine for high durability. Writes are committed to a quorum of replicas within a region before acknowledgment. For multi-region writes, Cosmos DB uses a multi-master replication protocol, allowing any region to accept writes. The consistency level is applied per request; strong consistency uses synchronous replication across regions, while others use asynchronous replication with bounded staleness. Indexing is automatic and comprehensive: every property is indexed by default, and you can customize indexing policies (include/exclude paths, composite indexes).
Key Components, Values, and Defaults
Azure Table Storage: - Maximum entity size: 1 MB (including all properties). - Maximum table size: 500 TB per storage account. - Maximum storage account size: 500 TB total across all services. - PartitionKey length: 1-1024 characters (string). - RowKey length: 1-1024 characters (string). - Default consistency: Eventual (for read operations from secondary). - Throughput target: Up to 20,000 IOPS per partition (for point queries). - Pricing: ~$0.045 per GB/month for LRS; $0.10 per GB/month for GRS.
Cosmos DB Table API: - Maximum item size: 2 MB (for SQL API; 1 MB for Table API). - Maximum container size: Unlimited (up to 10 TB per container, then partitions can split). - Default consistency: Session (if not specified). - Throughput: Provisioned from 400 RU/s to unlimited; autoscale from 400 RU/s max. - Latency: <10 ms for reads and writes at P99 within same region. - Pricing: Provisioned throughput (~$0.008 per RU/hour) + storage (~$0.25 per GB/month). - Global distribution: Up to 50+ regions; multi-region writes available.
Configuration and Verification Commands
Azure Table Storage CLI commands:
# Create table
az storage table create --account-name mystorageaccount --name mytable
# Insert entity
az storage entity insert --account-name mystorageaccount --table-name mytable --entity PartitionKey=pk RowKey=rk Name=John Age=30
# Query entity
az storage entity query --account-name mystorageaccount --table-name mytable --partition-key pk --row-key rk
# List tables
az storage table list --account-name mystorageaccountCosmos DB Table API CLI commands (using az cosmosdb):
# Create Cosmos DB account
az cosmosdb create --name mycosmosaccount --resource-group myrg --kind GlobalDocumentDB --capabilities EnableTable
# Create table
az cosmosdb table create --account-name mycosmosaccount --resource-group myrg --name mytable --throughput 400
# Insert item (via REST or SDK, not CLI directly)
# Use Azure Portal or SDK to insertInteraction with Related Technologies
Both services integrate with Azure Functions, Logic Apps, and Event Grid for event-driven architectures. Cosmos DB's change feed (via SQL API) enables real-time processing of inserts/updates; Table Storage does not have a native change feed but can use Azure Storage Analytics logs. Cosmos DB integrates with Azure Cognitive Search for full-text search; Table Storage requires separate indexing. Both support Azure Private Link for private endpoints. Cosmos DB provides built-in TTL (time-to-live) for automatic data expiration; Table Storage requires custom logic. Cosmos DB's multi-region writes enable active-active configurations; Table Storage is active-passive with manual failover.
Assess Requirements
Begin by gathering requirements: latency (Cosmos DB <10 ms vs Table Storage ~10-50 ms), throughput (Cosmos DB provisioned RU/s vs Table Storage up to 20K IOPS per partition), global distribution (Cosmos DB multi-region writes vs Table Storage manual GRS failover), indexing needs (Cosmos DB automatic secondary indexes vs Table Storage only PK/RK), consistency (Cosmos DB five levels vs Table Storage eventual for secondary reads), and cost (Table Storage ~$0.045/GB vs Cosmos DB ~$0.25/GB plus RU/s). This step determines which service aligns with the SLA and budget.
Evaluate Data Model
If the data is purely key-value with simple lookups by PartitionKey+RowKey, Table Storage is sufficient. If queries involve filtering on non-key properties (e.g., "all orders by customer ID where status=active"), Cosmos DB's automatic indexing on all properties avoids full table scans. Also consider entity size: Table Storage max 1 MB; Cosmos DB max 2 MB (1 MB for Table API). If data exceeds 1 MB, use Cosmos DB or store blobs with pointers.
Determine Consistency Needs
For applications requiring strong consistency (e.g., inventory, account balances), Cosmos DB with strong consistency guarantees linearizability. Table Storage provides strong consistency only for reads from primary; secondary reads are eventual. If multi-region writes are needed, Cosmos DB is the only option. For most applications, session consistency (Cosmos DB default) is sufficient and offers better performance than strong.
Plan for Scalability
Table Storage scales up to 500 TB per storage account, but partition sizes are limited to 20 TB. If data grows beyond, multiple storage accounts are needed. Cosmos DB scales horizontally with partition splits automatically up to unlimited storage. Throughput in Table Storage is limited by partition IOPS (20K) and storage account limits (20K requests/sec). Cosmos DB can provision millions of RU/s across regions. For high throughput (e.g., IoT telemetry), Cosmos DB is more suitable.
Calculate Cost
Cost comparison: For 1 TB data with 1,000 operations/sec, Table Storage cost ~$45/month (storage) + minimal transaction costs. Cosmos DB for same data: storage ~$250/month + throughput cost (1,000 RU/s = ~$240/month) = ~$490/month. However, if queries require secondary indexes, Table Storage would need additional processing (e.g., Azure Search), adding cost. Always model total cost including compute for data transformation and indexing if using Table Storage.
Scenario 1: IoT Telemetry Ingestion
A manufacturing company collects sensor data from thousands of devices every second. Each reading is small (few hundred bytes) and accessed by device ID and timestamp. Requirements: 50,000 writes/sec, sub-10 ms write latency, and occasional reads by device ID. Solution: Cosmos DB with Table API, provisioned 100,000 RU/s (autoscale), single-region writes with session consistency. Partition key: deviceId. Cost: ~$24,000/month. Alternative: Azure Table Storage would hit partition limits (20,000 IOPS per partition) and require multiple storage accounts and custom partitioning (e.g., by device group). Misconfiguration: Using Table Storage with a single partition key (e.g., all devices under one partition) would throttle writes at 20,000 ops/sec and cause 429 errors.
Scenario 2: User Profile Store
A global social media app stores user profiles (2 KB each) for 500 million users. Profiles are read frequently by userId, rarely updated. Need low latency reads globally (under 10 ms) and multi-region writes for disaster recovery. Solution: Cosmos DB with SQL API, partition key userId, strong consistency for writes, session for reads. Multi-region writes enabled across three regions. Cost: ~$500,000/month. Alternative: Table Storage with GRS would provide eventual consistency for reads from secondary regions, and manual failover could cause minutes of downtime. Misconfiguration: Using Table Storage with a single storage account for all users would exceed the 500 TB limit (500M * 2 KB = 1 TB, fine), but without secondary indexes, queries by email or username would require full table scans.
Scenario 3: Audit Logging
A financial institution needs to store 10 TB of audit logs per year, accessed only for compliance investigations by timestamp range. Latency of 1 second is acceptable. Budget is tight. Solution: Azure Table Storage with PartitionKey = date (e.g., 2025-03-17) and RowKey = timestamp. This allows efficient range queries. Cost: ~$450/month for storage + minimal transaction costs. Misconfiguration: Using Cosmos DB for this would cost ~$2,500/month for storage alone plus RU/s, overkill for the performance needs. Conversely, using Table Storage for a real-time dashboard requiring sub-second queries on multiple fields would require building a separate indexing layer (e.g., Azure Search), complicating the architecture.
What AZ-305 Tests (Objective 2.3)
The exam focuses on selecting the appropriate data storage solution based on requirements. Key codes: 2.3.1 (design for data storage), 2.3.2 (design for data partitioning), 2.3.3 (design for data replication and distribution). Expect scenario-based questions where you must choose between Table Storage and Cosmos DB Table API.
Common Wrong Answers and Why
Choosing Table Storage for global distribution with multi-region writes: Table Storage does not support multi-region writes. Candidates assume GRS provides this, but GRS is active-passive with manual failover. Cosmos DB is required for multi-master.
Selecting Cosmos DB for low-cost archival storage: Cosmos DB is expensive for infrequently accessed data. Table Storage or Azure Blob Storage (cool/archive tier) is cheaper.
Assuming Table Storage has secondary indexes: It does not. Queries on non-key properties require full table scans. Cosmos DB indexes all properties by default.
Thinking Cosmos DB Table API is identical to Table Storage: Cosmos DB Table API uses RU/s pricing, has different throughput scaling, and supports multiple consistency levels. Candidates may overlook the cost implications.
Specific Numbers and Terms
Table Storage max entity size: 1 MB. Cosmos DB SQL API: 2 MB; Table API: 1 MB.
Table Storage max table size: 500 TB per storage account.
Cosmos DB default consistency: Session.
Cosmos DB throughput minimum: 400 RU/s (provisioned) or autoscale (400 max).
Table Storage partition throughput: up to 20,000 IOPS per partition.
Cosmos DB latency: <10 ms at P99 for reads/writes in same region.
Edge Cases and Exam Traps
Query patterns: If the query uses PartitionKey and RowKey, Table Storage is efficient. If the query filters on other properties, Cosmos DB is better. Exam may present a query that uses a secondary index implicitly (e.g., "find users by email").
Consistency: If strong consistency is required, Table Storage only provides it for primary reads. For multi-region strong consistency, Cosmos DB is needed.
Data size: If entities exceed 1 MB, Table Storage cannot store them. Cosmos DB can store up to 2 MB.
Throughput: If sustained throughput exceeds 20,000 ops/sec per partition, Table Storage will throttle. Cosmos DB can scale to millions of RU/s.
Eliminating Wrong Answers
Ask: Does the requirement include global distribution with writes from multiple regions? → Cosmos DB. Is cost the primary driver and queries are simple key lookups? → Table Storage. Does the application need to query on multiple properties? → Cosmos DB. Is latency critical (<10 ms)? → Cosmos DB. Is the data archival with infrequent access? → Table Storage or Blob Storage.
Azure Table Storage is ideal for simple key-value lookups with low cost, but lacks secondary indexes and global multi-region writes.
Cosmos DB Table API provides automatic indexing on all properties, multiple consistency levels, and sub-10 ms latency globally.
Table Storage max entity size is 1 MB; Cosmos DB SQL API allows 2 MB (but Table API also 1 MB).
Table Storage partitions limit throughput to ~20,000 IOPS; Cosmos DB scales to millions of RU/s.
Cosmos DB default consistency is Session; Table Storage default is Eventual (for secondary reads).
For multi-region writes, Cosmos DB is required; Table Storage only supports active-passive with manual failover.
Cost: Table Storage is cheaper for infrequent access; Cosmos DB costs more due to provisioned throughput.
When queries involve filtering on non-key properties, choose Cosmos DB to avoid full table scans.
These come up on the exam all the time. Here's how to tell them apart.
Azure Table Storage
Cost-effective: ~$0.045/GB/month for LRS
Simple key-value store with only PK/RK indexes
Max entity size: 1 MB
Up to 20,000 IOPS per partition
Eventual consistency for secondary reads; strong only on primary
Cosmos DB Table API
Higher cost: ~$0.25/GB/month + RU/s
Automatic secondary indexing on all properties
Max entity size: 1 MB (Table API) or 2 MB (SQL API)
Unlimited throughput via RU scaling (millions RU/s)
Five consistency levels including strong and session; global distribution
Mistake
Azure Table Storage supports secondary indexes like Cosmos DB.
Correct
Azure Table Storage only indexes the PartitionKey and RowKey. All other properties are unindexed. Queries on non-key properties result in a full table scan. Cosmos DB automatically indexes every property by default.
Mistake
Azure Table Storage provides strong consistency for all reads.
Correct
Table Storage provides strong consistency only for reads from the primary region. Reads from secondary regions (if geo-replication is enabled) are eventually consistent. Cosmos DB offers five consistency levels including strong.
Mistake
Cosmos DB Table API is identical to Azure Table Storage in pricing.
Correct
Cosmos DB uses provisioned throughput (RU/s) pricing, which can be significantly more expensive than Table Storage's consumption-based model. Table Storage charges per GB and per transaction, while Cosmos DB charges per RU/hour plus storage.
Mistake
Table Storage can handle any amount of throughput without throttling.
Correct
Table Storage partitions have a throughput limit of approximately 20,000 IOPS per partition. If requests to a single partition exceed this, requests are throttled (HTTP 429). Cosmos DB can scale throughput per partition to much higher levels.
Mistake
Cosmos DB is always the best choice for NoSQL workloads.
Correct
Cosmos DB is overkill and too expensive for simple key-value stores with low throughput and latency requirements. Azure Table Storage is more cost-effective for such scenarios, especially when data is accessed by a known key.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
Choose Table Storage when your workload is simple key-value lookups by PartitionKey and RowKey, latency requirements are moderate (tens of ms), throughput per partition is under 20,000 IOPS, and cost is a primary concern. Table Storage is also suitable for archival data where you don't need secondary indexes or global distribution. For example, storing audit logs by date is a classic use case.
Cosmos DB Table API is a superset of Azure Table Storage. It supports the same Table REST API and SDKs, but adds automatic secondary indexing, multiple consistency levels (including strong and session), global distribution with multi-region writes, and provisioned throughput (RU/s). However, it is priced differently and may be more expensive.
Yes, you can migrate using Azure Data Factory or the Cosmos DB Data Migration Tool. The schema is compatible because both use the same Table API. However, you need to provision throughput in Cosmos DB, which may increase costs. Plan for downtime or use a dual-write strategy during migration.
Requests are throttled and return HTTP 429 (Too Many Requests). You can either reduce the request rate, increase the number of partitions, or use multiple storage accounts. Cosmos DB handles throttling by suggesting a retry-after interval and can scale throughput if autoscale is enabled.
Yes, Cosmos DB Table API supports multi-region writes. You can configure multiple write regions, and writes are conflict-resolved using a last-writer-wins (LWW) policy. This enables active-active configurations for low-latency global applications.
Azure Table Storage only indexes PartitionKey and RowKey. To query on other properties, you must perform a full table scan. Cosmos DB Table API automatically indexes all properties by default, and you can customize the indexing policy to include or exclude paths. This makes queries on non-key properties efficient.
Azure Table Storage can hold up to 500 TB per storage account (across all tables). Cosmos DB containers can scale to unlimited storage as partitions split automatically, but each container starts with a max of 10 TB before splits occur.
You've just covered Azure Table Storage vs Cosmos DB Design — now see how well it sticks with free AZ-305 practice questions. Full explanations included, no account needed.
Done with this chapter?