ServiceNow GlideRecord API

GlideRecord is the primary JavaScript API for reading and writing data in ServiceNow's database. Every server-side script that touches records — Business Rules, Script Includes, Scheduled Jobs, and REST APIs — uses GlideRecord. Mastering this API is the single most important developer skill in ServiceNow.

What GlideRecord Does

GlideRecord lets scripts interact with any table in the database. A script uses GlideRecord to find records, read their field values, update them, create new records, or delete them — all in JavaScript without writing raw SQL queries.

Database Table: incident
GlideRecord does the same job as SQL, but in JavaScript:

SQL:    SELECT * FROM incident WHERE state = 1
GlideRecord:
        var gr = new GlideRecord('incident');
        gr.addQuery('state', 1);
        gr.query();

Reading Records: The Basic Query Pattern

Every GlideRecord query follows the same four-step pattern: create the object, add conditions, execute the query, loop through results.

// Step 1: Create GlideRecord object targeting the 'incident' table
var gr = new GlideRecord('incident');

// Step 2: Add filter conditions (like a WHERE clause)
gr.addQuery('state', 1);                    // State = New
gr.addQuery('priority', 1);                 // AND Priority = Critical

// Step 3: Execute the query
gr.query();

// Step 4: Loop through each matching record
while (gr.next()) {
    gs.log('Incident: ' + gr.number + ' — ' + gr.short_description);
}

Common Query Methods

addQuery(field, value)

Adds a filter condition using exact equality. Multiple addQuery calls combine with AND logic — all conditions must match.

addQuery(field, operator, value)

Adds a filter with a specific operator. Operators include: CONTAINS, STARTSWITH, ENDSWITH, IN, NOT IN, greater than, less than, INSTANCEOF.

gr.addQuery('short_description', 'CONTAINS', 'VPN');
gr.addQuery('priority', 'IN', '1,2');
gr.addQuery('opened_at', '>=', gs.daysAgoStart(7));

addOrCondition(field, value)

Connects conditions with OR instead of AND. This must chain onto an existing addQuery call.

var stateQ = gr.addQuery('state', 1);    // State = New
stateQ.addOrCondition('state', 2);       // OR State = In Progress

orderBy(field) and orderByDesc(field)

Sorts query results. orderBy sorts ascending, orderByDesc sorts descending.

gr.orderBy('priority');          // Lowest priority number first (Critical)
gr.orderByDesc('opened_at');     // Newest records first

setLimit(n)

Caps how many records the query returns. Use this to prevent scripts from processing thousands of records unintentionally.

gr.setLimit(10);   // Return only the first 10 matching records

Reading Field Values

Inside the while loop, access field values using the GlideRecord object's field names:

while (gr.next()) {
    var num = gr.getValue('number');             // Stored value (string)
    var desc = gr.getValue('short_description'); // String field value
    var priority = gr.getValue('priority');      // Stored value: "1"
    var priorityLabel = gr.getDisplayValue('priority'); // "1 - Critical"
    var assignedTo = gr.getDisplayValue('assigned_to'); // "John Smith"
}

Creating a New Record

var newInc = new GlideRecord('incident');
newInc.initialize();                         // Prepare a blank record
newInc.setValue('short_description', 'Server CPU at 100%');
newInc.setValue('priority', 1);
newInc.setValue('category', 'infrastructure');
newInc.setValue('assignment_group',
    gs.getGroupByName('Network Support'));    // Set by group name
var sysId = newInc.insert();                 // Save and return sys_id
gs.log('Created incident: ' + sysId);

Updating Existing Records

var gr = new GlideRecord('incident');
gr.get('INC0001234');               // Get record by number or sys_id
gr.setValue('state', 6);            // Set State = Resolved
gr.setValue('close_notes', 'Issue resolved after server reboot.');
gr.update();                        // Save the changes

Deleting Records

var gr = new GlideRecord('incident');
gr.addQuery('state', 7);            // Closed incidents
gr.addQuery('resolved_at', '<', gs.daysAgoEnd(365)); // Over 1 year old
gr.query();
while (gr.next()) {
    gr.deleteRecord();
}

GlideRecord.get() Shortcut

When fetching exactly one record by its sys_id or by a unique field value, use the get() shortcut instead of query() plus next():

var gr = new GlideRecord('incident');
if (gr.get('abc123def456...')) {      // sys_id
    gs.log(gr.short_description);
}

// Or get by a unique field:
if (gr.get('number', 'INC0001234')) {
    gs.log(gr.state);
}

GlideAggregate: Counting Without Loading Records

When a script only needs a count or sum — not individual records — GlideAggregate is far more efficient than GlideRecord because it returns the calculation without loading record data into memory.

var agg = new GlideAggregate('incident');
agg.addQuery('state', 'NOT IN', '6,7');   // Not Resolved or Closed
agg.addAggregate('COUNT');
agg.query();
if (agg.next()) {
    var openCount = agg.getAggregate('COUNT');
    gs.log('Open incidents: ' + openCount);
}

Performance Tips

  • Always use addQuery conditions to filter records — never load all records and filter in the while loop.
  • Use setLimit() when you only need a fixed number of records.
  • Use GlideAggregate for counts and sums instead of GlideRecord loops.
  • Avoid running GlideRecord queries inside a while loop that iterates through another GlideRecord — this creates N+1 query problems that destroy performance on large data sets.

Leave a Comment

Your email address will not be published. Required fields are marked *