The critical insight here is that group membership lives in sys_user_grmember, not on the sys_user table itself. Most developers try to query users first, then filter by group — that's backwards and performs poorly. The membership table is the source of truth, and dot-walking from there to user fields is both faster and more reliable than trying to join the other direction.

When to use this

  • When you need to process all members of a specific group for notifications, assignments, or bulk operations
  • When building approval workflows that route to group members individually rather than the group itself
  • When you need both user details and the ability to control whether inactive users are included
  • When the group membership is relatively stable and you're not dealing with nested groups

When NOT to use this

  • Don't use this for groups with nested membership — use GlideUser.isMemberOf() or the Groups API instead
  • Don't use this in client scripts — wrap it in a Script Include and call via GlideAjax
  • Don't use this when you only need to check if a specific user is in the group — query sys_user_grmember directly with both user and group filters
  • Don't use this for very large groups (1000+ members) without pagination — you'll hit performance issues

Key behaviors and gotchas

  • Inactive users remain group members unless explicitly filtered out — user.active dot-walk query is essential for most use cases
  • The user field is a reference, so dot-walking is safe — the foreign key constraint guarantees a valid user record exists
  • Domain separation applies to sys_user_grmember records — you'll only see memberships for groups in your current domain scope
  • ACL evaluation happens on the user records during dot-walking — users you can't read won't appear in results
  • Always call toString() on sys_id values when collecting into arrays — GlideElement objects behave unpredictably outside the query loop
  • The sys_user_grmember table has indexes on both group and user fields — queries by group are fast even for large instances
⚠️

This pattern only returns direct group members. If your groups have nested membership (groups within groups), you'll miss users who inherit membership through parent groups. Use the Groups API or GlideUser methods for nested membership scenarios.

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