Microsoft AZ-204: Azure Cosmos DB — Study Guide
Part of the Microsoft Azure Developer Associate AZ-204 — Study Guide. Practice with verified answers in the Microsoft exam hub, or take timed practice tests on ExamRoll.io.
Overview
Azure Cosmos DB is a fully managed, globally distributed, multi-model database designed for low-latency, elastically scalable applications. It exposes multiple APIs over a common, partitioned storage and replication engine, provides five tunable consistency levels, and offers comprehensive SLAs for availability, latency, throughput, and consistency. Data is organized into accounts, databases, and containers (or collections/tables/graphs depending on API). Containers are horizontally partitioned and scaled by a partition key, and all operations are metered in Request Units (RUs), a normalized currency that abstracts CPU, IOPS, and memory.
APIs and Programmability
Cosmos DB supports several wire-compatible APIs so you can use native SDKs and drivers without rewriting your data model:
SQL (Core) API: The recommended default for new workloads. Stores JSON documents with rich, SQL-like query (SELECT, WHERE, ORDER BY, JOIN within a document, aggregates) and deterministic UDFs for computed predicates/projections. Server-side business logic runs as JavaScript stored procedures and pre/post triggers within a single logical partition, enabling ACID transactions over multiple items that share the partition key. TransactionalBatch provides multi-item operations in a partition. Point reads (id + partition key) are the most RU-efficient. Create a .NET client with code such as: new CosmosClient(endpoint, key).
MongoDB API: Wire-compatible with MongoDB, enabling use of standard MongoDB drivers and tools (for example, mongodump/mongorestore for migrations). You can use MongoDB features backed by Cosmos DB’s distribution, autoscale, and SLAs. Multi-document transactions are supported within the same logical partition; for strict per-user atomicity, use an unsharded collection or shard by a property such as username so related documents share a partition.
Cassandra API: Compatible with Apache Cassandra drivers and CQL. Ideal for wide-column and time-series access patterns. You get automatic global distribution and RU-based scaling instead of node management.
Gremlin API: Property graph model with TinkerPop Gremlin queries and traversals. Partitioning is essential to distribute vertices and edges for scalable traversals.
Table API: Key-value with Azure Table Storage–compatible SDKs and semantics, but backed by Cosmos DB’s global distribution, RU throughput, and lower-latency indexes.
Common SDK operations across APIs include CRUD, optimistic concurrency with ETags, upserts, server-side scripts (stored procedures, triggers), and UDFs (SQL API). Queries are parameterized to reduce RUs and improve security. Bulk operations and streaming APIs minimize client overhead and RU costs for high-throughput ingestion.
Consistency, Indexing, and Query Semantics
Cosmos DB offers five well-defined consistency levels per account (overridable per request in many SDKs):
Strong: Linearizability—reads see the most recent committed write globally. Maximizes correctness, limits write latency and regional flexibility, and is not available with multi-region writes enabled.
Bounded Staleness: Reads lag behind writes by at most K versions or T time. Guarantees monotonic read and write ordering; good trade-off for globally distributed reads that tolerate bounded lag.
Session (default): Per-session read-your-writes, write-follows-reads, and monotonic reads. Each client maintains a session token; sharing it across nodes (for example, via request options in the SDK) preserves read-your-writes across those nodes.
Consistent Prefix: Reads never observe out-of-order writes, but may see a prefix of the log.
Eventual: Highest availability and lowest latency with no ordering guarantees.
Indexing is automatic and consistent by default for the SQL API. Every item and property is indexed without schema management, so writes update the index immediately (indexing mode Consistent). You can refine the indexing policy to:
- Exclude large or write-heavy paths to lower RU write costs.
- Add composite indexes to support efficient ORDER BY on multiple properties and queries combining filters and sorting across different properties.
- Add spatial indexes for GeoJSON types (Point, LineString, Polygon, MultiPolygon) and query with spatial functions such as ST_DISTANCE, ST_WITHIN, and ST_INTERSECTS. Indexing mode can also be set to None for write-optimized containers that are read by id/partition key only. Different APIs expose indexing via their native paradigms (e.g., MongoDB and Cassandra driver constructs), but all leverage the underlying Cosmos indexing engine.
Be mindful of item size and query shape. The SQL API enforces an item size limit (for example, 2 MB), and cross-partition queries, large projections, and complex predicates increase RU consumption. Use selective projections, appropriate filters, and partition-aware queries to minimize RU cost.
Partitioning and Throughput (RUs)
Cosmos DB separates logical and physical partitions:
- Logical partitions group items by a partition key value. All items sharing the same key participate in transactional batches and server-side scripts together.
- Physical partitions are managed by the service and host many logical partitions. Throughput (RUs) and storage are distributed across physical partitions; “hot” logical partitions can bottleneck a physical partition’s throughput.
Choose an effective partition key with high cardinality and even access distribution over time. Good keys correlate with your primary access path (for example, userId, deviceId, tenantId, or orderId). Avoid low-cardinality or time-bucketed keys that cause skew (for example, country, status, or day). When no single property is suitable:
- Use a synthetic key that concatenates multiple properties.
- Append a random or hashed suffix to spread load across partitions while preserving queryability by prefix or by maintaining a lookup.
- Consider hierarchical partition keys to combine multiple properties, enabling better distribution and efficient prefix queries.
Throughput models:
- Provisioned throughput: Reserve RU/s on a container or database (shared by child containers). Predictable performance with cost stability. Scale manually or via APIs/CLI.
- Autoscale: Set a maximum RU/s; Cosmos DB elastically scales between 10% and 100% of that max based on load. Billed on the highest hourly RU used; excellent for variable workloads and unknown peaks.
- Serverless: No provisioned RU/s; pay per operation’s RU consumption. Ideal for development, spiky, or low-throughput workloads without predictable baseline.
RU optimization techniques include point reads by id+partition key, parameterized queries, selective projections, denormalizing to reduce JOIN-like patterns, and using change feed for derived views rather than complex multi-container queries. Use ETags with If-Match for concurrency control to avoid RU-expensive retries. Monitor RU metrics and throttling (HTTP 429) and implement retry policies with jitter in SDKs.
Global Distribution and Change Feed
Cosmos DB’s turnkey, multi-region distribution lets you add or remove regions at any time. All regions are readable; enabling multi-region writes allows concurrent writes everywhere with sub-10-ms read latency at the 99th percentile in proximate regions. Client SDKs should be configured with preferred regions to route traffic locally and fail over gracefully. In .NET, supply preferred regions via CosmosClientOptions ApplicationPreferredRegions (or the equivalent in other SDKs). Multi-region writes require a conflict resolution policy:
- Last Write Wins: Use a conflict resolution path (for example, a timestamp or version property). If unspecified, the system timestamp can be used.
- Custom Resolution: Use a merge stored procedure to deterministically reconcile conflicts.
- Manual: Inspect the conflicts feed and resolve explicitly.
The change feed provides an ordered, append-only log of changes per logical partition key. It is ideal for:
- Event-driven architectures and CQRS (projecting documents into read-optimized views).
- Downstream pipelines (data lake ingestion, search indexing, cache invalidation).
- Near-real-time analytics and auditing. There are two main consumption patterns:
- Change Feed Processor library: Distributed, fault-tolerant processing that uses a leases container to balance partitions across workers and scale out safely.
- Pull model with FeedIterator: Explicitly iterate changes with checkpointing logic you control; segment work across FeedRange to parallelize. Azure Functions offers a Cosmos DB trigger that wraps the processor pattern for serverless processing. You can start from the beginning or from “now,” and full-fidelity change feed captures intermediate updates and deletes for complete audit trails. Design your lease container with sufficient throughput and choose idempotent handlers to accommodate retries and at-least-once delivery.
Practical Problem Scenario
Spotify needs to deliver a globally available personalization service that ingests user interactions in real time, updates per-user recommendations, and serves low-latency reads from the nearest region. Writes can occur from mobile clients worldwide, and recommendation updates must fan out to downstream systems.
- Choose Cosmos DB SQL (Core) API with multi-region writes
- Why: The Core API offers rich query and server-side programmability. Multi-region writes minimize write latency globally and tolerate regional failover without write downtime.
- Define a high-cardinality partition key and hierarchical keys
- Approach: Partition on userId; for extremely active users, use hierarchical keys such as [“userId”, “bucket”] where bucket is a hash suffix.
- Why: Evenly distributes write and read load, enables transactional updates per user, and avoids hot partitions.
- Configure autoscale throughput on the primary containers
- Why: Traffic is diurnal and campaign-driven; autoscale handles bursts up to the configured max RU/s while keeping cost proportional to actual load.
- Set consistency to Session at the account level
- Why: Mobile clients require read-your-writes for the user experience without the latency constraints of Strong. Session tokens are carried by clients and the gateway tier to preserve session semantics across nodes.
- Implement change feed processing with Azure Functions and the Change Feed Processor
- Approach: Create a Functions app with a Cosmos DB trigger bound to the interactions container. Use a dedicated leases container and enable multiple instances for parallelism.
- Why: This provides resilient, scalable, and low-ops processing to update materialized views (e.g., a recommendations container) and to publish events to Event Hubs for streaming analytics.
- Create a derived recommendations container with a tailored indexing policy
- Approach: Exclude large, write-heavy properties from indexing; add composite indexes for (userId, score DESC) to support TOP-K queries.
- Why: Reduces RU write costs while enabling efficient sorted lookups for personalized feeds.
- Enable global distribution with preferred regions in SDKs
- Approach: Add regions in North America, Europe, and APAC. Configure CosmosClientOptions with ApplicationPreferredRegions based on app deployment region.
- Why: Ensures reads are served locally for sub-10-ms latency and that failover is transparent.
- Configure conflict resolution and observability
- Approach: Use Last Write Wins with a server-generated logical clock (version property) for idempotent updates, and route conflicts to a monitoring queue for rare edge cases.
- Why: Guarantees deterministic convergence under concurrent multi-region writes and provides operational visibility.
This architecture delivers globally low-latency reads and writes, resilient event processing via the change feed, cost-efficient autoscaling, and robust consistency semantics suitable for personalization workloads.
← Azure Storage and Blob Storage · All domains · Azure Container Solutions →
Practice these questions → · Timed practice on ExamRoll.io →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
Pass your exam →