Remote Groups are an Enterprise feature. On GrowthBook Cloud they’re only available to some organizations. Contact us if you’d like to try them.
How It Works
A Remote Group has a name and an attribute, like an ID List, but the SDK payload doesn’t contain its IDs. Instead:- You upload a CSV of IDs to GrowthBook, or keep the IDs in your own storage.
- A loader writes the uploaded IDs to a fast lookup store, such as Redis. The GrowthBook Proxy includes one.
- Before evaluating features, your app (or the Proxy, for remote evaluation) looks up which Remote Groups the user is in, using a resolver.
- The SDK checks rules against that list of groups.
Creating a Remote Group
Go to SDK Configuration → Saved Groups, open the Remote Groups tab, and click Add Remote Group. Choose a name and the attribute the IDs belong to. The attribute must be astring or number; secureString attributes aren’t supported, because the lookup needs the raw value.
After you create the group, it opens on its own page, where you can upload IDs.
Uploading is optional. If your IDs already live in your own database or cache, skip the upload and write your own resolver.
Uploading IDs
Click Upload CSV on the group’s page and choose a file. GrowthBook checks the start of the file first, so common mistakes show up before the upload. The file then goes straight to your file storage (S3 or Google Cloud Storage), and GrowthBook checks every line in the background. The CSV needs:- One ID per line. A first line equal to the attribute name is treated as a header and skipped.
- No more than one column. Quotes, blank lines, a BOM and Windows line endings are handled.
- IDs up to 1,024 characters.
- Numbers only, for
numberattributes. - Up to 100 MB, which is about 3 to 5 million IDs.
Choosing the Version a Group Uses
Uploading a file doesn’t change what the group targets. The version a group uses is part of the Saved Group, so changing it goes through a draft, like any other Saved Group change, and is reviewed and published the same way. See Publishing & Approval Flows. After you upload a file, click Add to revision once it’s validated. To use another version, click Use next to it in the uploads table. The uploads table marks the version the group uses as Live. Click a version to see its details: file name, size, SHA-256 checksum, and which data stores have loaded it. You can download any version, and delete versions the group doesn’t use.ID Counts
The ID count on an upload counts every ID in the file. If the file contains duplicate IDs, each one is stored only once when it’s loaded, so a data store can report fewer IDs than the file has. A warning icon in the uploads table shows when that happens.Targeting with Remote Groups
Use a Remote Group in a rule like any other Saved Group: in a rule’s Saved Groups targeting, or with the is in the saved group and is not in the saved group operators in a condition. A Remote Group can also be used with anotherstring or number attribute. For example, a group of VIP account IDs on account_id can target users whose parent_account_id is a VIP account. The group’s IDs are matched against the other attribute’s value, so you don’t need to upload the same IDs twice. In the condition builder, these groups show the attribute their IDs belong to, such as VIP Accounts (account_id IDs).
In the SDK payload, this is a separate group with the ID <group id>:<attribute>, such as grp_abc123:parent_account_id. Resolvers look up the attribute’s value in the original group’s IDs.
Looking Up a User’s Groups
Rules check Remote Groups against the user’s list of group IDs, in the internal__gb_remoteGroupIds attribute. Set that list in one of these ways.
GrowthBook Proxy with Remote Evaluation
With remote evaluation, the Proxy (version 1.6.0 or later) loads uploaded IDs into Redis and looks up each user’s groups before evaluating. Your app doesn’t need to do anything. IDs sent by the client are ignored, so users can’t add themselves to a group. Rules that use a group the Proxy’s Redis hasn’t loaded yet don’t match anyone, so a “not in group” rule never matches everyone while a group is loading. See Loading IDs into Redis for the Proxy settings.JavaScript SDK
The JavaScript SDK (version 2.0.0 or later) can look up a user’s groups with a resolver. On the SDK Connection, set Pass Saved Groups by reference to All Saved Groups, so the payload lists the Remote Groups and their attributes. For a Node.js server withGrowthBookClient, add the user’s groups to the user context before evaluating:
redisResolver reads the Redis keys the GrowthBook loader writes. If the lookup fails, addRemoteSavedGroups returns the user context unchanged, so rules using Remote Groups don’t match. Unlike the Proxy, redisResolver doesn’t check whether a group has been loaded, so make sure it has before using it in “not in group” rules.
If you look up groups some other way, pass them directly with the remoteGroupIds option, or with growthbook.setRemoteGroupIds([...]) on a GrowthBook instance.
Using Your Own Storage
A resolver is a function that takes the user’s attributes and the Remote Groups in the payload, and returns the IDs of the groups the user is in:valuesFrom field: the ID of the group whose IDs to check that attribute’s value against.
Other SDKs and Older Versions
SDKs without Remote Group support still work, as long as you set the__gb_remoteGroupIds attribute yourself: an array of the IDs of the groups the user is in. Rules check that attribute directly. Include the <group id>:<attribute> IDs for groups used on other attributes that the user matches. Leave the attribute unset until you’ve looked the groups up, so rules don’t match too early.
Loading IDs into Redis
The GrowthBook Proxy’s loader polls GrowthBook for each Remote Group’s version, downloads new versions, and loads them into Redis. Replicas that share a Redis take turns. Run it inside the Proxy, or on its own withREMOTE_SAVED_GROUPS_LOADER_ONLY=true, for example next to the Redis your servers use.
The loader uses the Proxy’s
SECRET_API_KEY to read Remote Groups. To report what it loaded, the key also needs permission to publish Saved Groups; with a read-only key, it still loads but doesn’t report.
Store ID: use one ID per Redis. Replicas sharing a Redis, or one Redis Cluster, use the same ID, and each separate Redis gets a different one. Each Redis shows up under its ID in a version’s details.
Redis requirements:
- Redis 6.2 or later. Redis Cluster is supported.
- Loaded IDs have no expiry, so use an eviction policy that keeps them, such as
noevictionor avolatile-*policy, or a Redis just for Remote Groups. If Redis evicts them, users silently drop out of their groups.
Using the REST API
Uploads use the same signed-URL flow as the app. First ask for an upload URL:signedUrl. When fields is set, send a form POST with those fields and the file last; otherwise PUT the file. Then record the upload:
status.type is valid or invalid:
currentUploadVersion in a revision, then publish it. Pass new as the revision version to open a draft:
currentUploadVersion directly with POST /saved-groups/{id}.
To delete an old upload, use DELETE /api/v1/saved-groups/{id}/uploads/{version}. The version the group uses, or one an open draft uses, can’t be deleted.
Writing Your Own Loader
To load IDs into your own store:- Poll
GET /api/v1/saved-groups?type=remote&limit=100. The response is paginated: whilehasMoreis true, fetch the next page by passingnextOffsetasoffset. Each group’scurrentUploadhas theversionit uses, or isnullwhen it uses none. Archived groups are included. Only after every page succeeds, remove the IDs of groups missing from the complete list. - Download a version with
GET /api/v1/saved-groups/{id}/uploads/{version}/file. It redirects to a short-lived download URL; follow the redirect without theAuthorizationheader. - Load the IDs. Remove duplicates, and when
currentUpload.numericis true, store numbers in their shortest form (String(Number(id))). - Optionally report the result with
POST /api/v1/saved-groups/{id}/uploads/{version}/loads, so it shows in GrowthBook.
currentUpload names.
