Most developers instinctively reach for GlideRecord iteration to count matching records, but this forces ServiceNow to load every row into memory just to increment a counter. GlideAggregate with COUNT pushes the counting down to the database layer, returning only the final number. The performance difference is dramatic — I've seen 30-second Business Rules drop to under 2 seconds by switching from GlideRecord loops to aggregate counts. The critical mistake is using getValue() instead of getAggregate() to retrieve the count — that'll return null and waste your time debugging.
When to use this
- Dashboard widgets showing counts of incidents by state, priority, or assignment group
- Business Rules that validate counts before allowing state transitions (e.g., "can't close parent with open child tasks")
- Scheduled Jobs calculating SLA compliance metrics or workload distribution reports
- Script Includes that need fast counts for conditional logic without processing individual records
When NOT to use this
- Client scripts — use
GlideAjaxto call a Script Include withGlideAggregateinstead - When you also need field values from the matching records — use
GlideRecorditeration to count and process in one pass - Complex queries with OR conditions across multiple fields —
GlideAggregatedoesn't supportaddOrCondition() - Counting records across multiple tables — aggregate each table separately then sum the results
Key behaviors and gotchas
getAggregate('COUNT')returns a string, not a number — always wrap withparseInt()for math operations- Empty result sets return no rows from
ga.next()— always handle the false case to avoid returning undefined groupBy()withCOUNTrequires awhileloop, not singlenext()call — one row per group- State field queries use integers (
'1,2,3'), not choice labels —GlideAggregatebypasses display value conversion - ACLs still apply — counts reflect only records the current user can read, not total table records
- Reference field queries (
assignment_group) return sys_ids ingetValue(), not display names
Never call getAggregate() without first checking ga.next() returns true — you'll get a null pointer exception that's impossible to debug from the error message alone.
Enjoying this? Get one deep-dive per week.
Join 1,000+ ServiceNow pros — scripts, GlideRecord patterns, Flow Designer techniques, and career moves. Free.