Group Member
A Group Member in Salesforce is a single record in the GroupMember object that links a user or another group to a parent group such as a Public Group or a Queue.
Definition
A Group Member in Salesforce is a single record in the GroupMember object that links a user or another group to a parent group such as a Public Group or a Queue. Each row records one membership: the GroupId field points to the parent group, and the UserOrGroupId field points to the user or nested group that belongs to it. The object is the platform's registry of who is in which group, and it is queryable through SOQL and editable through Setup, Data Loader, and the APIs.
Group membership feeds much of the sharing model. Public Groups grant folder access, list view visibility, queue ownership, and manual record sharing. Because a sharing rule or a manual share that targets a group reaches every member, the GroupMember object decides who actually receives that access. Knowing how the object behaves is the difference between clicking through members one at a time and managing membership in bulk with a script or a data file.
How group membership works under the hood
The GroupMember object and its fields
GroupMember is a lean object with two fields that matter. GroupId references the parent group, which can be a Public Group, a Queue, or a system group like a role pseudo-group. UserOrGroupId references the thing that belongs to the group, and that value is either a User Id or another Group Id when groups are nested. There is no separate junction record to maintain and no extra metadata to fill in. One row equals one membership. The object supports insert, delete, query, and retrieve calls. It does not support update. If you need to move a user from one group to another, you delete the old GroupMember row and insert a new one. There is no edit-in-place. This trips up developers who expect to change UserOrGroupId on an existing record, so plan membership changes as delete-then-insert pairs. SystemModstamp is available for tracking when a membership row last changed, which helps when you audit recent additions or removals across the org.
Public Groups versus Queues
Both Public Groups and Queues are stored in the Group object, and both keep their members in GroupMember. The Type field on Group separates them. A Public Group is a general container used in sharing rules, folder permissions, list view sharing, and manual shares. A Queue is a group with a job: it holds records that are waiting to be picked up, such as Cases, Leads, or custom object records routed for assignment. Queue members are the users (and groups) allowed to take ownership of those queued records. Because both types live in the same object, a plain query against GroupMember returns members of both unless you filter. If you want only Public Group membership, join to Group and filter on Type. Queues also create a matching QueueSobject record per object the queue serves, so a queue has a second moving part that a Public Group does not. Keep that in mind when you build a queue through the API rather than through Setup.
Which member types a group can hold
A group does not only hold individual users. Salesforce supports several member categories, and the right one depends on what you are trying to grant. You can add specific Users by name. You can add a Role, which includes only the users assigned to that role. You can add a Role and Subordinates, which includes the role plus everyone below it in the hierarchy. You can add another Public Group, which nests one group inside another. Orgs with Experience Cloud or portals also see member types for Portal Roles, Customer Portal Users, and Partner Users. Choosing a role-based member type instead of listing users keeps the group self-maintaining. When someone joins a role, they automatically gain the group's access without anyone editing membership. Listing individual users gives precise control but creates ongoing upkeep, because every joiner and leaver is a manual edit. Most well-run orgs lean on role-based members for broad access and reserve user-level members for small, deliberate groups.
Nested groups and how access resolves
A Public Group can contain another Public Group, and the platform resolves that nesting at the moment access is checked. If group A contains group B, then every member of B effectively belongs to A. Add a user to B and they immediately gain access everywhere A is referenced, with no second edit. This makes nesting a clean maintenance pattern. You build small, purpose-specific groups, then compose them into larger groups that sharing rules point at. The payoff is that you update membership in one place and the change cascades. Suppose three regional teams each have their own group, and a national group nests all three. Moving a person between regional teams updates one membership row, and the national group stays correct automatically. The cost is indirection: when you audit who has access through the national group, you have to walk the nesting to see the real population. Document your group structure so the resolved membership is not a mystery later.
Role pseudo-groups you cannot edit
Some groups exist conceptually but are not rows you can hand-edit in GroupMember. Role and Role-and-Subordinates groups represent the users in a role, optionally plus everyone beneath them. They show up in Group queries with a Type that marks them as role-based, but their membership is computed from the role hierarchy and the UserRole assignments, not from GroupMember rows you insert. You can target these pseudo-groups in a sharing rule, and you can add them as members of a Public Group, but you cannot manually drop a user into a role pseudo-group through the object. This matters when you audit access. A query of GroupMember rows for a role pseudo-group does not return the individual users, because those users are derived. To list them you query Users by RoleId, or you expand the hierarchy. Treat role-based groups as living views of the hierarchy. To change who is in one, you change the role assignment on the user, not a membership record.
Bulk membership and the mixed DML trap
Adding hundreds of users through the Setup UI is slow and error-prone. Data Loader against GroupMember is the standard alternative. Export the current rows, build the list you want, and insert the additions. Re-inserting an existing membership is effectively harmless, and removals are deletes against the matching rows. For attribute-driven membership, an Apex job can add or remove rows when a user's department or region changes, keeping groups in sync with the data that defines them. One hazard catches Apex developers. GroupMember is one of the setup objects that cannot be modified in the same transaction as a regular object like Account or a User record. Doing both in one transaction throws a mixed DML error. The fix is to split the work: change the GroupMember rows in one transaction and the non-setup records in another, often by moving the group update into an asynchronous method annotated with future or into a queueable. Plan for that boundary before you write the trigger, not after the error appears in a log.
Auditing and permissions
Group membership drifts over time. People change teams, leave, or get added for a one-off reason that outlives its purpose. A periodic audit keeps access honest. A grouping query such as SELECT Group.Name, COUNT(Id) FROM GroupMember GROUP BY Group.Name returns the size of every group and surfaces the ones that have ballooned. To see a specific group, SELECT UserOrGroupId FROM GroupMember WHERE GroupId = the target Id lists its direct members. Pair these with nesting awareness so you understand the resolved population, not just the direct rows. Editing membership is gated by permissions. Managing Public Group membership requires the Manage Public Groups (or equivalent sharing administration) permission, and managing queue membership ties to user administration rights. A standard user without those permissions cannot change group membership even for a group they appear to own. Audit who holds these permissions. An over-broad assignment lets someone adjust their own group membership and quietly grant themselves access the sharing model assumed they did not have.
How to add members to a Public Group
Group Member rows are usually managed by editing a Public Group in Setup. The flow below covers adding members through the standard interface. For hundreds of changes, use Data Loader against the GroupMember object instead, since the UI is built for handfuls, not bulk.
- Open Public Groups
From Setup, enter Public Groups in the Quick Find box and select Public Groups. Click New to create a group, or Edit next to an existing group to change its membership.
- Name the group
Set the Label, which is the display name, and confirm the Group Name, which is the API name. These identify the group in sharing rules and in queries against the Group object.
- Choose the member type
In the Search dropdown, pick the member type you want: Users, Roles, Roles and Subordinates, or Public Groups. The available members list updates to match the type you chose.
- Add members and save
Select members from the left list and click Add to move them to Selected Members. Each entry becomes one GroupMember row on save. Click Save to write the membership.
The display name shown in Setup and in sharing rule pickers. Make it descriptive so the group's purpose is obvious at a glance.
The unique developer name used by the API and managed packages. It is generated from the Label but can be set deliberately for stable references.
When on, records shared with the group are also shared up the role hierarchy. Deselect it for very large groups like All Internal Users to keep sharing recalculation fast.
Controls which category of members the available list shows: Users, Roles, Roles and Subordinates, Public Groups, and portal types when portals are enabled.
- GroupMember cannot be updated. To move a user between groups, delete the old row and insert a new one rather than editing UserOrGroupId.
- Inserting or deleting GroupMember in the same Apex transaction as an Account, Contact, or User causes a mixed DML error. Move the group change into a future or queueable method.
- Adding a Role and Subordinates member grants access to everyone below that role too, which can be far more people than the role name suggests. Confirm the hierarchy before saving.
- You cannot hand-add users to a role pseudo-group through GroupMember. Change the user's role assignment instead, since that membership is computed from the hierarchy.
Trust & references
Cross-checked against the following references.
Straight from the source - Salesforce's reference material on Group Member.
Hands-on resources to go deeper on Group Member.
About the Author
Dipojjal Chakrabarti is a B2C Solution Architect with 29 Salesforce certifications and over 13 years in the Salesforce ecosystem. He runs salesforcedictionary.com to help admins, developers, architects, and cert/interview candidates sharpen their fundamentals. More about Dipojjal.
Discussion
Loading discussion…