roblox-datastores

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

roblox-datastores

roblox-datastores

Keep persistence on the server. For concurrent writes, use a pure
UpdateAsync
transform; after a write error, reconcile the backend state before retrying or compensating.
Official sources:
For temporary queues, lobbies, and caches, use MemoryStoreService. Read types-of-datastores.md when choosing a store.
Cross-reference:
  • roblox-networking/SKILL.md for server-authoritative validation before any write.
  • roblox-core/SKILL.md for service acquisition patterns, pcall discipline, and Luau serialization rules.
  • roblox-gamepasses/SKILL.md when purchases affect persistent state (re-verify ownership on load).
  • roblox/SKILL.md for the overall hub and Engine API link.
将持久化保留在服务器端。对于并发写入,使用纯粹的
UpdateAsync
transform;写入发生错误后,在重试或补偿之前,先核对后端状态。
官方来源:
对于临时队列、大厅和缓存,使用 MemoryStoreService。在选择存储类型时,阅读 types-of-datastores.md。
交叉参考:
  • roblox-networking/SKILL.md:在任何写入前进行服务器权威验证。
  • roblox-core/SKILL.md:了解服务获取模式、pcall 规范和 Luau 序列化规则。
  • roblox-gamepasses/SKILL.md:当购买会影响持久化状态时使用;加载时重新验证所有权。
  • roblox/SKILL.md:查看整体 hub 和 Engine API 链接。

Choose a store

选择存储类型

  1. Is the data temporary/ephemeral, high-churn, or only needed while servers are active (queues, lobbies, rate counters, short caches)?
    → Use MemoryStoreService (queues, sorted maps, etc.). DataStores are overkill and more expensive/slower. See references and official comparison.
  2. Do you need sorted numeric queries for leaderboards or rankings?
    → Use OrderedDataStore (via GetOrderedDataStore). Values must be integers. No versioning/metadata. Special GetSortedAsync + DataStorePages iteration. Limits differ (see references/limits...).
  3. Do you need versioning for recovery/audit, user-defined metadata, key listing, or the richer DataStore API (
    ListKeysAsync
    ,
    ListVersionsAsync
    ,
    GetVersionAsync
    ,
    GetVersionAtTimeAsync
    )? → Use the full DataStore created via
    GetDataStore
    with
    DataStoreOptions
    (this returns the modern DataStore class). Preferred for serious player data.
  4. Simple key-value persistent storage without the above needs?
    → Use
    DataStoreService:GetDataStore()
    (returns a standard DataStore) or
    DataStoreService:GetGlobalDataStore()
    (legacy global store, scope
    "u"
    ). For new work, prefer a named
    GetDataStore
    store.
Scopes vs prefixes (modern recommendation): For new work, prefer key prefixes (e.g. "profiles/User_1234") + ListKeysAsync filtering over legacy scopes. Scopes prepend to keys automatically. Use DataStoreOptions.AllScopes=true + empty scope string for cross-scope listing (see references).
Studio access: If Studio needs backend APIs, use a dedicated test experience. Do not enable Studio sessions to read or write production data.
  1. 数据是临时或短期的、高频变化的,或者仅在服务器运行期间需要(队列、大厅、速率计数器、短时缓存)吗?
    → 使用 MemoryStoreService(队列、有序映射等)。对于这些场景,DataStores 属于过度设计,而且成本更高、速度更慢。参见 references 和官方对比文档。
  2. 需要对排行榜或排名执行排序数值查询吗?
    → 使用 OrderedDataStore(通过 GetOrderedDataStore 获取)。值必须为整数。不支持版本控制或元数据。需要使用特殊的 GetSortedAsync + DataStorePages 迭代方式。限制有所不同(参见 references/limits...)。
  3. 需要版本控制以支持恢复或审计、需要用户自定义元数据、key 列出,或需要更丰富的 DataStore API(
    ListKeysAsync
    、
    ListVersionsAsync
    、
    GetVersionAsync
    、
    GetVersionAtTimeAsync
    )吗?
    → 使用通过
    GetDataStore
    和
    DataStoreOptions
    创建的完整 DataStore(这会返回现代 DataStore class)。对于重要的玩家数据,这是首选方案。
  4. 只需要简单、持久的键值存储,不需要以上功能吗?
    → 使用
    DataStoreService:GetDataStore()
    (返回标准 DataStore),或
    DataStoreService:GetGlobalDataStore()
    (旧版全局存储,scope 为
    "u"
    )。对于新项目,优先使用命名的
    GetDataStore
    存储。
Scope 与 prefix(现代建议): 对于新项目,优先使用 key prefix(例如
"profiles/User_1234"
)配合 ListKeysAsync 过滤,而不是旧版 scope。Scope 会自动前置到 key 之前。使用
DataStoreOptions.AllScopes=true
和空 scope 字符串进行跨 scope 列出(参见 references)。
Studio 访问: 如果 Studio 需要访问后端 API,请使用专用测试体验。不要启用 Studio 会话去读取或写入生产数据。

Recommended safety workflows

推荐的安全工作流

Player data profile pattern (most common)

玩家数据 profile 模式(最常见)

See references/best-practices-and-gotchas.md for full examples and variations (including session locking and profile patterns).
High-level server flow (in a ModuleScript required by ServerScriptService scripts):
  1. On PlayerAdded:
    • Load with pcall + GetAsync (consider UseCache=false for critical fresh read after potential previous server issues).
    • Merge with defaults.
    • Store in a server-side table or profile object (e.g.
      playerData[player.UserId] = data
      ).
    • Apply any gamepass perks (cross-ref monetization skill) or other state.
    • Optionally fire a Remote to client for initial UI sync (never trust client data).
  2. During play:
    • Mutate the in-memory profile.
    • Periodically auto-save (every 30-60s) using UpdateAsync or SetAsync with proper transform.
    • On important events (purchase, level up, trade), save immediately with UpdateAsync for safety.
  3. On PlayerRemoving / BindToClose / character death:
    • Final save with pcall.
    • Clean up in-memory data.
    • For BindToClose, yield up to ~30 seconds to finish final saves (Roblox gives a bounded grace period).
  4. On errors during write:
    • Use the verification pattern: after a failed write, immediately GetAsync with UseCache=false to see actual backend state before deciding retry/refund/rollback.
Use UpdateAsync with a pure (non-yielding) transform function for any value that can be concurrently modified by multiple servers. It reads-then-writes atomically from the perspective of the last writer.
Serialization rules (critical): Only nil, booleans, numbers (no inf/-inf/nan), strings (valid UTF-8), buffer, and tables of the above. No functions, no metatables on saved tables, no cycles. Use HttpService:JSONEncode on suspect data during development to preview what will actually be stored. See references/core-operations... .
有关完整示例和变体(包括会话锁定与 profile 模式),请参阅 references/best-practices-and-gotchas.md。
高层服务器流程(位于由 ServerScriptService 脚本 require 的 ModuleScript 中):
  1. 在 PlayerAdded 时:
    • 使用 pcall + GetAsync 加载(如果之前的服务器可能存在问题,对于关键数据的新鲜读取,可考虑使用
      UseCache=false
      )。
    • 与默认值合并。
    • 存储在服务端 table 或 profile 对象中(例如
      playerData[player.UserId] = data
      )。
    • 应用任何 gamepass 权益(交叉参考 monetization skill)或其他状态。
    • 可选择触发 Remote,向客户端同步初始 UI(绝不信任客户端数据)。
  2. 游玩期间:
    • 修改内存中的 profile。
    • 定期自动保存(每 30-60 秒),使用
      UpdateAsync
      或
      SetAsync
      及合适的 transform。
    • 发生重要事件时(购买、升级、交易),立即使用
      UpdateAsync
      保存以确保安全。
  3. 在 PlayerRemoving / BindToClose / 角色死亡时:
    • 使用 pcall 执行最终保存。
    • 清理内存数据。
    • 对于 BindToClose,最多 yield 约 30 秒以完成最终保存(Roblox 会提供有界的宽限期)。
  4. 写入发生错误时:
    • 使用验证模式:写入失败后,立即使用
      UseCache=false
      执行 GetAsync,以查看实际后端状态,再决定重试、退款或回滚。
对于任何可能被多个服务器并发修改的值,请使用带有纯粹(非 yield)transform 函数的 UpdateAsync。它会先读取再写入;从最后写入者的角度看,这一过程是原子的。
序列化规则(关键): 只能存储 nil、boolean、number(不能为 inf/-inf/nan)、string(必须是有效 UTF-8)、buffer,以及由上述类型组成的 table。不得存储 function、带有 metatable 的已保存 table 或循环引用。开发期间,可对可疑数据使用 HttpService:JSONEncode,预览实际将被存储的内容。参见 references/core-operations...。

Leaderboards with OrderedDataStore

使用 OrderedDataStore 实现排行榜

Populate on relevant value changes or on save (use SetAsync or Increment).
Query with GetSortedAsync(ascending, pageSize, min?, max?) → DataStorePages. Iterate pages with GetCurrentPage() + AdvanceToNextPageAsync().
For bulk reads, use
BatchGetAsync(keys)
to fetch multiple ordered entries in one request. Each key counts as one
OrderedRead
(see error-codes-and-limits for quotas; missing keys are omitted). Remember: only numbers; keys are strings; page iteration has its own limits; no versioning.
Display in a ScrollingFrame or via UI on demand. Cache top-N in a standard DataStore if you want fast global access without repeated queries.
See references for full page iteration example and limits differences.
在相关值发生变化或保存时填充数据(使用 SetAsync 或 Increment)。
使用
GetSortedAsync(ascending, pageSize, min?, max?)
→ DataStorePages 进行查询。通过
GetCurrentPage()
+
AdvanceToNextPageAsync()
迭代各页。
对于批量读取,使用
BatchGetAsync(keys)
在一次请求中获取多个有序条目。每个 key 都会占用一个
OrderedRead
配额(参见 error-codes-and-limits;缺失的 key 会被省略)。
请注意:只支持 number;key 必须是 string;分页迭代有独立限制;不支持版本控制。
在 ScrollingFrame 中显示,或通过按需加载的 UI 显示。如果希望无需重复查询即可快速进行全局访问,可以将 top-N 缓存在标准 DataStore 中。
有关完整的分页迭代示例和限制差异,请参阅 references。

Versioning and recovery

版本控制与恢复

Every Set/Update/Increment on a standard DataStore (not Ordered) creates hourly-versioned backups: the first write to a key in a given UTC hour creates a new version snapshot, and subsequent writes in the same hour overwrite that hourly version. Versioned backups expire ~30 days after being superseded; the current version never expires.
  • ListVersionsAsync(key, sort, minDate?, maxDate?, pageSize?)
  • GetVersionAsync(key, version)
  • RemoveVersionAsync
    is deprecated. Do not present it as a current cleanup API; retain versions for recovery and use
    ListVersionsAsync
    ,
    GetVersionAsync
    , or
    GetVersionAtTimeAsync
    to inspect them.
  • GetVersionAtTimeAsync(key, timestampMillis): find the version current at a specific past time.
  • To revert: read the desired version, then SetAsync the value + metadata back (this creates a new current version).
Also use the daily Snapshot Data Stores Open Cloud API before risky publishes.
The Data Stores Manager in Creator Hub lets you browse keys, view metadata/version history, compare versions, and revert (with proper permissions).
See references/versioning-metadata-recovery.md for complete code samples including the "revert to time of incident" pattern.
标准 DataStore(非 Ordered)上的每次 Set/Update/Increment 都会创建按小时版本化的备份:在指定 UTC 小时内的首次 key 写入会创建新的版本快照,同一小时内的后续写入会覆盖该小时版本。版本化备份被取代约 30 天后会过期;当前版本永不过期。
  • ListVersionsAsync(key, sort, minDate?, maxDate?, pageSize?)
  • GetVersionAsync(key, version)
  • RemoveVersionAsync
    已弃用。不要将其作为当前的清理 API;应保留版本以供恢复,并使用
    ListVersionsAsync
    、
    GetVersionAsync
    或
    GetVersionAtTimeAsync
    进行检查。
  • GetVersionAtTimeAsync(key, timestampMillis)
    :查找过去某一特定时间点生效的版本。
  • 要回滚:先读取目标版本,然后使用 SetAsync 将值和元数据写回(这会创建新的当前版本)。
在执行高风险发布前,还要使用每日 Snapshot Data Stores 的 Open Cloud API。
Creator Hub 中的 Data Stores Manager 允许你浏览 key、查看元数据和版本历史、比较版本及回滚(需具备适当权限)。
有关完整代码示例,包括“回滚到事故发生时间”模式,请参阅 references/versioning-metadata-recovery.md。

Caching control

缓存控制

By default: GetAsync results are cached locally for 4 seconds. Subsequent Gets within the window return cache and do not count against limits. Writes update the cache immediately.
For verification after writes (especially after errors), or when you suspect staleness due to other servers:
lua
local opts = Instance.new("DataStoreGetOptions")
opts.UseCache = false
local value, info = store:GetAsync(key, opts)
This always hits the backend and counts against quotas. Use sparingly but correctly.
See references/versioning-metadata-recovery.md (for listing, caching, serialization) and references/best-practices-and-gotchas.md .
默认情况下:GetAsync 结果会在本地缓存 4 秒。在此时间窗口内,后续 Gets 会返回缓存,且不会计入限制。写入会立即更新缓存。
用于写入后的验证(尤其是写入出错后),或者怀疑其他服务器导致数据过期时:
lua
local opts = Instance.new("DataStoreGetOptions")
opts.UseCache = false
local value, info = store:GetAsync(key, opts)
这始终会访问后端并计入配额。应谨慎而正确地使用。
有关列出、缓存和序列化,请参阅 references/versioning-metadata-recovery.md;另请参阅 references/best-practices-and-gotchas.md。

Limits, quotas, throttling, and budgets

限制、配额、节流与预算

There are experience-level limits (scale with concurrent users across the whole experience) and per-server limits (configurable via DataStoreService:SetRateLimitForRequestType). Experience-level pools are shared between game servers and Open Cloud v2 Data Store traffic. Bulk external jobs can throttle live players (and vice versa).
UpdateAsync counts against both read and write budgets.
Use DataStoreService:GetRequestBudgetForRequestType(Enum.DataStoreRequestType.XXX) to check before heavy operations and wait in a loop if necessary.
Queues exist (size 30); when full, you get throttle errors (301-306 range or the newer *Throttled errors).
Full tables of every error code (101 KeyNameEmpty ... through all the *ExperienceThrottled and *GameServerThrottled variants), experience formulas (base 300 + concurrentUsers × N), and server-side errors are in references/limits-quotas-throttling-error-codes.md .
Observability dashboard (Creator Hub → Monitoring → Data Stores) shows real-time request counts by API/status, quota usage percentages, storage bytes vs limit.
Data Stores Manager shows total size vs storage limit (
500 MB + 1 MB × lifetime users
, measured as compressed latest-version size), per-DS key counts, etc. Do not pre-compress values before writing.
Call SetRateLimitForRequestType early in server init (once per type) to raise limits for migration scripts or busy servers. Base + (perPlayer * numPlayers). Constraints per type are documented.
这里有体验级限制(随整个体验的并发用户数扩展)和单服务器限制(可通过 DataStoreService:SetRateLimitForRequestType 配置)。体验级配额池由游戏服务器和 Open Cloud v2 Data Store 流量共享。批量外部任务可能会对活跃玩家流量进行节流,反之亦然。
UpdateAsync 同时计入读取和写入预算。
在执行高开销操作前,使用
DataStoreService:GetRequestBudgetForRequestType(Enum.DataStoreRequestType.XXX)
检查预算;如有必要,请在循环中等待。
队列容量为 30;队列满时会出现节流错误(301-306 范围或较新的 *Throttled errors)。
每个错误码的完整表格(从 101 KeyNameEmpty ... 到所有 *ExperienceThrottled 和 *GameServerThrottled 变体)、体验级计算公式(基础值 300 + concurrentUsers × N)以及服务器端错误,均见 references/limits-quotas-throttling-error-codes.md。
可观测性仪表板(Creator Hub → Monitoring → Data Stores)会按 API/状态显示实时请求数、配额使用百分比以及存储字节数与上限的对比。
Data Stores Manager 会显示总大小与存储上限的对比(
500 MB + 1 MB × lifetime users
,按压缩后的最新版本大小计算)、每个 DS 的 key 数量等。写入前不要预先压缩值。
在服务器初始化早期调用 SetRateLimitForRequestType(每种类型调用一次),为迁移脚本或繁忙服务器设置更高限制。基础值 +(perPlayer * numPlayers)。每种类型的限制条件均有文档说明。

Handle uncertain writes

处理结果不确定的写入

Every datastore call must be inside pcall.
On failure:
  • Log the specific error code/message.
  • Retry reads with bounded exponential backoff and jitter.
  • Treat an invoked write that returns an error as unknown, not rejected: reconcile with a fresh
    GetAsync
    using
    UseCache = false
    .
  • Replay a write only when the caller has proved the entire operation idempotent. Never automatically replay
    IncrementAsync
    .
  • Return explicit
    committed
    ,
    rejected
    , or
    unknown
    status so purchase/recovery code cannot mistake ambiguity for failure.
Never assume a failed Set/Update/Increment means "no change occurred."
UpdateAsync
transforms can run multiple times and must not yield or produce external side effects.
RemoveAsync creates a "tombstone" (Get returns nil) but older versions remain queryable for 30 days (unless explicitly removed).
每个 datastore 调用都必须放在 pcall 中。
失败时:
  • 记录具体错误码或错误消息。
  • 使用带抖动的有界指数退避重试读取。
  • 将已发起但返回错误的写入视为 unknown,而不是 rejected:使用
    UseCache = false
    发起新鲜的 GetAsync 来核对状态。
  • 只有在调用方已证明整个操作幂等时,才能重放写入。绝不自动重放
    IncrementAsync
    。
  • 返回明确的
    committed
    、
    rejected
    或
    unknown
    状态,使购买或恢复代码不会将结果不确定性误判为失败。
绝不要假设失败的 Set/Update/Increment 意味着“未发生更改”。
UpdateAsync
transform 可能运行多次,因此不得 yield,也不得产生外部副作用。
RemoveAsync 会创建一个“墓碑”(Get 返回 nil),但旧版本在 30 天内仍可查询(除非已显式移除)。

Management and monitoring

管理与监控

  • Use Data Stores Manager (Creator Hub) for inspection, key search by prefix, version compare/revert, and scheduled deletion (with cooldown). The Manager's Revert button can revert an individual key to a previous version. The Restore button is for data stores that are marked for deletion, not for reverting a key's value. Restoring a deleted key during its cooldown requires calling
    UpdateAsync
    from the Engine API or
    UpdateDataStoreEntry
    from Open Cloud.
  • Observability dashboard for trends and quota forecasting.
  • For bulk delete/migrate: Open Cloud Data Stores APIs or the official Batch Processor CLI/tool.
  • Set up notifications for approaching/exceeding storage limits.
  • Review usage regularly.
See references/versioning-metadata-recovery.md (covers listing/caching) and the manager/observability pages (linked in best-practices-and-gotchas.md).
  • 使用 Data Stores Manager(Creator Hub)进行检查、按 prefix 搜索 key、比较或回滚版本,以及计划删除(带冷却时间)。Manager 的 Revert 按钮可将单个 key 回滚到之前的版本。Restore 按钮用于恢复已标记为删除的数据存储,而不是回滚 key 的值。要在冷却期内恢复已删除的 key,需要通过 Engine API 调用
    UpdateAsync
    ,或通过 Open Cloud 调用
    UpdateDataStoreEntry
    。
  • 使用可观测性仪表板分析趋势并预测配额。
  • 对于批量删除或迁移:使用 Open Cloud Data Stores API 或官方 Batch Processor CLI/工具。
  • 设置接近或超过存储上限时的通知。
  • 定期检查使用情况。
有关列出和缓存,请参阅 references/versioning-metadata-recovery.md;有关 Manager 和可观测性页面,请参阅 best-practices-and-gotchas.md 中链接的文档。

Checklists

检查清单

Before any critical write:
  • Wrapped in pcall with explicit committed/rejected/unknown handling
  • Using UpdateAsync where races are possible, with a pure transform
  • Providing userIds array for RTBF/GDPR tracking where appropriate
  • Metadata supplied on every write (even if unchanged) when using full DataStore
  • Value is serializable (test with JSONEncode during dev)
  • Key naming consistent with prefixes for easy listing
On player join/load:
  • Fresh load or cache-aware as appropriate
  • Merge defaults safely
  • Re-verify ownership on PlayerAdded (gamepasses, etc.) and re-apply any non-owned one-time consumable grants
  • Client sync only of non-sensitive derived state
Before publishing risky data-logic changes:
  • Take a daily snapshot via Open Cloud if available
  • Test thoroughly on a copy experience
Ongoing:
  • Monitor dashboard and manager
  • Clean test/temporary data
  • Use MemoryStores for anything that doesn't need to survive server death
  • Prefer fewer data stores + larger cohesive objects + key prefixes
任何关键写入之前:
  • 使用 pcall 包裹,并明确处理 committed/rejected/unknown 状态
  • 在可能发生竞争时使用 UpdateAsync,并采用纯粹 transform
  • 在适当情况下提供 userIds 数组,以支持 RTBF/GDPR 跟踪
  • 使用完整 DataStore 时,每次写入都提供元数据(即使元数据未发生变化)
  • 值可序列化(开发期间使用 JSONEncode 测试)
  • key 命名与 prefix 保持一致,以便轻松列出
玩家加入或加载时:
  • 根据情况执行新鲜加载或缓存感知加载
  • 安全地与默认值合并
  • 在 PlayerAdded 时重新验证所有权(如 gamepass 等),并重新应用任何尚未标记为已拥有的一次性消耗品授权
  • 仅向客户端同步非敏感的派生状态
发布高风险数据逻辑变更之前:
  • 如果可用,通过 Open Cloud 获取每日快照
  • 在副本体验中进行充分测试
持续进行:
  • 监控仪表板和 Manager
  • 清理测试或临时数据
  • 对任何不需要在服务器退出后保留的数据使用 MemoryStores
  • 优先使用更少的数据存储、较大的内聚对象和 key prefix

Common mistakes

常见错误

  • Calling from client/LocalScript (immediate error + security hole).
  • Storing functions, metatables, or non-serializable data.
  • Using SetAsync for contended values (race condition → lost updates or duplication).
  • Ignoring throttle errors and hammering (leads to dropped requests and player frustration).
  • Hardcoding studio API access on live places.
  • Creating hundreds of tiny data stores instead of organizing by key/prefix.
  • Relying on cached Gets for post-write verification.
  • Forgetting that OrderedDataStore has no versioning and only integers.
  • Not handling the case where RemoveAsync has already been called (nil + tombstone).
  • Exceeding storage quota without monitoring (leads to surprise costs and potential write failures).
  • 从客户端或 LocalScript 调用(会立即报错并造成安全漏洞)。
  • 存储 function、metatable 或不可序列化的数据。
  • 对存在竞争的值使用 SetAsync(竞态条件可能导致更新丢失或重复)。
  • 忽视节流错误并持续冲击服务(会造成请求丢失和玩家不满)。
  • 在正式发布的 place 中硬编码 Studio API 访问。
  • 创建数百个微型数据存储,而不是按 key 或 prefix 组织数据。
  • 写入后验证时依赖缓存 Get。
  • 忘记 OrderedDataStore 不支持版本控制且只能存储整数。
  • 未处理 RemoveAsync 已被调用的情况(nil + 墓碑)。
  • 未监控就超出存储配额(可能导致意外费用和写入失败)。

Scripts folder usage

scripts 目录用法

The
scripts/
directory contains maturity-labeled examples:
  • SafeDataStore.lua
    : reviewed example with automatic read retries, explicit write states, opt-in idempotent replay, and uncached reconciliation.
  • BudgetMonitor.lua
    : experimental budget-inspection example.
Adapt and validate them in a dedicated test experience; this directory is not a versioned production library.
scripts/
目录包含按成熟度标注的示例:
  • SafeDataStore.lua
    :经过审查的示例,包含自动读取重试、明确的写入状态、可选启用的幂等重放,以及不使用缓存的状态核对。
  • BudgetMonitor.lua
    :实验性的预算检查示例。
在专用测试体验中适配并验证这些脚本;此目录不是可作为生产依赖进行版本管理的库。

How to proceed in practice

实际操作步骤

  1. Read the relevant references/ file(s) for the exact feature you are implementing.
  2. Implement using the patterns and code samples here + in references.
  3. Test budget behavior under load (use multiple test servers or the rate-limit setter for simulation).
  4. Add observability and alerts early.
  5. Profile storage growth with the Manager/Dashboard.
Combine this guidance with static analysis, focused tests, Studio integration, observability, and current official sources before trusting a persistence system.
For the authoritative class/property reference for any specific method, always cross-check https://create.roblox.com/docs/reference/engine (search for DataStoreService, GlobalDataStore, etc.).
<!-- catalog:references:start -->
  1. 阅读相关 references/ 文件,了解所实现功能的准确细节。
  2. 使用此处及 references 中的模式和代码示例进行实现。
  3. 在负载下测试预算行为(可使用多个测试服务器或 rate-limit setter 进行模拟)。
  4. 尽早添加可观测性和告警。
  5. 使用 Manager/Dashboard 分析存储增长。
在信任持久化系统前,应将本指南与静态分析、针对性测试、Studio 集成、可观测性以及当前官方资料结合使用。
有关任何具体方法的权威 class/property 参考,请始终核对 https://create.roblox.com/docs/reference/engine(搜索 DataStoreService、GlobalDataStore 等)。
<!-- catalog:references:start -->

Reference index

Reference index

  • best-practices-and-gotchas.md: Design player profiles, session locking, saves, or deletion workflows.
  • core-operations-and-patterns.md: Implement reads, writes, transforms, or error recovery.
  • limits-quotas-throttling-error-codes.md: Diagnose throttling, inspect budgets, or plan request and storage usage.
  • types-of-datastores.md: Choose standard, ordered, or temporary storage and organize keys.
  • versioning-metadata-recovery.md: Inspect versions, preserve metadata, or recover data after an incident.
<!-- catalog:references:end -->
  • best-practices-and-gotchas.md:设计玩家 profile、会话锁定、保存或删除工作流。
  • core-operations-and-patterns.md:实现读取、写入、transform 或错误恢复。
  • limits-quotas-throttling-error-codes.md:诊断节流问题、检查预算或规划请求与存储用量。
  • types-of-datastores.md:选择标准、有序或临时存储,并组织 key。
  • versioning-metadata-recovery.md:检查版本、保留元数据或在事故后恢复数据。
<!-- catalog:references:end -->