Users and scoped user IDs

Roblox exposes one effective user ID for each user in each game, group, or app. Depending on the user's history with that domain, their effective user ID is either their global user ID or a scoped user ID. This page explains how effective user IDs work and how to use the User type in your game code.

The following concepts are central to user identification:

ConceptDescription
UserA persistent account on Roblox.
PlayerThe representation of a user within a running game's data model (see Players).
User data typeA data type that carries a user's effective user ID and its domain context. This is the standard identifier for referencing users in game code.
Global user IDThe platform-level user ID that Roblox assigns to each account. It's globally unique across Roblox.
Scoped user IDA user ID assigned within a specific domain. A user's scoped user IDs are different in each game, group, or app.
Effective user IDThe single user ID that Roblox exposes for a user within a domain.
Pre-rollout userA user who first engaged with a domain before the scoped user ID rollout. In that domain, their effective user ID remains their global user ID.
Post-rollout userA user who first engaged with a domain after the scoped user ID rollout. In that domain, their effective user ID is a scoped user ID.

Effective user IDs and domains

Each user has one effective user ID within a specific game, group, or app. Roblox doesn't expose separate global and scoped user IDs for the same user in that domain:

  • A pre-rollout user has their global user ID as their effective user ID.
  • A post-rollout user has a scoped user ID as their effective user ID. That ID is only meaningful within that domain.

In game code, Player.UserId and Player.User.Id both return this effective user ID and always have the same numeric value (Player.User.Id equals Player.UserId), so your code doesn't need branching logic to choose between them.

Roblox scopes user identity across three types of domains:

DomainScoped toExample
Experience (Enum.DomainType.EXPERIENCE)A specific experienceA player's ID in your experience
GroupA specific Roblox group (community)A member's ID in your group
OAuth app (Enum.DomainType.OAUTH)A specific OAuth applicationA user's ID in your external tool

How effective user IDs work

When a player joins your game, they have one effective user ID for that game. A post-rollout user's effective user ID is a scoped user ID unique to that game. They receive a different scoped user ID in any other game, group, or app where they are also a post-rollout user. This means:

  • Effective user IDs are integers, whether they are global or scoped.
  • Effective user IDs are stable across sessions within the same domain.
  • A scoped user ID does not collide with any existing global user ID.
  • The same numeric value can appear in different domains for different users. The unique key is the combination of the domain (domain type and domain ID) and the effective user ID.

Example scenario

The following example demonstrates how different games reference the same user:

ScenarioUser contextEffective user ID seen by game
User connects to Game APre-rollout user123 (global user ID, unchanged)
User connects to Game BPost-rollout user500789 (scoped user ID for Game B)
User connects to Game CPost-rollout user302441 (scoped user ID for Game C)

Pre-rollout users

If a player is a pre-rollout user in your game, their effective user ID remains their global user ID in that game. Both Player.UserId and Player.User.Id return that global user ID. Roblox doesn't expose a second user ID for the player in that game. This ensures existing data store keys, leaderboards, and inventories continue to work without any changes.

Group domain

Each Roblox group is its own domain. A user has one effective user ID within a group, separate from their effective user ID in any game or OAuth application:

Working with the User Type

User is the standard way to identify users in game code. A User value carries the effective user ID alongside the domain type and domain ID, so the identity context always travels with the identifier. For full API details, see the User reference.

Get a User from a Player

The primary way to obtain a User is from a connected Player via Player.User:

local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
local user = player.User
print("Effective user ID:", user.Id) -- Always matches player.UserId
print("Domain type:", user.DomainType)
print("Domain ID:", user.DomainId)
end)

Construct a User from an ID

To create a User from a known effective user ID within the current game, use User.fromId():

local user = User.fromId(knownUserId)

Using User with engine APIs

Engine APIs that accept a user ID parameter also accept User values directly. Using User is recommended:

-- Both forms work:
BadgeService:AwardBadge(player.User, badgeId) -- Recommended
BadgeService:AwardBadge(player.UserId, badgeId)
-- Both forms work:
local target = Players:GetPlayerByUserId(player.User) -- Recommended
local target = Players:GetPlayerByUserId(someUserId)

When a numeric user ID is passed to an engine API that accepts user IDs, it is automatically wrapped into a User internally.

Engine APIs that return user IDs

Engine APIs that return numeric user IDs return the user's effective user ID:

  • Pre-rollout users — the API returns the user's global user ID.
  • Post-rollout users — the API returns the user's scoped user ID.

Player.UserId, Player.User.Id, and other engine APIs all return this same effective user ID for a user in your game, so existing code that reads numeric user ID fields continues to work without branching logic.

Open Cloud requests and responses use the same effective user ID for the target domain. They don't expose a second user ID for the same user in that domain.

Storing user identity

Use a numeric effective user ID only to identify a user within a single domain. A data store key in one game can use user.Id directly:

local key = ("player_%d"):format(player.User.Id)
PlayerDataStore:SetAsync(key, data)

When another domain reads the stored identity, such as an OAuth app that moderates users, store the string from ToString(). The string encodes the domain context together with the effective user ID. Using the integer alone can apply an action to the wrong user when the same number identifies a different user in another domain.

local encoded = player.User:ToString()
SomeDataStore:SetAsync("support_ticket_user", encoded)
-- Later, restore from the string
local user = User.fromString(encoded)

For more details on serialization guarantees, see the User reference.

Best practices

  • Use Player.User as the standard identifier in new code.
  • Use the numeric effective user ID only within a single domain, such as data store keys for one game.
  • Use ToString() and fromString() when another domain reads the stored identity.

When to use User or Player

  • Use Player for in-server actions: character movement, GUI, teleport, chat, inventory.
  • Use User for identity that outlives a session: data stores, Open Cloud tools, cross-game references.
©2026 Roblox Corporation. Roblox, the Roblox logo and Powering Imagination are among our registered and unregistered trademarks in the U.S. and other countries.