Learn how to configure Dataverse queues and routing rules to build a structured work assignment system in model-driven apps. This lesson covers queue item lifecycles, team-based distribution patterns, and automatic case routing from scratch.

Picture this: your customer service team has 200 open cases, three regional support teams, and zero visibility into who's working on what. Agents are stepping on each other's toes, high-priority tickets are aging in the inbox, and the team lead is manually reassigning records in a spreadsheet at 5 PM every Friday. This is the exact problem Dataverse queues were built to solve — and when configured correctly, they transform chaotic shared inboxes into structured, auditable work pipelines.
Queues in Dataverse are more than a holding pen for records. They're a full work management system: records enter a queue as queue items, agents pick them up explicitly (marking ownership and preventing double-handling), and the lifecycle of each item is tracked from arrival to resolution. Combined with routing rules, you can automatically direct incoming records to the right queue based on any combination of field values — no manual sorting required. Layer on team-based distribution and you have a complete, scalable assignment engine built entirely within Power Apps.
By the end of this lesson you'll have the knowledge and hands-on experience to design and configure a queue-based work distribution system for a real-world scenario. We'll use a customer support case management context throughout — relatable to nearly every organization — but the patterns apply equally to field service work orders, loan applications, IT incidents, or any high-volume record processing flow.
What you'll learn:
You should be comfortable with model-driven app fundamentals before diving in. Specifically:
Before touching any configuration, let's establish exactly what's happening under the hood. This distinction matters because most queue-related frustrations come from misunderstanding the data model.
Dataverse has two separate system tables at play:
Queue (queue) — This is the container. Think of it like a mailbox or tray. It has a name, an owner, a type (public or private), and optionally an email address for inbound routing. A queue doesn't hold records directly.
Queue Item (queueitem) — This is the wrapper. When a record (like a Case) is added to a queue, Dataverse creates a Queue Item record that links the queue to that record. The Queue Item is where all the work-state metadata lives: which worker picked it up, when it was created, and what its current status is.
This distinction is crucial. The underlying Case record doesn't change ownership when it enters a queue. The Queue Item is the ephemeral assignment mechanism. You can have the same Case record appear as a queue item in multiple queues simultaneously (though this is generally inadvisable in practice — more on that in the troubleshooting section).
Out of the box, certain system tables are already queue-enabled: Case (Incident), Activity types (Email, Phone Call, Task, etc.), and a few others. For custom tables, you need to explicitly enable queue support in the table settings.
To enable a custom table for queues:
Support Request table)Warning
Queue-enabling a table is a one-way door in managed solutions. Once a table is queue-enabled and that setting is deployed via a managed solution, you cannot disable it without unmanaging the solution layer. Make this decision deliberately and document it in your solution design.
Once a table is queue-enabled, you'll see a Add to Queue button appear on records of that type in model-driven apps, and Power Automate flows can route records to queues programmatically.
Now let's build some queues. We'll use a scenario: a software company with three support tiers — Tier 1 (general inquiries), Tier 2 (technical issues), and Tier 3 (enterprise escalations). Each tier has a team of agents and needs its own queue.
When you create a queue, the first meaningful decision is its type:
For team-based work distribution, you almost always want public queues.
Navigate to your model-driven app, then to Settings > Advanced Settings > Service Management > Queues — or alternatively through the Customer Service Hub if your environment has it. In some environments, you'll find queues in the Service module of the classic interface.
A cleaner path for makers is directly through the maker portal:
Or via the model-driven app runtime:
Fill in the queue form:
| Field | Tier 1 Queue Example | Notes |
|---|---|---|
| Name | Tier 1 - General Support |
Descriptive, includes the tier |
| Type | Public | Visible to all agents with queue access |
| Owner | Tier 1 Support Team | Can be a team or user |
| Incoming Email | tier1@support.contoso.com |
Optional — enables email routing |
| Description | General inquiries, billing, account access | Helps agents know what belongs here |
Repeat this for Tier 2 and Tier 3 queues, adjusting ownership to the appropriate team record in your environment.
Tip
Naming conventions matter enormously once you have dozens of queues. Use a consistent pattern like [Tier] - [Region] - [Channel] so queues sort predictably in lists and dropdowns. A queue named "Queue 1" creates maintenance headaches within months.
For public queues, membership determines who gets notified and who can pick items from the queue when using certain routing configurations. To add members:
In practice, for team-based distribution you'll typically assign queue ownership to an owner team in Dataverse rather than adding individual members — this way, when team membership changes (someone joins or leaves), the queue doesn't need reconfiguration. Team ownership is the more maintainable pattern at scale. If you need a refresher on how Dataverse teams are structured, see the article on Dataverse Security: Business Units, Security Roles, and Teams.
A routing rule is the mechanism that automatically moves records into queues when certain conditions are met. Without routing rules, agents or flows must manually add records to queues — which works for simple scenarios but doesn't scale.
Routing in Dataverse is organized as Routing Rule Sets, each containing one or more Rule Items. The structure looks like this:
Routing Rule Set: "Case Routing - Standard"
├── Rule Item 1: Enterprise accounts → Tier 3 Queue
├── Rule Item 2: Technical issues, severity High → Tier 2 Queue
├── Rule Item 3: All remaining cases → Tier 1 Queue
Rule items are evaluated in order, and processing stops at the first matching rule. This means you put your most specific rules first and your catch-all rule last — just like a series of if/else if statements.
Only one Routing Rule Set can be active at a time per entity. If you need different routing logic for different scenarios (e.g., business hours vs. after-hours), you'll need to activate/deactivate rule sets via Power Automate or handle the branching within a single rule set using conditions.
Navigate to Settings > Service Management > Routing Rule Sets (in the classic interface), or find it under Customer Service Hub > Service Management.
Case Routing - Tier AssignmentSelect Add Rule Item from the subgrid or command bar. Each rule item has:
Let's configure our three rules:
Rule Item 1: Enterprise Accounts → Tier 3
Conditions:
Account: Customer Type = Enterprise
OR
Case Priority = Critical
Route To Queue: Tier 3 - Enterprise Escalations
Order: 1
Rule Item 2: Technical Issues, High Severity → Tier 2
Conditions:
Case Type = Technical Issue
AND
Case Priority = High
Route To Queue: Tier 2 - Technical Support
Order: 2
Rule Item 3: Catch-All → Tier 1
Conditions: (leave empty — matches everything)
Route To Queue: Tier 1 - General Support
Order: 3
Key insight
The condition builder for routing rules uses the same query interface as view filters. If you're already comfortable creating and customizing views in model-driven apps, you'll find the condition builder familiar. You can filter on related table columns (like Account fields) as well as the record's own columns.
Once your rule items are saved, return to the Routing Rule Set record and select Activate from the command bar. You'll see the status change to Active. Only one rule set per entity can be active — activating a new set automatically deactivates the previous one.
To trigger routing, you can:
ApplyRoutingRule action)Warning
Routing rules are not automatically applied when a record is updated — only when explicitly triggered. If a case's priority changes from Normal to Critical, you must re-trigger routing to move it to Tier 3. Plan for this in your business process design. A Power Automate flow triggered on field change is the typical solution.
Understanding the queue item lifecycle is what separates a well-run queue system from one that just feels like another record list. The lifecycle has four key states:
When a record is routed to a queue, Dataverse creates a Queue Item record. At this point:
Worked By field is empty (unassigned)Status is activeAn agent navigates to the queue, finds the item, and selects Pick from the queue item record or the queue view. When an item is picked:
Worked By field is set to the picking agent's user recordThis explicit pick mechanism is what prevents two agents from unknowingly working the same case — a critical safeguard in any shared queue environment.
If an agent picks an item and then realizes they can't handle it (wrong expertise, needs escalation, etc.), they can Release it. Releasing:
Worked By fieldWhen work is complete (or the record is resolved/closed), the queue item should be removed. This happens:
Note
A removed queue item is not deleted — the QueueItem record is deactivated and its status reason changes to Inactive. This gives you a full audit trail of what was queued, when, who worked it, and when it was removed. This history can be surfaced in charts and dashboards to monitor team throughput.
To expose queues and queue items in your model-driven app, you need to add the Queues area to your site map. In the site map editor:
Configure a view that shows queue items filtered to the current user's queues. This is usually done with a "My Work" style view using the Worked By (Me) and queue membership filters.
For a well-designed queue management experience, you typically want three views:
Worked By = Current UserIndividual queues are useful, but the real power comes from structuring queues around owner teams in Dataverse. This enables several patterns that individual user assignment simply can't match.
This is the pattern we've been building: each functional team owns a queue. Work is routed to the queue, and any team member can pick items. This model:
Dataverse doesn't have a native round-robin assignment engine, but you can build one. When a queue item is created in the Tier 1 queue:
Worked By field on the queue item directly via the Dataverse connector's Update Row action// Simplified Power Automate expression for round-robin index
// Assuming 'agentList' is an array of user IDs from team members
// And 'currentIndex' is stored in a configuration table
mod(outputs('Get_current_index')?['body/cr_roundrobinindex'], length(variables('agentList')))
This is more reliable than trying to balance by record count in real time, and it's auditable.
Tip
Store your round-robin counter in a dedicated Dataverse configuration table rather than in environment variables or SharePoint. This keeps it within the same transactional boundary as your queue operations and makes it accessible from the app UI for admins to reset or adjust.
For organizations with complex routing needs, you can extend the routing rule approach by creating skill-specific queues and mapping agents to queues based on their certifications or product expertise.
Example: Within Tier 2 Technical Support, you have agents who specialize in Product A vs. Product B. Create sub-queues:
Tier 2 - Product ATier 2 - Product BAdd a custom column to your Case table: Product Area (choice column with values Product A, Product B, Other). Then add routing rule items that branch on this column before the general Tier 2 rule.
This is also where model-driven app security roles and team-based access intersect with queue design. Product A specialists should only see Product A queue items by default — configure their default views and security appropriately.
If your organization is structured regionally, you can route based on account geography. Add a lookup to a Region table on your Case, or use the related Account's address fields:
Routing rule conditions:
Related Account: Region = "North America" → North America Support Queue
Related Account: Region = "EMEA" → EMEA Support Queue
Related Account: Region = "APAC" → APAC Support Queue
This pairs naturally with Dataverse's business unit structure. If each region is its own business unit, teams and queues align cleanly with the organizational hierarchy. For background on how that hierarchy works, revisit Dataverse Security: Business Units, Security Roles, and Teams.
Configuration is only half the job. Your agents need a usable interface to interact with queues daily.
On the Case main form, add a Queue Item quick view form or a label showing the current queue. Since the queue item is a separate table, you can't add it as a simple field on the Case form natively — but you have two good options:
Quick View Form: Create a quick view form for the Queue Item table and add it to the Case form in a "Work Assignment" section. This requires a relationship between Case and Queue Item, which exists as a system relationship (queueitem.objectid → incident.incidentid).
Subgrid: Add a Queue Items subgrid to the Case form showing related queue items. This gives the agent and manager full context: which queues the case is in, who's working it, and when it was added.
For form design guidance, the article on designing model-driven forms with sections, tabs, subgrids, and quick view forms covers the mechanics of adding these components.
A queue worklist view should be the agent's primary daily interface. Configure it as follows:
For the Age column, use a calculated column on the Queue Item table that computes Today() - Created On in days. This gives agents and managers instant visibility into SLA risk without manual calculation.
Tip
Create a personal view as a template that agents can import, rather than expecting them to build their own. Document the steps for saving a view as a personal view, then share the exported view XML with the team. Managers can configure team-level views as system views through the maker portal.
Build a dashboard that shows:
This kind of operational visibility is exactly what makes a queue system valuable to leadership — not just the agents using it day to day.
Let's build a working queue configuration from scratch. This exercise takes approximately 45–60 minutes in a developer environment.
You work for a software company called Contoso Solutions. The customer support team is split into two tiers. Tier 1 handles billing and account issues; Tier 2 handles technical product problems. Cases come in via email and the web portal. You need automatic routing and a clean agent worklist.
If you're using a custom table instead, enable queues in table properties as described earlier.
Create two queues:
Tier 1 - Billing & Account, Type: Public, Owner: Tier 1 Support TeamTier 2 - Technical, Type: Public, Owner: Tier 2 Technical TeamCase Tier Routing, Entity: CaseCase Type = Question OR Case Type = Request, Route To: Tier 1 - Billing & Account, Order: 1Tier 2 - Technical, Order: 2Tier 1 - Billing & Account queueWorked By columnMy Active Queue ItemsWorked By = Current User AND Status = ActiveCongratulations — you now have a functional, routed, assigned queue system.
Symptom: Creating cases and expecting automatic routing, but records aren't appearing in queues.
Cause: The routing rule set is in Draft status.
Fix: Open the rule set and select Activate. Verify status shows Active before testing.
Symptom: Enterprise cases are routing to Tier 1 instead of Tier 3.
Cause: The catch-all rule (no conditions) is listed before the specific rules.
Fix: Reorder rule items so catch-alls are always at the highest order number. Rule items with no conditions match every record, so they must come last.
Symptom: The same Case appears in both Tier 1 and Tier 2 queues, confusing agents.
Cause: Routing was triggered twice, or manual "Add to Queue" was used in addition to automatic routing.
Fix: Understand that Dataverse allows a record in multiple queues simultaneously — there's no system enforcement of single-queue membership. If your business rules require single-queue assignment, add a Power Automate flow that removes queue items from other queues when one is picked. Alternatively, build a business rule or server-side logic to prevent the second addition.
Symptom: Agents can't see queues or queue items despite being team members.
Cause: The security role assigned to agents doesn't include privileges on the Queue and Queue Item tables.
Fix: In the security role editor, ensure the role has at least Read access to Queue (at Business Unit or Organization level) and Read/Write/Create access to Queue Item. The default Customer Service Representative role in Dynamics 365 environments handles this correctly — use it as a reference. More on this in the model-driven app security article.
Symptom: A case priority changes to Critical but doesn't move to the Tier 3 escalation queue.
Cause: Routing rules only fire when explicitly triggered — not on record updates by default.
Fix: Build a Power Automate cloud flow triggered on "When a row is modified" for the Case table, filtered to when Priority changes. Include a Dataverse action to call the ApplyRoutingRule message, passing the Case record ID. This automates re-routing on significant field changes.
Symptom: Resolved cases still show as active queue items, polluting the worklist.
Cause: For system tables like Case, Dataverse automatically deactivates queue items when the case is resolved. For custom tables, this isn't automatic.
Fix: For custom queue-enabled tables, add a Power Automate flow that removes (deactivates) queue items when the record reaches its terminal status. Use the Remove Queue Item Dataverse action or update the Queue Item's status to Inactive directly.
Queues and routing rules are genuinely one of the most underutilized features in the Power Platform ecosystem. When configured well, they give your organization:
The key mental model to internalize: queues hold queue items, not records. The queue item is the assignment artifact — it's what agents pick, release, and complete, while the underlying record follows its own lifecycle independently.
From here, consider these logical next steps:
Extend with Power Automate: Build flows that re-route on field changes, implement round-robin assignment, and send notifications when high-priority items age beyond SLA thresholds.
Add Business Process Flows: Queue-based work pairs beautifully with business process flows that guide agents through the steps required to resolve each type of queue item. Link the BPF stage to queue item state for a seamless guided experience.
Build Analytics: Create queue health dashboards showing volume trends, agent throughput, and SLA adherence. The Queue Item table's history makes this straightforward with standard chart and list components.
Consider Unified Routing: If you're in a Dynamics 365 Customer Service environment, explore Unified Routing — Microsoft's newer, more powerful routing engine that builds on the queue concepts here with ML-based skill matching, capacity management, and analytics. It uses the same queue tables but extends the routing logic significantly beyond what rule sets can do.
The patterns you've configured in this lesson form the conceptual foundation for that entire tier of functionality. Master this, and unified routing's additional capabilities will make immediate sense.