ServiceNow executes orderBy() and orderByDesc() calls as MySQL ORDER BY clauses in the sequence you call them β not the sequence you'd logically expect. The first orderBy() call becomes the primary sort, each subsequent call becomes a tiebreaker. This means you can't reorder or modify the sort criteria after calling query() β the database has already executed and returned sorted results. Developers often assume they can sort in JavaScript after querying, but processing 10,000+ records client-side will kill your transaction time.
When to use this pattern
- Processing records in priority sequence within Business Rules or Scheduled Jobs
- Generating reports where row order matters (oldest incidents first, highest priority tickets)
- Batch processing where you need consistent ordering across multiple script executions
- Early exit scenarios where you only need the first N records in a specific order
When NOT to use this pattern
- Client-side scripts β use
GlideAjaxwith server-side sorting instead - Large result sets (>1000 records) on non-indexed fields β you'll timeout the database
- When you only need aggregated data β use
GlideAggregatewithorderBy()instead - Inside loops over other GlideRecords β you're creating N+1 query scenarios that will crash under load
Key behaviors and gotchas
- Chaining multiple
orderBy()calls creates multilevel sorting β first call is primary, subsequent calls break ties - Choice field sorting uses display values, not underlying integers β
prioritysorts as "1-Critical", "2-High" alphabetically - Reference field sorting uses the display field of the referenced table, not the
sys_idvalue - Sorting on non-indexed fields forces full table scans β
descriptionandwork_noteswill kill performance - ACLs still apply to sorted results β users only see records they have read access to, in the specified order
- Domain separation affects sort order β records from different domains may sort differently based on field visibility
Never sort by journal fields (work_notes, comments, activity_due) β they're stored in separate tables and will either fail silently or create massive JOIN queries that timeout.