ServiceNow's STARTSWITH and CONTAINS operators look identical in the API but behave radically differently at the database level. STARTSWITH can leverage database indexes for prefix matching, while CONTAINS forces a full table scan regardless of indexes. Most developers discover this performance cliff only after their scheduled job starts timing out in production on a 500k-record table.
When to use this
- When building user search functionality that needs to match name prefixes ("Find users starting with 'John'")
- When the
CONTAINSresult set is bounded by other indexed filters and you control the query scope - When processing incident numbers or request numbers that follow consistent prefixes ("INC", "REQ", "CHG")
- When building scheduled jobs that need partial text matching with proper
setLimit()protection
When NOT to use this
- Don't use
CONTAINSon large tables without other restrictive filters — use Text Search instead - Don't use either operator in client scripts — build server-side endpoints with proper caching
- Don't use
CONTAINSin Business Rules that fire on every record insert — you'll create database contention - Don't use these operators when you need exact matches — use standard
addQuery('field', 'value')for better performance
Key behaviors and gotchas
CONTAINSqueries ignore all database indexes and perform full table scans — execution time scales linearly with table sizeSTARTSWITHcan use database indexes but only when the field has an index and the prefix is at least 3 characters- Both operators are case-insensitive by default —
STARTSWITH 'john'matches "John Smith" and "JOHNSON" - Domain separation affects results — queries only return records visible to the current domain context
- ACLs are enforced — records that fail read ACL checks are silently excluded from results
- Always use
setLimit()withCONTAINSqueries — without it, a single query can consume server resources for minutes
CONTAINS queries on tables with more than 100k records will cause performance issues in production. Always combine with restrictive indexed filters (like active=true, created within date range) or use ServiceNow's Text Search functionality instead.
Enjoying this? Get one deep-dive per week.
Join 1,000+ ServiceNow pros — scripts, GlideRecord patterns, Flow Designer techniques, and career moves. Free.