Updated recently
Last updated:
Quick Answer: A ServiceNow update set captures configuration changes — tables, scripts, UI policy, flows — as sys_update_XML records, and you promote them between instances by committing on the source and retrieving on the target. They work, but they are not source control: no diffs, no branching, no merge, and a careless override can silently revert a colleague’s production change. Teams that outgrow them move to Git-backed source control integration.
ServiceNow Update Sets: What They Actually Capture
An update set is a container. Every configuration change you make while it is selected as your “latest update set” gets recorded into it as an update record in the sys_update_xml table — essentially a snapshot of each affected row, including its sys_id, so the same record updates cleanly on the target instance instead of duplicating.
The capture rules that matter in practice:
- Configuration, not data. Table rows you create via the UI that count as configuration (business rules, client scripts, UI policies, flow definitions, catalog items) are captured. Transactional data — incidents, users, CIs — is not. That data moves via import sets, which is a different mechanism entirely.
- Custom vs override. A record you create fresh is a custom record and is captured as INSERT_OR_UPDATE. A record that already existed on your instance — an out-of-box business rule, say — only enters your update set if you explicitly mark it as an override. This is where most of the pain lives; more below.
- Deletes are captured too. Deleting a record you own creates a delete update, which will delete the corresponding record on the target when the set is applied.
The XML inside an update record is exactly what the platform stores and applies. A truncated but structurally accurate example for a script include:
<record_update table="sys_script_include">
<sys_script_include action="INSERT_OR_UPDATE">
<sys_id>5f8a2c9d1b2e44f0a1c3d4e5f6a7b8c9</sys_id>
<name>UtlGetPayerDetails</name>
<script>function getPayer(gr) {
if (!gr.next()) return '';
return gr.getValue('payer_name');
}</script>
<access>public</access>
<sys_name>UtlGetPayerDetails</sys_name>
</sys_script_include>
</record_update>
You can audit what is actually in a set — before anyone promotes it — with a straight query against that table:
var ux = new GlideRecord('sys_update_xml');
ux.addQuery('update_set', current.sys_id);
ux.addQuery('action', 'INSERT_OR_UPDATE');
ux.orderBy('target_name');
ux.query();
while (ux.next()) {
gs.info(ux.getValue('target_name') + ' :: ' + ux.getValue('type'));
}
Running that query at review time is the cheapest quality gate available to a ServiceNow team, and astonishingly few do it.
Local vs Global Update Sets
Update sets come in two flavours, and the distinction is about people, not technology:
- Global update sets are visible to every developer on the instance. They get shared, half-finished, and promoted by whoever has commit rights. On a large team this is how unrelated changes end up travelling together.
- Local update sets are private to the developer who created them until exported or committed. They are the default for individual work.
The working rule on real teams: every developer works in their own local update set, named after the ticket or change record. One change, one update set. When the change is reviewed, the local set is committed, and the committed set is retrieved on the next instance in the chain (dev → test → prod). Mixing two logical changes into one set — the “I’ll just sneak this in” move — is the single most common source of promotion regret.
The Promotion Workflow That Actually Works
- On the source instance, open the update set and Commit it. This freezes it and produces the retrievable XML.
- On the target instance, use Retrieve Update Sets — either pulling directly from the source instance over HTTPS or uploading the committed XML file.
- The retrieved set lands as “Not Yet Committed”; review its Updates list (run the
sys_update_xmlquery above), then apply. - Apply sets in order. Update sets are not order-independent: a set that assumes a table or field created by an earlier set will fail or half-apply if promoted out of sequence.
- Verify on the target — not “does the page load”, but “does the changed behaviour work” — then mark the set complete and move on. Auto-import and scheduled retrieval exist, but the teams that sleep well still review before applying.
The Override Problem, and Losing a Change to the Wrong Update Set
Two failure modes account for most update-set incidents, and both deserve names.
The override trap. You need to change an out-of-box business rule. If you edit it directly, nothing is captured unless you mark the record as an override. Even then, the override carries the entire record — your one-line change plus whatever state the record had when you saved it. If a colleague had separately overridden the same record on their branch of work, one of you is about to silently revert the other when both sets are promoted. The modern mitigation is to prefer “copy and modify” patterns — a custom business rule plus a “Do not execute” marker on the OOB one — so each change lives in its own record and override collisions cannot happen.
The wrong-latest-set problem. Updates capture into whatever update set is currently selected as latest. Forget to switch back after testing in a colleague’s set and your change lands in their set — or worse, in a set that was already committed, where it will never be promoted at all. The symptom is maddening: the change works in dev, is absent in test, and a senior admin spends a night reconstructing what happened. Symptom-free prevention is one line of discipline: check the breadcrumb at the top of the screen before you configure anything.
Why Update Sets Are Not Source Control
Teams that came to ServiceNow from software engineering keep rediscovering the same four limits:
- No diffs or review. You cannot see what a set changes line by line before it lands. The Updates list tells you which records, not what inside them changed.
- No branching or merge. Two developers needing the same record will collide in XML, not in a merge conflict you can resolve — the platform’s response is last-write-wins on the whole record.
- No partial application. A set applies as a unit. If record 47 of 52 fails, you do not get a clean “46 applied” state to reason from.
- Ordering fragility. Dependencies between sets exist but are invisible; nothing stops you promoting them out of order.
Update sets are a configuration transport mechanism, and treating them as a version-control system is the architectural mistake behind many painful upgrades.
The Modern Alternative: Git-Backed Source Control
ServiceNow now supports proper source control integration for application development: link an application in Studio to a Git repository, work in branches, commit and merge through normal pull-request review, and run automated tests before deployment. Paired with the Automated Test Framework (ATF), this gives you what update sets never could — reviewable diffs, parallel work without collisions, and a test suite that runs before anything touches production.
The migration path is gradual, and it should be: most organisations run both for a while. New custom application work goes to Git-backed apps; classic ITSM configuration keeps using update sets until the team’s test coverage is good enough to justify the move. What almost nobody does — and should — is exporting update sets to Git for archival, which turns your promotion history into something greppable.
Update Sets vs Import Sets: Do Not Confuse Them
| Dimension | Update Sets | Import Sets |
|---|---|---|
| Moves | Configuration (tables, scripts, UI, flows) | Data (users, CIs, records) |
| Transport | Commit → retrieve → apply | Data source → staging table → transform map |
| Key tables | sys_update_xml, sys_update_set |
sys_transform_map, staging tables |
| Failure mode | Wrong set, override collision, order | Bad transform, coalesce mismatch, duplicate rows |
| Reversible? | Back out, if you planned for it | Only if you kept an audit trail |
Getting this taxonomy right is half of instance hygiene. The other half is the discipline from the war story below — and if you want the wider context of how instance administration fits the ServiceNow career picture, our ServiceNow roadmap pillar covers it in full.
What Actually Happens at Work
The most expensive update-set incident I know of involved a four-developer team on a financial-services tenant, mid-way through an ITSM implementation. Developer A was configuring incident SLAs; developer B was fixing a catalog variable condition that a business stakeholder wanted “today, before the steering call”. B made the fix directly in production — a two-minute change, no update set, rationalised as an emergency.
Three weeks later, A’s update set — built and tested in dev over those same weeks — was promoted to production. Because A had also overridden the same out-of-box UI policy record while working around a dev-instance quirk, the promotion carried A’s dev-era version of B’s fix over it. The catalog item broke in production, on a Friday, during month-end onboarding. Recovery meant reconstructing B’s original two-minute change by hand, under time pressure, with a business stakeholder on the call.
The fix was procedural, and cheap: one update set per ticket, named accordingly; no production configuration without a set selected; overrides require a second pair of eyes precisely because they carry whole records. Every team reinvents these rules the hard way at least once. The senior admins worth their ₹20+ LPA are simply the ones who wrote theirs down after the first incident.
Training Resources
Update-set discipline is best learned on a real instance, with real promotion cycles. SkilBrill ServiceNow Training covers instance administration, configuration promotion and testing workflows across the Admin and Developer tracks, with placement support.
FAQ
What are ServiceNow update sets used for?
Moving configuration — scripts, business rules, UI policies, flows, catalog items — between instances. Anything transactional, like incident records or user data, moves via import sets instead.
What is the difference between a local and a global update set?
Local sets are private to their creator until exported or committed; global sets are visible and shared across the instance’s developers. Use local sets, one per change, and let sharing happen at commit time.
Can I use update sets for source control and code review?
Not really — they lack diffs, branching and merge, and apply as whole units. For genuine source control, use ServiceNow’s Git-backed source control integration, ideally with the Automated Test Framework.
Why did my change disappear after promoting an update set?
Almost always one of two causes: your change was made while a different update set was selected, or another set overrode the same out-of-box record and overwrote your version on apply. Audit the sys_update_xml table and the record’s update set history to find out which.
Do update sets move data between instances?
No. Data moves via import sets — staging tables plus transform maps with coalesce fields. Update sets carry configuration only, which is exactly why mixing the two up causes so much confusion.
