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 GlideAjax to call a Script Include with GlideAggregate instead
  • When you also need field values from the matching records — use GlideRecord iteration to count and process in one pass
  • Complex queries with OR conditions across multiple fields — GlideAggregate doesn't support addOrCondition()
  • 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 with parseInt() for math operations
  • Empty result sets return no rows from ga.next() — always handle the false case to avoid returning undefined
  • groupBy() with COUNT requires a while loop, not single next() call — one row per group
  • State field queries use integers ('1,2,3'), not choice labels — GlideAggregate bypasses 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 in getValue(), 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.

Free Newsletter

Enjoying this? Get one deep-dive per week.

Join 1,000+ ServiceNow pros — scripts, GlideRecord patterns, Flow Designer techniques, and career moves. Free.

No spam · Unsubscribe anytime