ServiceNow Assignment Group History: Track Group Changes
August 2026 · Assigner
To report on ServiceNow assignment group history, build the report on the metric_instance table rather than on the audit log. A field-type metric definition watching assignment_group writes one metric_instance record every time the group changes, and each record holds the group the task moved to plus the duration it stayed there. That is what turns "which teams touched this incident, and how long did each one hold it" into a report you can group and average. The reassignment_count field on the task tells you how many times a task was reassigned and never to whom, and metrics do not backfill, so nothing is captured before the definition exists.
This question comes up in a very specific situation. Somebody in a service review asks how long tickets sit with the network team before reaching the application team, and it turns out the platform holds the answer in a form nobody can report on. The current assignment_group value is one field showing one group, so it tells you where a ticket is and nothing about where it has been. The history exists, but it lives in places that were built for auditing rather than for analytics, which is why the obvious approach fails.
How do you track assignment group history in ServiceNow?
There are four places the information lives, and they are genuinely different tools rather than four ways of doing the same thing. Picking the wrong one is the usual reason this project stalls.
| Where to look | What it gives you | Best for | What to watch out for |
|---|---|---|---|
| metric_instance | One record per group the task passed through, with the value and how long it stayed there | Reporting and dashboards, average time per group, handoff analysis | Only captures changes after the definition is created. No backfill. |
| reassignment_count on the task | A single integer counting how many times the task was reassigned | Spotting tickets that bounced, as a filter or a KPI | A count with no names and no durations. Tells you something is wrong, never what. |
| sys_history_line | The readable per-record change list behind the Activity stream | Reading the story of one specific ticket | Built for humans reading one record, not for aggregate reporting. |
| sys_audit | The raw field-level audit rows for every audited field | Forensics and compliance questions | Generally discouraged as a reporting source. Large, unindexed for this use, and slow. |
The short version: metric_instance for reporting, reassignment_count for filtering, sys_history_line for reading one ticket, sys_audit only when you genuinely need forensics. Almost every request that starts as "can we report on assignment group history" is answered by the first one.
Why not just report on sys_audit?
Because it is the right data in the wrong shape. The audit log records that a field changed from one value to another at a timestamp, one row per change per field, across every audited field on every audited table. It is a faithful record and it is enormous, and building a report on it means asking the database to reconstruct durations by pairing consecutive rows for the same record. That is expensive at any real volume, and it is the reason experienced admins steer this work away from sys_audit.
There is also a subtler problem. The audit log gives you transitions, and what people actually want is dwell time. Knowing that an incident moved from Network to Applications at 14:12 does not tell you it sat with Network for three days; you have to find the previous row to work that out, then handle the first assignment and the still-open final assignment as special cases. Metrics do that pairing for you when the change happens, which is the entire point of the table.
How to report on assignment group history with metric_instance
The mechanism is a metric definition of type field value duration. Once it is active, the platform writes a metric_instance record every time the field you nominated changes, capturing what the field changed to and how long it stayed at the previous value. The records that matter carry four things: Value, meaning who or what the field was changed to, Duration, meaning how long it stayed at that value, ID, the task record it belongs to, and Metric Definition, the reference back to the rule that created it.
Work through it in this order.
1. Check whether the definition already exists. Open Metrics, then Metric Definitions, and filter on the Incident table. Many instances already have a definition covering assignment_group, and if yours does then you may have months of usable history sitting there that nobody has reported on. Look before you build, because a duplicate definition on the same field produces duplicate metric instances and a report that double counts.
2. Confirm the field is audited. Field-level metric tracking depends on auditing being enabled for that field. If assignment_group is not audited on the table in question, the metric will not populate, and this is the most common reason a correctly configured definition produces nothing at all.
3. Create the definition if you need one. Set the table to the one you care about, set the type to field value duration, and point it at assignment_group. Keep it scoped. A definition on the Task table itself will fire for every child table you have, which is a lot of records for a question that was probably only ever about incidents.
4. Build the report on metric_instance, not on incident. This is the step people get wrong. Filter where the metric definition is your assignment group definition and the table is incident, then bring in value, duration, and the task ID. Group by value to get average and total time per group, or group by ID to read the path an individual ticket took through your organization.
5. Sanity check the open records. The final metric instance for a task that is still open is still accumulating, so its duration is a partial figure. Decide deliberately whether your report includes in-flight work, because averages that mix completed and open dwell times drift downward and look like an improvement you did not make.
One note on tables other than Task. Metrics are wired into the task lifecycle, so applying the same idea to CMDB tables takes more work than ticking a box: it involves cloning the business rule that drives metric collection. If your question is about which group supports a configuration item rather than which group is holding a ticket, that is a different field and a different design, and the distinction between the two is worth reading up on in assignment group vs support group before you build anything.
What does reassignment_count actually count?
It is a single integer on the task that increments as the task is reassigned, and its value is entirely in what it lets you filter. A list of incidents with a reassignment count above five is a list of your routing failures, and it takes about ten seconds to produce. As a report it is a good early warning system and a reasonable KPI to trend month over month.
What it cannot do is explain anything. The count has no names in it and no durations, so an incident with a count of eight looks identical whether it toured eight teams once each or ping-ponged between two teams four times. Those are different problems with different fixes, and telling them apart needs the metric instances. Use the count to find the tickets worth investigating, then use metric_instance to investigate them.
Metrics do not backfill, so what about the history you already have?
This is the part that stings, and it is worth knowing before you promise a report to anyone. Metrics are only captured after the definition is created. Turning on a definition today gives you data from today. It does not reach back through the audit log and construct the records it would have written last quarter.
You have three honest options. Accept it, create the definition now, and set expectations that the report becomes useful in a month, which is usually the right answer. Write a fix script that reads historical audit rows and generates the matching metric instances, which is a real and reasonably common approach but is genuine engineering work that needs testing in a sub-production instance first. Or answer the immediate question directly out of the audit data as a one-off analysis, accepting the query cost once, while the metric definition starts collecting properly for every future report.
What you should not do is wait for a decision. The definition costs almost nothing to create and every day it is not running is a day of history you cannot get back cheaply.
How do you see assignment group history on a single incident?
For one ticket you do not need a report at all. The Activity stream on the record already shows group changes for audited fields, and the data behind it lives in sys_history_line, which is a considerably friendlier read than the raw audit table. Opening the record and reading the activity list answers the question for a single incident faster than any report will.
The distinction worth holding onto is that per-record reading and aggregate reporting are separate jobs with separate tools. Trying to make the Activity stream answer a question about four hundred incidents leads people to sys_audit, and trying to make metric_instance explain one specific ticket is more work than just opening it.
What to measure once you have the data
Having the data changes the conversation, so it helps to know which numbers actually lead somewhere. Three are worth building.
Average dwell time per group tells you where work waits. A group with a high average is not necessarily slow; it is often a group that receives tickets it cannot resolve and has to route onward, which is a triage problem upstream rather than a capacity problem in that team.
The most frequent handoff pairs tell you where your routing rules are wrong. If eighty percent of tickets arriving at the service desk get reassigned to the same second group, that path should have been the initial assignment, and fixing the rule removes a queue wait for every one of those tickets. This is the single highest value thing in the whole dataset, and it is invisible without per-group durations.
The share of tickets with a reassignment count above one tells you how good your initial assignment is, which is the number most worth trending. When these figures go into a monthly service review, the useful move is to bring the two or three routing rules you intend to change alongside them, since a table of dwell times invites debate while a proposed rule change invites a decision. If you need the numbers to become a deck for that review rather than a screenshot of a list view, that conversion is a solved problem and not worth an afternoon of your time.
Be careful with one trap. Long dwell times often reflect a ticket that was assigned to a group and then simply sat there, because assignment to a group is not assignment to a person. If your reports show work waiting rather than work being done, the fix is not a routing rule, and the diagnosis usually starts with assignment rules that are not firing the way you think.
Where reporting on history stops helping
All of the above is retrospective. It tells you, accurately and usefully, where work went last quarter, and every insight it produces has to be converted by hand into a rule change that might improve next quarter. That loop is slow, and it is slow in a specific way: the numbers describe groups, while the delays they measure are almost always caused by what happens after a ticket reaches a group.
A group queue distributes nothing. Work sits in it until somebody claims it, so the fastest agents take the most, specialists get cherry-picked for the interesting problems, and whoever joined most recently takes what is left. None of that shows up in a group-level dwell time report, which is why teams can fix every routing rule the data suggests and still see the same waiting. ServiceNow's own answer to the gap is Advanced Work Assignment, which pushes work to available people rather than into queues, though it needs the plugin, an ITSM, CSM, or HRSD subscription, and a workspace containing the Agent Inbox. The wider set of group fields and what each is for is covered on our ServiceNow assignment group page.
Assigner sits beside ServiceNow rather than replacing it. Once the group is known, it assigns to a named person using true round robin, weighted round robin, live workload, skills, and availability, applies the same engine to sales leads and ops tasks as to tickets, and records the rule and the candidates behind every assignment, so the history you have been trying to reconstruct from metric instances is written as the decision is made rather than reassembled afterward. That reasoning is what our transparent assignment page is about, and pricing is published at $12 per user per month. It is a companion rather than a live two-way sync, and it is built to help rather than to guarantee an outcome.
Stop hand-sorting your incoming work
Route every ticket, lead, and request to the right available person by skill, workload, and availability, using rules you control, and every assignment shows why. Rules you control, no black box.