πŸ”’ Guided

Pre-launch preview. Authorised access only.

Incorrect code

Guided by A Guide to Cloud
Explore AB-900 AI-901 aws-aif-c01
Guided DP-420 Domain 1
Domain 1 β€” Module 9 of 11 82%
9 of 28 overall

DP-420 Study Guide

Domain 1: Design and Implement Data Models

  • Cosmos DB β€” The Big Picture Free
  • Designing Your Data Model Free
  • Partition Key Strategy Free
  • Synthetic and Hierarchical Partition Keys Free
  • Relationships β€” Embedding vs Referencing Free
  • SDK Connectivity and Client Configuration Free
  • SDK CRUD Operations and Transactions Free
  • SQL Queries in Cosmos DB Free
  • SDK Query Pagination and LINQ Free
  • Server-Side Programming Free
  • Transactions in Practice Free

Domain 2: Design and Implement Data Distribution

  • Global Replication and Failover
  • Consistency Levels: Five Choices, Real Trade-Offs
  • Multi-Region Writes and Conflict Resolution

Domain 3: Integrate and Move Data

  • Change Feed with Azure Functions and Processors
  • Analytical Workloads: Synapse Link and Fabric Mirroring
  • Data Movement: ADF, Kafka, and Spark Connectors

Domain 4: Optimize Query and Operation Performance

  • Indexing Policies: Range, Spatial, and Composite
  • Request Units and Query Cost Optimization
  • Integrated Cache and Dedicated Gateway
  • Change Feed Patterns: Materialized Views and Estimator

Domain 5: Maintain an Azure Cosmos DB Solution

  • Monitoring: Metrics, Logs, and Alerts
  • Backup and Restore: Periodic vs Continuous
  • Network Security: Firewalls, VNets, and Private Endpoints
  • Data Security: Encryption, Keys, and RBAC
  • Cost Optimization: Throughput Modes and RU Strategy
  • DevOps: Infrastructure as Code and Deployments
  • Exam Strategy and Cross-Domain Review

DP-420 Study Guide

Domain 1: Design and Implement Data Models

  • Cosmos DB β€” The Big Picture Free
  • Designing Your Data Model Free
  • Partition Key Strategy Free
  • Synthetic and Hierarchical Partition Keys Free
  • Relationships β€” Embedding vs Referencing Free
  • SDK Connectivity and Client Configuration Free
  • SDK CRUD Operations and Transactions Free
  • SQL Queries in Cosmos DB Free
  • SDK Query Pagination and LINQ Free
  • Server-Side Programming Free
  • Transactions in Practice Free

Domain 2: Design and Implement Data Distribution

  • Global Replication and Failover
  • Consistency Levels: Five Choices, Real Trade-Offs
  • Multi-Region Writes and Conflict Resolution

Domain 3: Integrate and Move Data

  • Change Feed with Azure Functions and Processors
  • Analytical Workloads: Synapse Link and Fabric Mirroring
  • Data Movement: ADF, Kafka, and Spark Connectors

Domain 4: Optimize Query and Operation Performance

  • Indexing Policies: Range, Spatial, and Composite
  • Request Units and Query Cost Optimization
  • Integrated Cache and Dedicated Gateway
  • Change Feed Patterns: Materialized Views and Estimator

Domain 5: Maintain an Azure Cosmos DB Solution

  • Monitoring: Metrics, Logs, and Alerts
  • Backup and Restore: Periodic vs Continuous
  • Network Security: Firewalls, VNets, and Private Endpoints
  • Data Security: Encryption, Keys, and RBAC
  • Cost Optimization: Throughput Modes and RU Strategy
  • DevOps: Infrastructure as Code and Deployments
  • Exam Strategy and Cross-Domain Review
Domain 1: Design and Implement Data Models Free ⏱ ~14 min read

SDK Query Pagination and LINQ

Use LINQ queries, FeedIterator pagination, MaxItemCount, continuation tokens, and session tokens for efficient data retrieval with the Cosmos DB .NET SDK.

Beyond raw SQL

β˜• Simple explanation

Imagine reading a very long book. You don’t read all 500 pages at once β€” you use a bookmark. In Cosmos DB, a continuation token is your bookmark. You read a page of results, get a bookmark, and next time you pick up right where you left off.

LINQ is like having a translator β€” you write C# code, and it gets converted to Cosmos DB SQL automatically. Not everything translates, but the common stuff works great.

The Cosmos DB SDK offers two main ways to query beyond raw SQL strings:

  • LINQ: Write type-safe queries in C# that the SDK translates to Cosmos DB SQL. Good for developers who prefer compile-time safety.
  • FeedIterator: A pagination mechanism that handles large result sets page by page. Works with both SQL and LINQ queries.

Key pagination concepts: MaxItemCount (how many items per page), continuation tokens (stateless resume point), and session tokens (read-your-writes consistency).

LINQ queries

Basic LINQ

using Microsoft.Azure.Cosmos.Linq;

IOrderedQueryable<TaskItem> queryable = container
    .GetItemLinqQueryable<TaskItem>();

// Build the LINQ query
var linqQuery = queryable
    .Where(t => t.TenantId == "tenant-abc" && t.Type == "task")
    .Where(t => t.Status == "active")
    .OrderByDescending(t => t.CreatedAt)
    .Take(20);

// Convert to FeedIterator for execution
using FeedIterator<TaskItem> feed = linqQuery.ToFeedIterator();

List<TaskItem> results = new();
while (feed.HasMoreResults)
{
    FeedResponse<TaskItem> response = await feed.ReadNextAsync();
    results.AddRange(response);
    Console.WriteLine($"Page RU: {response.RequestCharge}");
}

LINQ translation table

C# LINQCosmos DB SQL
.Where(t => t.Status == "active")WHERE c.status = 'active'
.OrderBy(t => t.CreatedAt)ORDER BY c.createdAt ASC
.OrderByDescending(t => t.CreatedAt)ORDER BY c.createdAt DESC
.Take(10)TOP 10
.Select(t => new { t.Id, t.Title })SELECT c.id, c.title
.Count()SELECT VALUE COUNT(1)
.Where(t => t.Tags.Contains("urgent"))WHERE ARRAY_CONTAINS(c.tags, 'urgent')
.Where(t => t.Name.StartsWith("Web"))WHERE STARTSWITH(c.name, 'Web')

Not all LINQ translates. Complex expressions, custom methods, or unsupported functions throw a runtime exception during translation. Test your LINQ queries during development.

FeedIterator pagination

Cosmos DB returns results in pages. Use FeedIterator to process them:

var query = new QueryDefinition(
    "SELECT * FROM c WHERE c.tenantId = @tenant AND c.type = 'task'")
    .WithParameter("@tenant", "tenant-abc");

var options = new QueryRequestOptions
{
    MaxItemCount = 25,  // max items per page
    PartitionKey = new PartitionKey("tenant-abc")
};

using FeedIterator<TaskItem> feed = container.GetItemQueryIterator<TaskItem>(
    query, requestOptions: options);

while (feed.HasMoreResults)
{
    FeedResponse<TaskItem> page = await feed.ReadNextAsync();

    foreach (TaskItem task in page)
    {
        Console.WriteLine($"  {task.Title}");
    }

    Console.WriteLine($"--- Page: {page.Count} items, {page.RequestCharge} RU ---");
}

MaxItemCount is a maximum, not exact. A page may return fewer items if:

  • The 4 MB response size limit is reached
  • The query runs out of RU budget for that page
  • There are simply fewer items remaining

Continuation tokens

For stateless pagination (e.g., API endpoints with β€œnext page” links), use continuation tokens:

// First page β€” no continuation token
string? continuationToken = null;

var options = new QueryRequestOptions { MaxItemCount = 10 };

using FeedIterator<TaskItem> feed = container.GetItemQueryIterator<TaskItem>(
    query,
    continuationToken: continuationToken,
    requestOptions: options);

if (feed.HasMoreResults)
{
    FeedResponse<TaskItem> page = await feed.ReadNextAsync();

    // Save the continuation token for the next request
    continuationToken = page.ContinuationToken;

    // Return to client: { items: [...], nextToken: "eyJ..." }
}

// Subsequent pages β€” pass the token back
using FeedIterator<TaskItem> nextFeed = container.GetItemQueryIterator<TaskItem>(
    query,
    continuationToken: continuationToken,  // resume from where we left off
    requestOptions: options);

Key properties of continuation tokens:

  • Opaque: Don’t parse or modify them β€” they’re an internal format that can change between SDK versions
  • Stateless: The server doesn’t store session state; the token contains all resume information
  • Expiration: They don’t expire, but they become invalid if the container’s partition layout changes significantly
πŸ’‘ Exam tip: continuation tokens are opaque

Never parse, modify, or depend on the internal structure of continuation tokens. They’re opaque strings that the SDK uses internally. The format can change between SDK versions without notice. Just pass them back to GetItemQueryIterator to resume. The exam may present options that suggest parsing the token β€” always reject those.

Session tokens

Session tokens enable read-your-writes consistency in session consistency level (the default):

// Write an item β€” capture the session token
ItemResponse<TaskItem> writeResponse = await container.CreateItemAsync(task, pk);
string sessionToken = writeResponse.Headers.Session;

// Read with the session token β€” guaranteed to see the write
var readOptions = new ItemRequestOptions
{
    SessionToken = sessionToken
};

ItemResponse<TaskItem> readResponse = await container.ReadItemAsync<TaskItem>(
    task.Id, pk, readOptions);
// This read is guaranteed to reflect the write above

How session tokens work:

  1. Every write returns a session token in the response headers
  2. The SDK automatically tracks session tokens internally
  3. If you’re using a single CosmosClient instance (singleton), session consistency works automatically
  4. If you have multiple clients or services, you need to pass session tokens explicitly
πŸ’‘ Exam tip: session tokens across services

Session consistency guarantees read-your-writes within the same session. A single CosmosClient automatically maintains the session. But if Service A writes and Service B reads (different CosmosClient instances), Service B may not see the write immediately. To fix this, pass the session token from Service A’s write response to Service B’s read request. The exam tests this multi-service scenario.

Putting it all together

πŸš€ Priya’s task list API uses pagination:

[HttpGet("tasks")]
public async Task<ActionResult> GetTasks(
    [FromQuery] string tenantId,
    [FromQuery] string? pageToken = null)
{
    var query = new QueryDefinition(
        "SELECT * FROM c WHERE c.tenantId = @tenant AND c.type = 'task' ORDER BY c.createdAt DESC")
        .WithParameter("@tenant", tenantId);

    var options = new QueryRequestOptions
    {
        MaxItemCount = 20,
        PartitionKey = new PartitionKey(tenantId)
    };

    using FeedIterator<TaskItem> feed = _container.GetItemQueryIterator<TaskItem>(
        query, continuationToken: pageToken, requestOptions: options);

    FeedResponse<TaskItem> page = await feed.ReadNextAsync();

    return Ok(new
    {
        items = page.ToList(),
        nextPageToken = page.ContinuationToken,
        ruCharge = page.RequestCharge
    });
}

🎬 Video walkthrough

🎬 Video coming soon

SDK Query Pagination β€” DP-420 Module 9

SDK Query Pagination β€” DP-420 Module 9

~14 min

Flashcards

Question

What does MaxItemCount control in a Cosmos DB query?

Click or press Enter to reveal answer

Answer

It sets the maximum number of items per page in FeedIterator results. It's a maximum, not a guarantee β€” pages may return fewer items if the 4 MB response limit is hit, RU budget is exhausted, or fewer items remain.

Click to flip back

Question

Are continuation tokens safe to parse or modify?

Click or press Enter to reveal answer

Answer

No β€” continuation tokens are opaque. Never parse, modify, or depend on their internal structure. Just pass them back to GetItemQueryIterator to resume pagination. The format can change between SDK versions.

Click to flip back

Question

What does a session token guarantee in Cosmos DB?

Click or press Enter to reveal answer

Answer

Read-your-writes consistency β€” if you write an item and then read it within the same session, you're guaranteed to see the write. A single CosmosClient handles this automatically. Across multiple clients/services, you must pass the session token explicitly.

Click to flip back

Question

What LINQ method translates to Cosmos DB's ARRAY_CONTAINS?

Click or press Enter to reveal answer

Answer

The .Contains() method on a collection property. For example, .Where(t => t.Tags.Contains('urgent')) translates to WHERE ARRAY_CONTAINS(c.tags, 'urgent').

Click to flip back

Knowledge check

Knowledge Check

Priya's API returns 20 tasks per page using MaxItemCount = 20. A request returns only 12 items with a non-null continuation token. Why?

Knowledge Check

Service A writes a new task and returns the session token. Service B (separate CosmosClient) reads the same task but gets a 404. What's the fix?

Knowledge Check

Ravi writes a LINQ query using a custom extension method: .Where(t => MyCustomHelper(t.Name)). What happens?


Next up: Server-Side Programming β€” stored procedures, UDFs, and triggers that run JavaScript directly inside the Cosmos DB engine.

← Previous

SQL Queries in Cosmos DB

Next β†’

Server-Side Programming

Guided

I learn, I simplify, I share.

A Guide to Cloud YouTube Feedback

© 2026 Sutheesh. All rights reserved.

Guided is an independent study resource and is not affiliated with, endorsed by, or officially connected to Microsoft. Microsoft, Azure, and related trademarks are property of Microsoft Corporation. Always verify information against Microsoft Learn.