Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 9

Plugin Execution: Synchronous, Asynchronous, and Pipeline Stages

Recommended resources

Welcome to the first lesson of our second module, "Advanced Dataverse Server-Side Logic." In the previous module, we established a strong foundation in solution architecture and Application Lifecycle Management (ALM), focusing on how to package and deploy your customizations reliably.

Now, we shift our focus from the what and how of deployment to the core of your application's intelligence: server-side business logic. Given your extensive background in classic Dynamics 365 plugin development, this lesson will not re-teach the basics. Instead, we'll elevate the discussion to a strategic level, focusing on the architectural decisions that ensure your solutions are performant, scalable, and stable.

Today, we will address the learning outcome: Evaluate synchronous vs. asynchronous plugin execution and select appropriate pipeline stages for business requirements. Mastering this is about moving from "making it work" to "making it work right"—a critical distinction for a senior developer and a key topic for the PL-400 exam.

1. The Event Execution Pipeline: A Strategic Review

You are already familiar with the plugin event execution pipeline from your C# development work. Let's revisit it, not as a sequence of steps, but as a set of strategic options, each with distinct implications for data integrity, performance, and user experience.

The core of the pipeline revolves around the database transaction. The stage you choose determines whether your code runs before, during, or after this transaction.

This diagram provides an excellent visual summary of the entire process, which we will deconstruct throughout this lesson.

Dataverse Event Execution Pipeline and Plugin Execution Modes
This flowchart illustrates the key stages of the Dataverse event pipeline (Pre-Validation, Pre-Operation, Post-Operation) and their relationship to the database transaction. It also contrasts the characteristics of Synchronous and Asynchronous execution modes.

The three stages available for custom plugins are:

  • Pre-Validation (Stage 10): Executes outside the database transaction.
  • Pre-Operation (Stage 20): Executes inside the database transaction, before the main system operation.
  • Post-Operation (Stage 40): Executes inside the database transaction, after the main system operation has completed.

The choice of stage is not arbitrary; it's a design decision. To explore this in a practical context, the following article provides detailed, real-world scenarios that justify the selection of each stage.

Dynamics 365 Plugin Execution Pipeline Explained with Real-World Scenarios

This article from Power Stack Engineering excels at explaining not just what each stage does, but why you would choose one over the others. It provides clear business scenarios and justifications that are crucial for architectural design.

Please read the sections detailing each of the three main plugin stages. For each stage, focus on: Real-World Pre-Validation Plugin Example: Understand why stopping an operation before the transaction (e.g., checking business hours) is efficient. Real-World Pre-Operation Plugin Example: Note how this stage is ideal for modifying data and enforcing rules that must be part of the atomic transaction, with full rollback capability. Real-World Post-Operation Plugin Example: See why this stage is necessary for logic that depends on the primary record's existence (e.g., creating a related task) and understand the implications for error handling.

As the article highlights, a common source of production issues isn't faulty code but the incorrect placement of that code within the pipeline. Let's summarize the strategic purpose of each stage:

Stage Transactional? Key Purpose Typical Scenario
Pre-Validation No To validate incoming data and cancel an operation early for efficiency, without initiating a database transaction. Verifying a user's license or custom permission before allowing an action. Checking against an external service that determines validity.
Pre-Operation Yes To modify the properties of the target entity before it is saved. Guarantees that your changes and the core operation succeed or fail together (atomic). Populating a FullName field from FirstName and LastName. Enforcing a rule that a specific field must be set based on another field's value.
Post-Operation Yes To perform actions that require the primary record to have been created and assigned an ID. Creating a set of related child records (like default tasks) immediately after a parent record (like a project) is created.

2. Execution Mode: Synchronous vs. Asynchronous

The second critical decision is the execution mode. This determines how your plugin code runs and its impact on the user.

  • Synchronous (Sync): The plugin executes in real-time as part of the main operation thread. The user interface will "freeze" and wait for the plugin to complete. If a synchronous plugin in the Pre-Operation or Post-Operation stage fails, the entire database transaction is rolled back.
  • Asynchronous (Async): The plugin is queued to be executed by the Asynchronous Service in the background. The main operation completes, and the user can continue working. The plugin runs shortly after, on a separate thread and in a separate transaction.

This distinction is fundamental to designing a responsive and robust system.

Demystifying the Plugin Event Execution Pipeline in Microsoft Dynamics 365

For a concise summary of the differences and best practices, this article provides a clear breakdown.

Read the sections 'Synchronous vs Asynchronous Execution' and the best practice 'Go async for external calls'. This will reinforce the key trade-offs.

Evaluating the Trade-offs

Choosing between sync and async involves balancing competing priorities.

Consideration Synchronous Asynchronous
User Experience Poor for long operations. The user must wait for the plugin to finish. Excellent. The UI is responsive, and the user can continue working immediately.
Data Consistency Strong and immediate. The operation and plugin logic are atomic. Eventual. The main record is saved, but the async logic completes later. The system is temporarily in an intermediate state.
Performance Can degrade perceived system performance if the plugin is slow (over 200ms is noticeable). Improves perceived performance by offloading work to a background process.
Error Handling & Rollback Simple. An exception rolls back the entire transaction. The user gets immediate feedback. Complex. The main transaction is already committed. Failures are logged as "System Jobs" and require a separate monitoring and retry strategy.
Use Case Critical, fast-running logic that must be part of the main transaction. Modifying data before save. Long-running operations (> 2 seconds), calls to external systems, non-critical follow-up tasks (e.g., sending an email).

A critical point to remember is that asynchronous plugins always run after the main transaction is committed, regardless of the stage they are registered on. While you must register them in the Post-Operation stage, their execution is fundamentally "post-transaction."


3. A Framework for Decision-Making

To bring this all together, here is a practical framework for deciding where and how your plugin logic should run. Ask yourself these questions in order:

  1. Is the goal to validate data and potentially stop the operation based on rules that don't require modifying the record itself?

    • Yes: Use a Synchronous plugin in the Pre-Validation stage.
    • Example: Checking if an account's credit limit has been exceeded before a new order is created.
  2. Is the goal to modify data on the current record before it is written to the database? Does this change need to be part of the atomic transaction?

    • Yes: Use a Synchronous plugin in the Pre-Operation stage.
    • Example: Automatically setting the "Territory" field on a Lead based on its postal code.
  3. Is the goal to perform a follow-up action that relies on the record's newly created ID, and must this action complete immediately and be part of the main transaction?

    • Yes: Use a Synchronous plugin in the Post-Operation stage.
    • Example: Updating a counter on a parent record immediately after a child record is created.
  4. Is the task non-essential for the user's immediate feedback, long-running (e.g., calling an external API), or can it fail without needing to roll back the primary record creation/update?

    • Yes: Use an Asynchronous plugin registered on the Post-Operation stage.
    • Example: Calling a Power Automate flow, sending a notification email, or synchronizing the new record to an external data warehouse.
Test your understanding!

A client has the following requirement: When a high-priority "Case" record is created in Dataverse, two things must happen:

  1. A "Service Level Agreement (SLA) Start Date" field on the Case record must be immediately populated with the current date and time. This value must be saved with the Case.
  2. An email notification must be sent to a support manager. The email generation and sending process can sometimes take a few seconds, and it should not prevent the user from saving the Case quickly.

How would you implement this using plugins? Specify the entity, message, stage, and execution mode for each piece of logic and justify your choices.

Show answer

This requirement should be implemented with two separate plugin steps, or potentially two separate plugins, registered on the Create message of the Case entity.

  1. Populating the SLA Start Date:

    • Stage: Pre-Operation
    • Mode: Synchronous
    • Justification: The logic needs to modify the data before it is saved, making Pre-Operation the correct stage. By placing this logic inside the transaction, we guarantee that the SLA Start Date is never null for a high-priority case. It must be synchronous to ensure the modification happens as part of the core operation.
  2. Sending the Manager Email:

    • Stage: Post-Operation
    • Mode: Asynchronous
    • Justification: This is a classic "fire and forget" action. It's a non-critical, potentially long-running task (network latency, SMTP server response). Making it asynchronous provides a responsive user experience. If the email fails to send, it will not roll back the Case creation, which is the desired behavior. The failure will be logged in System Jobs for an administrator to review.

Conclusion

In this lesson, we elevated the conversation around plugins from simple implementation to strategic design. Making the correct choice between pipeline stages and execution modes is fundamental to building professional-grade Power Platform solutions that are both robust and performant.

Key Takeaways:

  • The choice of plugin stage (Pre-Validation, Pre-Operation, Post-Operation) is determined by its relationship to the database transaction.
  • Pre-Validation is for efficient, non-transactional checks.
  • Pre-Operation is for transaction-safe data modification before the save.
  • Post-Operation is for logic that depends on the saved record's ID.
  • The choice of execution mode (Synchronous vs. Asynchronous) is a trade-off between user experience, data consistency, and performance.
  • Use Synchronous for fast, critical logic that must be part of the atomic operation. Use Asynchronous to offload long-running or non-critical tasks to the background.

Up Next:
Now that you have mastered the strategy for triggering logic on standard Dataverse operations (Create, Update, Delete, etc.), we will explore how you can create your own operations. In the next lesson, we will cover how to implement custom APIs in Dataverse to create new message-based operations, giving you full control over your platform's service layer.