This chapter covers designing non-relational (NoSQL) database solutions in Azure, focusing on Azure Cosmos DB and Azure Table Storage. For the AZ-305 exam, this topic area appears in approximately 10-15% of questions, often integrated into broader solution design scenarios. You will learn to choose the right database for workload requirements, configure consistency, partition data, and optimize performance. Mastering these concepts is critical for designing scalable, globally distributed data solutions.
Jump to a section
Imagine a global mailroom system for a company with offices in New York, London, and Tokyo. Each office has its own mailroom that can accept and send packages. The company uses a single, unified package tracking system where every package has a unique ID. When a package is sent from New York to London, the New York mailroom records it locally and immediately sends a copy to the London mailroom. The London mailroom acknowledges receipt. The system guarantees that once the sender gets confirmation, the package is safely stored in London. If the New York mailroom fails before sending, the package is still safe in New York. The mailroom can also handle many package types: documents, parcels, fragile items—each with different handling rules (like different consistency levels). The system allows the company to choose how strongly to enforce that all mailrooms see the same package at the same time: strong consistency means all mailrooms must acknowledge before the sender gets confirmation; eventual consistency means the sender gets confirmation as soon as one mailroom accepts, and others will get it eventually. This mirrors Azure Cosmos DB's global distribution: each region has a replica; writes are committed in one region and asynchronously replicated; consistency levels control the trade-off between latency and staleness.
What Are Non-Relational Databases and Why They Exist
Non-relational databases (NoSQL) are designed to handle data that does not fit neatly into tables with fixed schemas. They provide flexible schemas, horizontal scaling, and high performance for specific access patterns. In Azure, the primary non-relational offerings are Azure Cosmos DB and Azure Table Storage (which is part of Azure Storage). Azure Cosmos DB is a fully managed, globally distributed, multi-model database service that supports document, key-value, graph, and column-family data models. Azure Table Storage is a key-value store for structured NoSQL data, offering lower cost but limited features.
How Azure Cosmos DB Works Internally
Azure Cosmos DB is built on a proprietary distributed database engine that uses a resource-governed, multi-tenant architecture. Data is stored in containers (collections, tables, graphs) that are partitioned across physical nodes. Each partition is replicated across multiple regions for global distribution. Writes are committed to a single region (the write region) and asynchronously replicated to other regions. Reads can be served from any region, depending on the consistency level chosen.
Partitioning: Cosmos DB uses partition keys to distribute data. Each logical partition has a maximum size of 20 GB. Physical partitions are managed by the system. The partition key is hashed to determine the physical partition. Choosing a good partition key is crucial for performance: it should have high cardinality and evenly distribute request units (RU) and storage.
Request Units (RUs): RUs are a measure of throughput. Each operation (read, write, query) consumes RUs based on item size, index size, and operation type. A 1 KB point read costs 1 RU. A 1 KB write costs 5 RUs. Queries cost more depending on complexity. You provision throughput at the container or database level. Autoscale allows throughput to scale automatically based on demand.
Consistency Levels: Cosmos DB offers five consistency levels (from strongest to weakest): Strong, Bounded Staleness, Session, Consistent Prefix, and Eventual. Strong consistency guarantees linearizability: writes are visible to all reads immediately but increases latency and reduces availability during region failures. Eventual offers the lowest latency but no ordering guarantees. Session is the default, providing monotonic reads and writes within a session. Bounded Staleness allows a configurable staleness window (time or operations). Consistent Prefix guarantees that reads never see out-of-order writes.
Multi-Master Writes: Cosmos DB supports multi-region writes, allowing writes to be accepted in any region. Conflict resolution policies (last-writer-wins or custom) handle concurrent updates. This provides high availability but requires careful conflict handling.
Indexing: By default, Cosmos DB indexes all properties. You can customize indexing policies to include or exclude paths, set index types (range, spatial, composite), and configure precision. Indexing consumes RUs and storage.
Azure Table Storage
Azure Table Storage is a key-value store that offers a simpler, lower-cost alternative for structured NoSQL data. It is part of Azure Storage and is accessed via REST API. Tables store entities (rows) with properties (columns). Each entity has a partition key and row key, forming a composite primary key. Partition key determines the partition (physical storage). Row key uniquely identifies an entity within a partition. Table Storage offers eventual consistency by default, with strong consistency available for reads within a partition using the Accept: application/json;odata=nometadata header.
Key Components and Defaults
Azure Cosmos DB:
Default consistency: Session
Max partition size: 20 GB per logical partition
RU charge for 1 KB point read: 1 RU
RU charge for 1 KB write: 5 RU
Autoscale max RU/s: up to 1,000,000 RU/s (subject to quota)
Multi-master: enabled via multiple write regions
Azure Table Storage:
Default consistency: Eventual
Max table size: 500 TiB
Max entity size: 1 MiB
Max number of properties: 255 (including partition key, row key, and timestamp)
Partition key size: up to 1 KiB (string), row key size: up to 1 KiB
Configuration and Verification
Azure Cosmos DB: - Create a Cosmos DB account via Azure CLI:
az cosmosdb create --name mycosmosdb --resource-group myrg --locations regionName=eastus failoverPriority=0 isZoneRedundant=falseList account keys:
az cosmosdb keys list --name mycosmosdb --resource-group myrgSet throughput on a container:
az cosmosdb sql container throughput update --account-name mycosmosdb --database-name mydb --name mycontainer --resource-group myrg --throughput 400Azure Table Storage: - Create a storage account:
az storage account create --name mystorageaccount --resource-group myrg --location eastus --sku Standard_LRS --kind StorageV2Create a table:
az storage table create --name mytable --account-name mystorageaccountInsert an entity (using PowerShell):
$entity = @{
"PartitionKey" = "p1"
"RowKey" = "r1"
"Name" = "John"
}
Add-AzTableRow -Table $table -PartitionKey $entity.PartitionKey -RowKey $entity.RowKey -Property @{"Name"="John"}Interaction with Related Technologies
Azure Cosmos DB integrates with Azure Functions (triggers and bindings), Azure Synapse Link (HTAP), Azure Cognitive Search (indexing), and Azure Data Factory (ETL). It also supports change feed for event-driven architectures. Azure Table Storage is often used with Azure Functions and Azure Logic Apps for simple data storage, and can be accessed via the Azure Storage SDK.
Performance Considerations
For Cosmos DB, partition key selection is critical. A bad partition key can cause hot partitions, leading to throttling (429 errors). Use high-cardinality keys like user IDs or device IDs. Avoid date-based keys that cause sequential writes to one partition. For Table Storage, choose a partition key that distributes load evenly. Use row key for efficient point queries.
Cost Optimization
Cosmos DB costs are based on provisioned throughput (RU/s) and storage. Use autoscale for variable workloads. Reserved capacity offers discounts for 1-3 year commitments. Table Storage is cheaper but limited to 20,000 IOPS per partition and 500 TiB total. Choose Table Storage for low-cost, simple key-value storage with minimal latency requirements.
1. Identify Data Access Patterns
Analyze the workload: read-heavy vs write-heavy, latency requirements, global distribution needs. For example, an IoT telemetry ingestion system may write millions of events per second with low latency tolerance. A product catalog may be read-heavy with infrequent updates. This step determines whether to use Cosmos DB (multi-model, global distribution) or Table Storage (low-cost, simple key-value). Also assess consistency requirements: financial transactions may need strong consistency, while social media feeds can tolerate eventual consistency.
2. Choose the Data Model
Cosmos DB supports document (SQL API), key-value (Table API), column-family (Cassandra API), and graph (Gremlin API). For Table Storage, the data model is fixed: entities with partition key and row key. For Cosmos DB, if data is hierarchical and queried by multiple fields, use SQL API. If data is simple key-value with high throughput, use Table API. If existing Cassandra workloads, use Cassandra API. For graph relationships, use Gremlin API. This choice affects query capabilities, indexing, and consistency options.
3. Design Partitioning Strategy
For Cosmos DB, select a partition key that evenly distributes RU consumption and storage. Avoid keys with few distinct values (e.g., 'status' with only 'active' and 'inactive'). For Table Storage, partition key determines the partition; use a key that spreads entities across partitions (e.g., user ID). Row key should uniquely identify the entity. In Cosmos DB, logical partition size limit is 20 GB; if exceeded, choose a different partition key. For Table Storage, partition key size is limited to 1 KiB.
4. Configure Consistency and Replication
For Cosmos DB, choose the consistency level based on the trade-off between strong guarantees and performance. For globally distributed apps, enable multi-region writes to reduce write latency. For Table Storage, consistency is eventual by default; for strong consistency, use the 'Accept: application/json;odata=nometadata' header on reads. Configure replication: Cosmos DB replicates across regions; Table Storage replicates at the storage account level (LRS, GRS, RA-GRS). For high availability, use multi-region Cosmos DB or RA-GRS for Table Storage.
5. Provision Throughput and Scale
For Cosmos DB, provision RU/s at the container or database level. Use autoscale for unpredictable workloads. Monitor throttling (HTTP 429) and adjust. For Table Storage, throughput is limited to 20,000 IOPS per partition (assuming 1 KiB entities). Scale by adding more partitions. For Cosmos DB, use reserved capacity for cost savings. For Table Storage, consider using Azure Table Storage with Azure Functions to handle spikes. Verify performance with load testing and adjust partition keys or indexing policies if needed.
Scenario 1: Global E-Commerce Product Catalog
A multinational e-commerce company needs a product catalog accessible from multiple regions with low latency reads and occasional writes. They choose Azure Cosmos DB with SQL API, multi-region writes enabled, and Session consistency. The partition key is productId (high cardinality). They provision 100,000 RU/s with autoscale. During a Black Friday sale, traffic spikes to 500,000 RU/s; autoscale handles it. Misconfiguration: initially they used category as partition key, causing hot partitions for popular categories (e.g., 'Electronics' had 50 GB of data, exceeding 20 GB limit). They had to migrate to a new container with productId partition key.
Scenario 2: IoT Sensor Telemetry
A manufacturing company collects sensor data from thousands of IoT devices. Each device sends a reading every second. They need high write throughput and low cost. They choose Azure Table Storage. Partition key is deviceId, row key is timestamp (reverse ticks for newest-first). They use a storage account with LRS and enable Azure Functions to aggregate data hourly. Common issue: write throttling when many devices share the same partition key (e.g., all devices in a factory with factoryId as partition key). Solution: use deviceId as partition key to distribute writes. They also use Table Storage's batch operations (up to 100 entities per batch) to improve throughput.
Scenario 3: Social Media Feed
A social media app stores user posts in Azure Cosmos DB using Table API. They need global distribution for users worldwide. They enable multi-region writes with last-writer-wins conflict resolution. Partition key is userId, row key is postId. Consistency is Eventual for low latency. They provision 10,000 RU/s per container. During a viral event, one user becomes a hot partition (millions of followers reading and writing). They mitigate by using a composite partition key (e.g., userId_region) to distribute load. They also use the change feed to index posts in Azure Cognitive Search for full-text search.
AZ-305 Objective Codes: This chapter aligns with objective 2.3: Design a non-relational database solution. Sub-objectives include: select the appropriate Azure service (Cosmos DB vs Table Storage), configure consistency, design partitioning, and plan for global distribution.
Common Wrong Answers and Why Candidates Choose Them: 1. Choosing Strong consistency for all workloads – Candidates think stronger is always better. Reality: Strong consistency reduces availability and increases latency. The exam expects you to choose the weakest acceptable consistency based on business requirements. 2. Using Table Storage for globally distributed, low-latency reads – Table Storage does not natively support multi-region writes or low-latency reads from multiple regions. Cosmos DB is needed for global distribution. 3. Selecting a partition key with low cardinality – Candidates choose 'status' or 'category'. This causes hot partitions. The exam tests that partition keys must have high cardinality and evenly distribute load. 4. Provisioning RU/s at the database level for all containers – This shares throughput, which can lead to throttling of one container by another. The exam expects you to provision at the container level for performance isolation.
Specific Numbers and Terms That Appear on the Exam: - 20 GB maximum logical partition size in Cosmos DB. - 1 RU for a 1 KB point read; 5 RU for a 1 KB write. - Five consistency levels: Strong, Bounded Staleness, Session, Consistent Prefix, Eventual. - Session is the default consistency. - Table Storage entity size limit: 1 MiB. - Table Storage max table size: 500 TiB. - Autoscale max RU/s: up to 1,000,000 (subject to quota).
Edge Cases and Exceptions: - Multi-master writes require conflict resolution; the exam tests that last-writer-wins is the default and custom policies are possible. - Bounded Staleness requires a configurable staleness window (time in seconds or operations). The exam may ask for the maximum staleness (5 seconds or 100,000 operations). - Table Storage supports batch operations of up to 100 entities, all with the same partition key. - Cosmos DB change feed is only available for SQL API and Cassandra API, not for Table API or Gremlin API.
How to Eliminate Wrong Answers: - If the scenario requires global distribution with low-latency reads and writes, eliminate Table Storage and any single-region Cosmos DB options. - If the scenario emphasizes cost savings and data is simple key-value, eliminate Cosmos DB. - If consistency requirements mention 'read-your-writes' or 'monotonic reads', Session consistency is likely the answer. - If partition key options are given, eliminate any that have low cardinality (e.g., boolean, status, date-only).
Azure Cosmos DB is a globally distributed, multi-model database with five consistency levels; Session is the default.
Partition key in Cosmos DB must have high cardinality and evenly distribute RU consumption; logical partition max size is 20 GB.
1 RU = 1 KB point read; 5 RU = 1 KB write in Cosmos DB.
Azure Table Storage is a low-cost key-value store with eventual consistency; entity size limit is 1 MiB, max table size 500 TiB.
Table Storage does not support multi-region writes; use Cosmos DB for global distribution with low-latency writes.
Autoscale in Cosmos DB scales between 10% and 100% of max RU/s; costs 1.5x the manual throughput rate.
Multi-master writes in Cosmos DB require conflict resolution; default is last-writer-wins.
These come up on the exam all the time. Here's how to tell them apart.
Azure Cosmos DB
Globally distributed with multi-region writes and reads
Five consistency levels including Strong and Session
Supports multiple data models: document, key-value, column-family, graph
High throughput: up to millions of RU/s per account
Autoscale and reserved capacity for cost management
Azure Table Storage
Single-region writes with geo-redundant storage (GRS) for DR
Eventual consistency by default; strong consistency available per request
Key-value store only (entities with partition key and row key)
Throughput limited to 20,000 IOPS per partition
Lower cost per GB stored; no reserved capacity
Mistake
Azure Cosmos DB and Azure Table Storage are interchangeable for all NoSQL workloads.
Correct
They serve different purposes. Cosmos DB is a globally distributed, multi-model database with multiple consistency levels and high throughput (up to millions of RU/s). Table Storage is a simple, low-cost key-value store with limited throughput (20,000 IOPS per partition) and eventual consistency by default. Table Storage is suitable for non-critical, low-latency workloads that do not require global distribution or strong consistency.
Mistake
Strong consistency in Cosmos DB is always the best choice for data integrity.
Correct
Strong consistency reduces availability during regional failures and increases write latency. It should only be used when business requirements demand it (e.g., financial transactions). For most applications, Session or Eventual consistency is sufficient and provides better performance.
Mistake
Partition key selection is not critical for performance in Cosmos DB.
Correct
Partition key selection is one of the most important design decisions. A poor partition key (low cardinality, causing hot partitions) leads to throttling (429 errors), increased latency, and potential 20 GB partition size limit violations. Always choose a partition key with high cardinality that evenly distributes RU consumption and storage.
Mistake
Table Storage supports global distribution with multi-region writes.
Correct
Table Storage does not support multi-region writes. It offers geo-redundant storage (GRS) for disaster recovery, but only one region can be written to at a time. Read access to the secondary region is available only with RA-GRS, and reads may be stale. For global distribution with multi-region writes, use Cosmos DB.
Mistake
Cosmos DB autoscale eliminates the need to plan for throughput.
Correct
Autoscale scales throughput automatically between 10% and 100% of the max RU/s. However, it cannot exceed the configured maximum. If traffic spikes beyond the max, throttling occurs. Additionally, autoscale has a cost premium (1.5x the cost of manual throughput for the same max). Plan the max RU/s based on expected peak load.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
Use Cosmos DB when you need global distribution, multiple consistency levels, multi-region writes, or support for document, graph, or column-family data models. Use Table Storage when you need a simple, low-cost key-value store for non-critical data that does not require global distribution or strong consistency. Table Storage is ideal for logging, metadata, and IoT telemetry with moderate throughput.
The best partition key has high cardinality (many distinct values) and evenly distributes request units (RU) and storage across partitions. Examples: user ID, device ID, order ID. Avoid low-cardinality keys like status (active/inactive) or date-only (e.g., 2023-01-01) as they cause hot partitions. Also ensure that no single logical partition exceeds 20 GB.
Start with Session consistency (default) as it provides read-your-writes and monotonic reads within a session. Use Strong only if you require linearizability and can tolerate higher latency and reduced availability. Use Eventual for lowest latency and maximum availability. Bounded Staleness is a middle ground with a configurable staleness window. Consistent Prefix prevents out-of-order reads.
Yes, but with limitations. Table Storage supports geo-redundant storage (GRS) for disaster recovery, but only one region can be written to. Reads from the secondary region are available only with RA-GRS and may be stale. For active-active global distribution with low-latency writes from multiple regions, use Cosmos DB.
Cosmos DB will return a 'Partition key reached maximum size of 20 GB' error. You must redesign the partition key to distribute data more evenly. You can create a new container with a different partition key and migrate data. Use composite partition keys or synthetic keys to achieve better distribution.
Throttling is indicated by HTTP 429 status codes. Monitor via Azure Monitor metrics: 'Total Requests' with 'StatusCode=429'. Also set alerts. To mitigate, increase RU/s, optimize queries, or redesign partition key. Use the Cosmos DB SDK's retry policy to handle transient throttling.
The change feed is a persistent log of changes to items in a container. It captures inserts and updates (not deletes by default). Use it for event-driven architectures, real-time analytics, and data synchronization to other systems. It is available for SQL and Cassandra APIs. For Table API, use Azure Functions with Table Storage binding to capture changes.
You've just covered Designing Non-Relational Database Solutions — now see how well it sticks with free AZ-305 practice questions. Full explanations included, no account needed.
Done with this chapter?