Domain 1: Design and Implement Data Models
- Cosmos DB for NoSQL is schema-agnostic, so the model is driven by access patterns rather than by normal forms. Start from the queries the application must serve and the ratio of reads to writes, then shape documents to satisfy the common read in a single request.
- Storing multiple entity types in one container is normal and often correct. Add a discriminator field such as type, give each entity a partition key value that groups what is read together, and you can retrieve a parent and its children in one query rather than one per container.
- Embed related entities in the same document when they are read together, change together, and are bounded in number and size. Embedding turns a join into a point read, which is the single biggest performance decision in the model.
- Reference between documents instead when the related data is unbounded, changes independently, or is large. A document has a 2 MB limit, and an unbounded array inside a document is the classic design that works in testing and fails in production.
- Denormalisation duplicates data across documents deliberately so a read needs one request. The cost is write amplification and the risk of divergence, which is why the change feed is the standard mechanism for keeping denormalised copies consistent.
- Every item is uniquely identified by the combination of its partition key and its id, not by id alone. Two items in different logical partitions may share an id, and a point read requires both values.
- Unique keys enforce uniqueness of a property within a logical partition, not across the container, and they must be defined when the container is created. That constraint is frequently tested.
- Set a default time to live on a container so items expire automatically, and override it per item with the ttl property. A container TTL of -1 means items never expire unless an item sets its own; deletion by TTL consumes leftover throughput rather than costing extra.
- Version documents by keeping a schema version property on every item so application code can read old and new shapes during a migration. Cosmos DB will not migrate documents for you - the application handles both shapes until a background job rewrites the old ones.
- Choose a partition key with high cardinality and even access, so both storage and request volume spread across physical partitions. A logical partition has a 20 GB limit, and a key that concentrates traffic creates a hot partition that throttles while the rest of the container idles.
- Plan transactions when choosing the key, because transactional batches and stored procedures work only within one logical partition. If two entities must change atomically, they must share a partition key value.
- Cross-partition queries fan out to every physical partition and cost far more request units than a query scoped to one. Include the partition key in the WHERE clause wherever possible, and treat a design that cannot do so as a modelling problem rather than a throughput problem.
- A synthetic partition key concatenates several properties, or appends a random or calculated suffix, to spread writes that would otherwise land on one value - a date, for example, where every write on a given day would hit the same logical partition.
- Hierarchical partition keys let you specify up to three levels, such as tenant then user then session. The container subpartitions on the full path, so a logical partition can exceed 20 GB and queries that specify a prefix are still targeted rather than cross-partition.
- When a workload genuinely needs two different partition keys, the answer is a second copy of the data keyed differently, kept in step by the change feed - not an index. Cosmos DB partitions data physically, so one container has one partitioning scheme.
- Estimate throughput and storage from the workload before choosing a mode: the request units per second the peak needs, and the total data size. The capacity planner converts operation counts and item sizes into an RU/s estimate.
- Choose provisioned throughput for predictable, sustained traffic and serverless for intermittent, spiky or development workloads that would otherwise pay for idle capacity. Autoscale sits between them, scaling between 10% and 100% of a maximum and billing on what is used.
- Database-level provisioned throughput is shared by every container in the database, which is economical for many small containers but gives no isolation - one busy container can starve the others. Provision at container level when a container needs guaranteed throughput.
- Request units are the currency for everything: reads, writes, queries and stored procedures all consume them, a 1 KB point read costs about 1 RU, and a write costs several times more. Exceeding the provisioned rate returns HTTP 429 with a retry-after hint.
- Choose the connectivity mode deliberately: direct mode connects to backend replicas over TCP for the lowest latency and is the default for the .NET SDK, while gateway mode routes through a single HTTPS endpoint and is what you use behind restrictive firewalls or from environments that cannot open the direct-mode port range.
- Create the CosmosClient once and reuse it as a singleton for the life of the application. Creating a client per request exhausts connections and adds latency, and it is the most common SDK mistake the exam tests.
- Configure the client for the application: set the preferred region list for global distribution so reads go to the nearest replica, tune parallelism and buffered item count for cross-partition queries, enable SDK logging for diagnostics, and use the Cosmos DB emulator for offline development.
- Write queries that work with the document shape: query nested objects with dotted paths, unwind arrays with JOIN over the array within the same item, aggregate with COUNT, SUM, AVG, MIN and MAX, and order with ORDER BY, which requires the indexing policy to support the path.
- Correlated subqueries let an inner query reference the outer item, which is how you filter an array and project only matching elements. Use EXISTS with a subquery instead of a JOIN when you only need to know whether a match exists, because it avoids the cross-product.
- Know the function families the exam names: array functions such as ARRAY_CONTAINS and ARRAY_LENGTH, type-checking functions such as IS_DEFINED, IS_NULL and IS_STRING for a schema-agnostic store, and the mathematical, string and date functions including GetCurrentDateTime.
- Choose a point operation over a query whenever you have both the id and the partition key: a point read costs about 1 RU for a 1 KB item, while the equivalent SELECT costs more and scales worse. This is the single cheapest optimisation in the SDK.
- Use a patch operation to change specific properties without reading and rewriting the whole document, which saves RUs and avoids clobbering concurrent changes to other fields. Transactional Batch groups several operations on one logical partition into one atomic unit.
- Bulk support in the SDK batches many independent operations for throughput-heavy loads; enable it with AllowBulkExecution and issue operations concurrently. Bulk optimises for throughput, not latency, so it is for loading rather than for serving requests.
- Implement optimistic concurrency with ETags: read the item, send the ETag as an If-Match condition on the write, and handle the 412 precondition failure by re-reading and retrying. That is how you prevent a lost update without locking.
- Paginate queries with a maximum item count and follow the continuation token to fetch the next page. Do not assume a page is full or that an empty page means the end - only a null continuation token means the results are exhausted.
- Handle 429 responses by respecting the retry-after header; the SDK retries automatically up to a configurable limit, and persistent throttling means the throughput or the partition key needs attention rather than more retries. Retrieve query metrics to see the RU charge and where it went.
- Server-side JavaScript runs inside the engine: stored procedures execute atomically within one logical partition, pre- and post-triggers run as part of an operation when the request explicitly asks for them, and user-defined functions extend the query language but cannot use the index.
- Stored procedures must handle bounded execution: the runtime can stop a procedure before it finishes, so a procedure that processes many items must check the boolean returned by each call and return a continuation so the caller can resume.
Domain 2: Design and Implement Data Distribution
- Distribute data globally when users are geographically spread and reads should be local, or when the service must survive a regional outage. Adding a region replicates the whole account and multiplies the throughput cost by the number of regions.
- Enable service-managed failover so Cosmos DB promotes a read region automatically when the write region becomes unavailable, and set the failover priority so you control which region is promoted. A manual failover moves the single write region deliberately, for a planned migration or a drill.
- Learn the five consistency levels in order of strength: strong, bounded staleness, session, consistent prefix and eventual. Strength costs latency and RUs; weaker levels cost correctness guarantees, and the right answer is the weakest level that still satisfies the requirement.
- Session consistency is the default and is usually the right answer for a user-facing application: it guarantees read-your-own-writes within a session, which is what users notice, without the latency of strong consistency.
- Strong consistency cannot be used with multi-region writes, and in a multi-region account it restricts the write region's availability. Bounded staleness is the usual compromise, defining the lag as a number of versions or an interval of time.
- Consistency affects cost as well as behaviour: strong and bounded staleness reads consume roughly twice the RUs of session, consistent prefix and eventual reads. That factor matters when a question asks about both correctness and cost.
- Override consistency per request to something weaker than the account default using query request options - never stronger. Pass a session token between application tiers when session consistency must span more than one client instance.
- Multi-region writes make every region a write region, which lowers write latency for distributed users at the cost of possible conflicts. Use it when writes originate worldwide; keep a single write region when a global ordering is simpler to reason about.
- Conflict resolution is either last-writer-wins on a chosen numeric or timestamp property, which is the default and needs no code, or a custom stored procedure that receives the conflicting versions and decides. Unresolved conflicts land in the conflicts feed for manual handling.
- Point application connections at replicated data deliberately: set the preferred regions list so the SDK reads locally and fails over in the order you specify, and remember that in a single-write-region account, writes still travel to the write region regardless of where the client is.
Domain 3: Integrate an Azure Cosmos DB Solution
- Cosmos DB Mirroring for Microsoft Fabric continuously replicates a container into Fabric OneLake in near real time with no ETL and no impact on the transactional store, which is the current default answer for getting operational data into analytics.
- Choose mirroring when the goal is a managed, low-maintenance replica queryable by the whole Fabric stack, and the Spark connector when you need to read or write the transactional store directly from Spark code, including writing results back.
- The analytical store is a column-oriented copy of a container, updated automatically and isolated from transactional throughput so analytical queries never consume the container's RUs. It must be enabled on the container and has its own retention setting.
- Azure Synapse Link connects the analytical store to Synapse Spark and Synapse SQL serverless, so analysts query operational data without a pipeline. Synapse SQL serverless can read the analytical store but not write to the transactional store.
- Change Data Capture on the analytical store exposes inserts, updates and deletes as a feed for incremental downstream processing, and time travel in Fabric Warehouse queries data as it stood at a past point without keeping copies.
- The change feed is the integration backbone: it is a persistent, ordered record of creates and updates per logical partition. It does not surface deletes, so model deletion as a soft-delete flag with a TTL when downstream consumers must observe it.
- An Azure Functions trigger on the change feed is the low-code way to react to data changes, scaling with the number of leases. Use it to push events to Event Hubs or Service Bus so other applications consume changes without touching Cosmos DB.
- Use the change feed to maintain denormalised copies: when the source item changes, the function rewrites the duplicated fields wherever they were copied, which is what makes a denormalised model safe to operate.
- Enforce referential integrity and aggregate with the same mechanism, since Cosmos DB has neither foreign keys nor cross-document aggregates: a change feed function validates the reference or updates a running total document as changes arrive.
- Archive with the change feed by writing older items to cheaper storage such as Azure Blob Storage or the analytical store, then letting TTL remove them from the transactional container - which keeps the hot container small and its queries cheap.
- Azure AI Search indexes Cosmos DB through a built-in indexer for full-text and vector search over the same data, which is the answer when the requirement is relevance-ranked search rather than the exact predicate matching the SQL API provides.
Domain 4: Optimize an Azure Cosmos DB Solution
- Optimise a query by first measuring it: retrieve the RU charge from the response headers and the query metrics from the diagnostics, which show retrieved document count against output document count. A large gap means the engine is loading documents the filter then discards.
- The most effective query optimisations are structural: include the partition key so the query is targeted rather than fanning out, project only the properties needed rather than SELECT *, and filter on indexed paths.
- Point operations beat queries when both id and partition key are known, so retrieve the RU cost of each and prefer the point read. A point read of a 1 KB item is about 1 RU regardless of container size.
- The integrated cache is an in-memory cache in a dedicated gateway that serves point reads and query results at zero RU cost within its staleness window. It requires gateway connectivity mode and session or eventual consistency, which is the detail most often missed.
- By default every property is indexed, which is convenient for reads and expensive for writes. A write-heavy workload should exclude paths that are never filtered or sorted on; a read-heavy one can afford broad indexing.
- Know the index kinds: range indexes serve equality, range comparisons and ORDER BY; spatial indexes serve geospatial predicates; and composite indexes serve queries that filter or sort on several properties at once.
- A composite index is required for an ORDER BY on two or more properties, and its definition must match the query's property order and directions - a composite index on (a ASC, b ASC) does not serve ORDER BY a DESC, b DESC unless the exact reverse is also defined.
- Indexing policy changes are applied online as a background transformation, so the container stays available while the index rebuilds. Progress is visible on the container, and query behaviour during the rebuild reflects the partially built index.
- Choose between consistent and lazy indexing mode carefully: consistent is the default and keeps the index current with each write, while none disables indexing altogether and suits a container used purely for point reads by id and partition key.
- Develop a change feed processor by using an Azure Functions trigger for the managed option, or the change feed processor in the SDK when you need control over the lease container, the batch size and the checkpointing.
- The lease container coordinates change feed processing: each lease corresponds to a range of the feed, and the number of instances that can work in parallel is bounded by the number of leases. The change feed estimator reports how far behind the processor is running.
- Use the change feed for denormalisation, referential enforcement, aggregation persistence and archiving - the four published patterns. They exist because Cosmos DB deliberately omits joins, foreign keys and cross-document aggregates from the engine.
- Watch the request charge on writes as well as reads: a write costs more the more indexed paths a document has, so an over-indexed container shows up as an unexpectedly expensive insert rather than a slow query.
- Optimise cross-partition queries you cannot avoid by tuning the SDK's maximum degree of parallelism and maximum buffered item count, which trade client memory for latency. Neither reduces the RU cost - only a better partition key or filter does that.
- When throughput is the constraint rather than the query, decide between scaling and redesigning: autoscale absorbs spikes, but persistent throttling concentrated on a few partitions is a hot partition, and no amount of extra RU/s fixes a partition key that distributes badly.
Domain 5: Maintain an Azure Cosmos DB Solution
- Start troubleshooting from the response status code: 429 means throttling against provisioned throughput, 449 is a transient concurrency conflict worth retrying, 408 is a timeout, 403 covers authorisation and firewall refusals, and 404 can mean the item is genuinely absent or the partition key was wrong.
- Normalized RU Consumption is the metric that reveals hot partitions: it reports the maximum utilisation across partitions rather than the average, so a value pinned at 100% while total consumption looks modest means one partition is saturated.
- Monitor server-side latency separately from end-to-end latency. If server-side latency is low but the client sees slow calls, the problem is network, region selection, or the client - not the database.
- Monitor replication latency and availability per region so you know how far a read region trails the write region, which is what determines the data loss window in a failover.
- Configure Azure Monitor alerts on the signals that matter operationally: normalized RU consumption, 429 rate, server-side latency, and available storage. Send resource logs to a Log Analytics workspace and query them with KQL for per-operation diagnostics.
- Monitor throughput and data distribution across partitions in the portal, which shows RU consumption and storage per physical partition. Both views answer whether the partition key is working, and they are the evidence a design change needs.
- Choose between periodic and continuous backup by the recovery requirement: periodic backups are taken on an interval and restored by raising a support request, while continuous backup supports self-service point-in-time restore to any second within the retention window.
- Continuous backup restores into a new account rather than over the existing one, so a restore is always a side-by-side operation followed by a cutover. Retention is either 7 or 30 days depending on the tier chosen.
- A restore point is located by timestamp, and the portal shows the restorable window per account, database and container - including containers that were deleted, which is the case periodic backup handles least well.
- Separate control plane from data plane access. Azure RBAC governs the control plane - creating accounts, changing throughput, reading keys - while data plane access to items is granted through the Cosmos DB data plane RBAC roles assigned to a Microsoft Entra identity.
- Prefer Microsoft Entra ID identities over account keys for data access, because a key grants full access to everything in the account and cannot be scoped. Where keys are unavoidable, store them in Azure Key Vault and rotate them, using the secondary key to rotate without downtime.
- Disable key-based authentication entirely where policy requires it, and restrict Data Explorer access through Azure RBAC so an administrator with control-plane rights cannot silently read data unless granted data-plane access as well.
- Control network access with a firewall allow-list, service endpoints, or a private endpoint that gives the account a private IP inside your virtual network and removes public exposure. Configure CORS when a browser-based application calls the account directly.
- Encryption at rest is always on with Microsoft-managed keys; customer-managed keys in Key Vault give you control of the key lifecycle and the ability to revoke access, at the cost of an RU overhead and a hard dependency on the vault remaining reachable.
- Always Encrypted encrypts specific properties on the client so the service never sees plaintext, which is what a requirement for protecting a field from database administrators calls for. Encrypted properties support only equality comparison.
- Choose a data movement strategy by size and shape: SDK bulk operations for code-driven loads, Azure Data Factory or Synapse pipelines for scheduled orchestrated movement, the Kafka connector for streaming in or out, Stream Analytics for windowed streaming transforms, and the Spark connector for large distributed reads and writes.
- Cosmos DB can be a custom endpoint for Azure IoT Hub message routing, which lands device telemetry directly without an intermediate function - useful when the requirement is ingestion with minimal moving parts.
- Raise throughput before a large migration and lower it afterwards, and disable non-essential indexing during the load. A bulk import at steady-state throughput is the usual reason a migration takes far longer than estimated.
- Prefer declarative infrastructure for anything that must be reproducible: ARM or Bicep templates provision accounts, databases and containers, and are the supported way to maintain an indexing policy in production so a portal edit does not silently diverge from source control.
- Use imperative operations - PowerShell or the Azure CLI - for actions that are events rather than state: migrating between standard and autoscale throughput, and initiating a regional failover. Those are things you do, not things a template describes.
- Keep production changes reviewable: indexing policy, throughput mode and network rules all belong in templates under source control, because each of them changes cost or availability and each is easy to change by hand in the portal and forget.
DP-420: Azure Cosmos DB Developer Specialty exam tips
- Data models are 35-40% of the exam - more than double any other area except maintenance. Partition key selection, embedding against referencing, and the RU cost of the resulting access pattern are the recurring themes, so start there and go deep.
- Almost every performance question resolves to the partition key. Before answering, ask whether the query can include the partition key, whether a logical partition could exceed 20 GB, and whether writes concentrate on one value.
- Learn the five consistency levels in order and what each costs. Session is the default and usually correct; strong and bounded staleness roughly double read RUs; strong is incompatible with multi-region writes.
- Know the change feed properly. It underpins denormalisation, referential enforcement, aggregation and archiving - the four published patterns - and it does not surface deletes, which is why soft deletes with TTL keep appearing in correct answers.
- Memorise the SDK details the exam actually tests: a singleton CosmosClient, direct against gateway connectivity mode, ETags for optimistic concurrency, Transactional Batch scoped to a single logical partition, bulk support for loading, and continuation tokens for paging.
- For maintenance questions, separate control plane from data plane. Azure RBAC governs the account; Cosmos DB data plane RBAC with a Microsoft Entra identity governs the items. Account keys cannot be scoped, so they are rarely the recommended answer.
- Read cost questions carefully. RUs scale with item size, indexed paths, query fan-out and consistency level, and multiply by the number of regions. More than one of those is usually in play in a single scenario.
Study guide FAQ
What score do I need to pass DP-420?
A score of 700 or greater is required to pass, on Microsoft's scaled 1-1000 range, and it is not a simple percentage of questions answered correctly. Microsoft does not publish a fixed question count or duration for DP-420, and both can vary between forms. There is no penalty for a wrong answer, so answer every question.
How much coding does DP-420 require?
Enough to read it rather than to write it from scratch. Microsoft states that you should be able to write efficient SQL queries for the NoSQL API, create indexing policies, interpret JSON, read C# or Java code, and use PowerShell, plus create server-side objects with JavaScript for stored procedures, triggers and user-defined functions. Expect to be shown a snippet and asked what it does or what is wrong with it.
Which topic carries the most weight?
Design and implement data models at 35-40%, followed by maintain an Azure Cosmos DB solution at 25-30%. Together those two are around two thirds of the exam. Data distribution and integration are only 5-10% each, so do not spend disproportionate time on multi-region writes and Synapse Link.
How do I choose a partition key?
Pick a property with high cardinality and evenly spread access, that appears in the filters of your most frequent queries, and that keeps any logical partition under the 20 GB limit. Check that entities needing atomic changes share a key value, since transactional batches and stored procedures are scoped to one logical partition. Where no single property works, use a synthetic key or a hierarchical partition key of up to three levels.
Is the change feed the same as Change Data Capture?
No, and the exam distinguishes them. The change feed is a persistent, ordered record of creates and updates on the transactional store, consumed by the SDK or an Azure Functions trigger, and it does not surface deletes. Change Data Capture is a feature of the analytical store that exposes inserts, updates and deletes for incremental analytical processing.