πŸ”’ 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 10 of 11 91%
10 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 ⏱ ~16 min read

Server-Side Programming

Implement stored procedures (JavaScript, partition-scoped, ACID), user-defined functions (read-only in SQL queries), and pre/post triggers in Cosmos DB β€” and know when to use each.

Code inside the database

β˜• Simple explanation

Imagine giving the librarian a set of instructions instead of fetching books yourself. You say: β€œFind the book, check if it’s overdue, update the fine, and log it β€” all in one go.” The librarian does everything locally without you making multiple trips.

That’s a stored procedure β€” JavaScript code that runs inside Cosmos DB. There are also UDFs (helper calculations used in queries) and triggers (code that runs before or after a write). All are written in JavaScript.

Cosmos DB supports three types of server-side code, all written in JavaScript:

  • Stored procedures: Execute complex logic with ACID transactions within a single logical partition. Can read, create, update, and delete items.
  • User-Defined Functions (UDFs): Read-only functions callable from SQL queries. Used for custom calculations or formatting.
  • Triggers: Pre-triggers run before a write (validate, set defaults). Post-triggers run after a write (update metadata, log). Triggers are NOT automatic β€” they must be explicitly specified per request.

Stored procedures

Writing a stored procedure

Stored procedures are JavaScript functions that execute within a single logical partition with ACID guarantees:

// Stored procedure: create a project and its first task atomically
function createProjectWithTask(project, task) {
    var context = getContext();
    var container = context.getCollection();
    var response = context.getResponse();

    // Create the project
    var projectAccepted = container.createDocument(
        container.getSelfLink(),
        project,
        function (err, createdProject) {
            if (err) throw new Error("Failed to create project: " + err.message);

            // Create the task (only if project succeeded)
            var taskAccepted = container.createDocument(
                container.getSelfLink(),
                task,
                function (err, createdTask) {
                    if (err) throw new Error("Failed to create task: " + err.message);
                    response.setBody({
                        project: createdProject,
                        task: createdTask
                    });
                }
            );

            if (!taskAccepted) throw new Error("Task creation not accepted β€” timeout?");
        }
    );

    if (!projectAccepted) throw new Error("Project creation not accepted β€” timeout?");
}

Key characteristics:

  • Written in JavaScript (not C# or Java)
  • Scoped to a single logical partition β€” all reads and writes must target the same partition key value
  • Provide ACID transactions β€” if any operation fails, everything rolls back
  • Use callback-based async β€” not Promises, not async/await
  • 5-second timeout β€” if the procedure doesn’t complete within 5 seconds, it’s aborted

Calling from C#

var project = new { id = "proj-003", tenantId = "tenant-abc", type = "project", name = "API Rewrite" };
var task = new { id = "task-201", tenantId = "tenant-abc", type = "task", projectId = "proj-003", title = "Design endpoints" };

Scripts scripts = container.Scripts;

StoredProcedureExecuteResponse<dynamic> response = await scripts.ExecuteStoredProcedureAsync<dynamic>(
    storedProcedureId: "createProjectWithTask",
    partitionKey: new PartitionKey("tenant-abc"),
    parameters: new dynamic[] { project, task });

Console.WriteLine($"Result: {response.Resource}");
Console.WriteLine($"RU charge: {response.RequestCharge}");
πŸ’‘ Exam tip: 5-second timeout

Stored procedures have a hard 5-second execution limit. If your procedure processes a large number of items, it may time out. The pattern is to process items in batches, return a continuation token when time runs low (check !container.createDocument(...) returning false), and have the client re-invoke the procedure to continue. Know this pattern for the exam.

User-Defined Functions (UDFs)

UDFs are read-only JavaScript functions used inside SQL queries:

// UDF: calculate task priority score
function priorityScore(urgency, impact) {
    if (urgency === "critical" && impact === "high") return 100;
    if (urgency === "critical" || impact === "high") return 75;
    if (urgency === "medium") return 50;
    return 25;
}

Use in a SQL query:

SELECT c.title, udf.priorityScore(c.urgency, c.impact) AS score
FROM c
WHERE c.tenantId = 'tenant-abc'
  AND c.type = 'task'
ORDER BY udf.priorityScore(c.urgency, c.impact) DESC

UDF rules:

  • Read-only β€” they can compute and return values, but cannot create, update, or delete items
  • Called with the udf. prefix in SQL queries
  • Add RU overhead β€” they run for every matching document
  • Cannot be used in stored procedures or triggers

Pre-triggers and post-triggers

Pre-triggers (before a write)

Run before an insert, replace, or delete to validate or set defaults:

// Pre-trigger: auto-set createdAt and validate required fields
function validateAndStamp() {
    var context = getContext();
    var request = context.getRequest();
    var doc = request.getBody();

    // Validate
    if (!doc.title || doc.title.length === 0) {
        throw new Error("Title is required");
    }

    // Set defaults
    if (!doc.createdAt) {
        doc.createdAt = new Date().toISOString();
    }

    doc.updatedAt = new Date().toISOString();

    // Write the modified document back
    request.setBody(doc);
}

Post-triggers (after a write)

Run after a successful write to update metadata or log changes:

// Post-trigger: update a metadata document with the latest task count
function updateTaskCount() {
    var context = getContext();
    var container = context.getCollection();
    var response = context.getResponse();
    var createdDoc = response.getBody();

    if (createdDoc.type !== "task") return;

    // Query for the metadata document
    var query = 'SELECT * FROM c WHERE c.type = "metadata" AND c.id = "task-count"';
    var accepted = container.queryDocuments(container.getSelfLink(), query,
        function (err, docs) {
            if (err) throw err;
            if (docs.length === 0) return;

            var meta = docs[0];
            meta.count += 1;
            meta.lastUpdated = new Date().toISOString();

            container.replaceDocument(meta._self, meta, function (err) {
                if (err) throw err;
            });
        }
    );

    if (!accepted) throw new Error("Query not accepted");
}

Triggers are NOT automatic

This is critical: Triggers do NOT fire automatically. You must explicitly specify them in each request:

// Specify pre-trigger and post-trigger in the request
var options = new ItemRequestOptions
{
    PreTriggers = new List<string> { "validateAndStamp" },
    PostTriggers = new List<string> { "updateTaskCount" }
};

await container.CreateItemAsync(task, new PartitionKey("tenant-abc"), options);

If you don’t specify the trigger in ItemRequestOptions, it simply doesn’t run β€” no error, no warning.

Comparing stored procedures, UDFs, and triggers

FeatureStored proceduresUDFsTriggers
LanguageJavaScriptJavaScriptJavaScript
Can read dataβœ… Yesβœ… Yes (in query context)βœ… Yes
Can write dataβœ… Yes (create, update, delete)❌ No β€” read-onlyβœ… Yes (pre: modify request body; post: write to container)
ACID transactionβœ… Yes β€” entire procedure is atomicN/A β€” runs inside a queryβœ… Part of the triggering operation's transaction
Partition scopeSingle logical partition onlyRuns within the query's scopeSame partition as the triggering operation
InvocationCalled explicitly from SDKCalled with udf. prefix in SQLSpecified in ItemRequestOptions β€” NOT automatic
Timeout5 secondsPart of query timeoutPart of the triggering operation's timeout
Best forMulti-item transactions, complex business logicCustom calculations in queriesValidation (pre), audit logging (post)

Ravi’s mistake: Ravi registered a pre-trigger to validate all task documents but forgot to specify it in ItemRequestOptions. Tasks without titles were created successfully. Priya pointed out that triggers are opt-in per request, not automatic database-level constraints.

πŸ’‘ Exam tip: triggers must be explicitly specified

The exam loves this: β€œRavi created a pre-trigger to enforce validation, but invalid documents are still being created. Why?” The answer is always that triggers are NOT automatic. They must be specified in PreTriggers or PostTriggers in each SDK request. There’s no β€œenable for all operations” setting.

🎬 Video walkthrough

🎬 Video coming soon

Server-Side Programming β€” DP-420 Module 10

Server-Side Programming β€” DP-420 Module 10

~16 min

Flashcards

Question

What language are Cosmos DB stored procedures, UDFs, and triggers written in?

Click or press Enter to reveal answer

Answer

JavaScript. Not C#, not Java, not Python β€” only JavaScript. Stored procedures use callback-based async (not Promises or async/await).

Click to flip back

Question

Are Cosmos DB triggers automatic?

Click or press Enter to reveal answer

Answer

No. Triggers must be explicitly specified in each SDK request via PreTriggers or PostTriggers in ItemRequestOptions. If you don't specify them, they don't fire β€” no error, no warning.

Click to flip back

Question

What is the execution timeout for a stored procedure?

Click or press Enter to reveal answer

Answer

5 seconds. If the procedure doesn't complete within 5 seconds, it's aborted and all changes are rolled back. For large batch operations, use a continuation pattern β€” process a chunk, return a token, and have the client re-invoke.

Click to flip back

Question

Can UDFs write data to the container?

Click or press Enter to reveal answer

Answer

No β€” UDFs are read-only. They can only compute and return values within a SQL query. They're called with the udf. prefix: SELECT udf.myFunc(c.field) FROM c.

Click to flip back

Question

What scope do stored procedures execute in?

Click or press Enter to reveal answer

Answer

A single logical partition. All reads and writes within a stored procedure must target the same partition key value. This gives ACID guarantees but means you can't do cross-partition operations.

Click to flip back

Knowledge check

Knowledge Check

Ravi creates a pre-trigger to validate that every task has a title. He creates a task without a title using the SDK. What happens?

Knowledge Check

Priya's stored procedure processes 10,000 items in a logical partition. What risk does she face?

Knowledge Check

Sophie wants to calculate a 'risk score' for each task in a SQL query. Which server-side feature should she use?


Next up: Transactions in Practice β€” real-world patterns for order processing with TransactionalBatch, inventory reservation with stored procedures, and cross-partition sagas.

← Previous

SDK Query Pagination and LINQ

Next β†’

Transactions in Practice

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.