ServiceNow Glide Record Explained
Definition and Purpose
A Glide Record is a server-side Java-like object in ServiceNow that represents a single record in any table (incidents, users, changes, custom tables). When you write a server-side script (business rule, script action, scheduled job, etc.), you work with Glide Records to read field values, update records, query the database, and perform CRUD operations (Create, Read, Update, Delete).
Glide Records are essential for any non-trivial automation in ServiceNow. They handle the complexity of safely accessing data, respecting access control lists (ACLs), triggering business rules, managing database transactions, and ensuring data consistency across tables. Without Glide Records, server-side scripting would be error-prone and insecure.
Creating and Querying Glide Records
You create a Glide Record using `new GlideRecord(‘table_name’)`. To retrieve an existing record, you call `gr.get(sys_id)` or `gr.query()` with filters. Example: `var gr = new GlideRecord(‘incident’); gr.addQuery(‘state’, ‘1’); gr.query();` retrieves all incidents in state 1 (New). You iterate through results with `while (gr.next()) { … }`.
When you retrieve a record, Glide Record fetches field values from the database and caches them in memory. You access fields using dot notation: `gr.short_description`, `gr.priority`, `gr.assignment_group`. Glide Record respects ACLs: if your user role does not have read access to a field, accessing it throws an exception or silently returns null depending on platform configuration.
Updating and Inserting Records
To update a record, you retrieve it, modify fields, and call `gr.update()`. Example: `gr.priority = ‘2’; gr.update();` sets priority to 2 and commits the change to the database. To insert a new record, you create a blank Glide Record, set fields, and call `gr.insert()`, which returns the sys_id of the new record.
Updates and inserts trigger business rules associated with that table. If your business rule updates a Glide Record, it triggers all insert/update business rules on that table. This can lead to infinite loops if you update the same record within its own business rule. Always check whether you are in a business rule context before updating.
Performance and Best Practices
Glide Record queries are powerful but slow if misused. Querying all 100,000 incidents and looping through them in a script takes minutes and can overwhelm your instance. Instead, use `.setLimit()` and `.addQuery()` to filter server-side: `gr.addQuery(‘state’, ‘!= 7’); gr.setLimit(1000); gr.query();` retrieves at most 1000 non-closed incidents, much faster than fetching all and filtering in code.
Do not query in a loop: loop over a set of sys_ids and query each individually is inefficient. Instead, query once with all necessary filters and iterate. Avoid accessing related tables with additional queries: if you need an incident’s assignment group name, do a single query with `.addQuery(‘assignment_group.name’, ‘value’)` rather than looping and querying each group individually.
Encapsulation and Reusable Patterns
Experienced developers wrap Glide Record logic in utility functions that handle error cases and return clean data. Instead of writing Glide Record queries in every business rule, create a helper function that encapsulates the logic, makes the code more readable, and centralises ACL and performance considerations across your codebase.
For frequent operations (fetching a user by email, finding open incidents for an assignment group), create a script include that other scripts can import and reuse. This reduces duplication and makes maintenance easier. Well-designed utility functions also make it easier to refactor: if you need to optimize a frequently-called Glide Record operation, you only change the function in one place rather than updating every script that performs that operation.
Common Gotchas and Pitfalls
Glide Records can execute unexpectedly if you are not careful. Calling `gr.update()` within an update business rule on that same table can trigger the business rule recursively. Use `current.update()` instead, which bypasses business rule triggers, or add a guard to check whether the business rule has already run. Another common mistake: accessing a field on a related table without fetching the relationship. If you write `gr.assignment_group.manager`, Glide Record automatically fetches the assignment_group record, but this happens synchronously and can slow your code. Better practice is to fetch the assignment_group explicitly and then access the manager field if you need it multiple times.
Debugging and Troubleshooting
If a Glide Record operation fails silently (does not return expected results, or throws an exception), check: Does the user executing the script have ACL permissions? Is the table name spelled correctly? Are query filters using the right field names? The script debugger is essential for stepping through Glide Record operations and seeing what data is being returned. Log unexpected results to a log table so you can investigate asynchronously if the issue does not surface in interactive debugging.
Where a GlideRecord call can change more than intended
A GlideRecord call looks harmless in a short script, but it is the point at which server-side code reads or writes real records under the rules of the platform. The common questions about it are about syntax, and those are easy to answer. The harder questions are about consequences: which business rules fire when the write happens, whether the query returns the set the author pictured, and what the script does when the set is much larger than expected. A script that is correct for the test instance can still lock a table or flood a queue on a production instance with ten times the records. Reviewing a GlideRecord script is therefore less about the lines and more about the volume and the side effects around them.
A short review question helps. What does this script touch, how many rows can it touch in the worst case, and what else runs when it writes? If the answers are not obvious from the code, the script needs a comment or a redesign before it ships.
Choosing the right write method for the job
The platform offers several ways to change a record from server code, and each one has a different effect on the business rules attached to the table. The table compares the ones that appear most often.
| Approach | Business rules run | Typical use | Risk to watch |
|---|---|---|---|
| Changing the current record inside its own business rule | Yes, as part of the same transaction | Setting a derived field during the save | Triggering the same rule again and looping |
| Updating a record found by a separate query | Yes, for that table | Bulk changes from a scheduled job | Cascading updates that nobody planned |
| Writing without running business rules | No | Controlled data repair with a documented reason | Skipping logic that other processes depend on |
| Calling a shared helper that wraps the query | Depends on the helper | Logic reused across several scripts | A change to the helper affects every caller |
Skipping business rules is a tempting option and a dangerous one. It is sometimes the right call for a repair, but the repair must be documented, reviewed, and reversible, and the people who own the skipped logic must know it did not run.
A review sequence for server-side scripts
- Read the query conditions and write down the expected number of matches in ordinary operation and in the worst case you can reasonably imagine.
- Check whether the script runs inside a business rule on the same table, and if so, confirm that it does not write back to the record that triggered it.
- Confirm that the script reads only the fields it needs, and that related values are fetched once rather than inside a loop.
- Decide what the script does when a query returns nothing, when a field is empty, and when the user running it lacks the access to read a related record.
- Run the script against a copy with production-sized data, and watch the number of records changed against the number expected.
- Add a log line that records the count of records changed and the identifier of the run, so that a bad run can be traced and reversed.
The failures that do real damage
A serious failure is an unbounded update. A script that updates every record matching a broad condition will do exactly what it was told, and if the condition was meant to be narrow, the damage is wide. Scripts that run from a schedule are especially exposed because nobody watches them run. A second failure is the recursive business rule, which triggers itself through an update on the same record and either loops or produces a chain of changes that is hard to unwind. A third is the silent access problem: a script running as a user who cannot read a related table will see empty values and make decisions on them, so a routing rule can send work to the wrong group without any error.
Each of these is preventable with the same habit. Put a limit on the number of records any batch script may change, and make the script stop and report when the limit is reached, rather than continuing to the end of the table.
Checks that show a script is behaving
Compare the number of records a scheduled script reports as changed with the number the business expects, and investigate any run that differs by a wide margin. Review the run time over several cycles, because a script that slows steadily is often reading more than it needs. Look at the logs for entries that show empty values where the script expected data, since those entries reveal access or data problems that the outcome alone would hide. Keep the script’s owner and purpose in its description, so that a later reader knows whether a skipped business rule was intentional.
When not to write a script at all
A script is not always the answer. If the change is a field that should follow a rule every time, a business rule, a data policy or a client-side control expresses the intent better and is easier to review. If the change is a one-off correction of a few records, a supervised update in the interface with a recorded reason is safer than a script that will be forgotten and run again. Reserve scripts for logic that must run on the server, that must process more records than a person can handle, or that must respond to events that the interface cannot see.
Harder questions about server-side scripting
Should every script call go through a shared helper?
Helpers help when the same query is needed in several places, because a single fix reaches every caller. They hurt when the helper becomes a black box that hides what each caller touches. Keep helpers small and documented, and list the callers so that a change to the helper can be reviewed against all of them.
How should a script handle a record that is locked or in use?
Design for the case where the update fails or is retried. Record which items were processed, so that a restart resumes from the right point and does not repeat changes that already happened. A script that assumes a clean run can double-apply changes after the first interruption.
Is it safe to change a record that another team owns?
Only through a defined interface, such as a documented business rule, an approved helper, or a request to the owning team. A direct write from another team’s script bypasses the controls that owner has put in place, and it can surface later as an unexplained change in their records. The script include pattern is a common way to expose a shared operation with a clear owner.
Next step
Going through the query scope, the business rules it triggers and the limits on each run can find the risk in a single sitting.
The notes on business rule governance and performance cover the rules that a script may trigger, and the script debugger concept shows how to step through a run before it reaches production. For larger custom builds, the custom application development service describes how server-side code is structured and reviewed.
Frequently asked questions
What is the difference between a Glide Record and a Glide API Record?
A Glide Record is server-side and subject to ACLs, business rules, and instance state. A GlideAPI Record is a deprecated API that is similar but without some safety guarantees. Use Glide Record for all new code.
Can we use Glide Records in client scripts running in the browser?
No. Glide Records are server-side objects and only work in server-side contexts (business rules, script actions, scheduled jobs, script includes). In client scripts, use GlideAjax or REST APIs to communicate with the server.
What happens if a Glide Record update violates a mandatory field or validation rule?
The update() method throws an exception or returns false, depending on how the validation is configured. The record does not update. You should catch exceptions and either display an error message or take an alternative action (such as logging an error).
Related guides
Related Oblytech services
Where this topic turns into delivery work, these are the Oblytech services that cover it.
Planning, running or fixing a ServiceNow programme? Tell us where you are and we will suggest a sensible next step.
Contact us