Skip to content

KeepBlox

Player data for Roblox that loses nothing, fails loudly, and never stutters a frame. It reads and writes ProfileStore's records, so you can switch with one require and switch back.

KeepBlox keeps session-locked player profiles on DataStore. Only one server can write a profile at a time, and a server that loses the session stops writing at once.

It stores the same record format as ProfileStore and speaks the same lock protocol. That gives you three things:

  • Switch with one require. KeepBlox.Compat.ProfileStore is ProfileStore’s API over KeepBlox. Keys stay where they are, in the same format.
  • Mixed servers. Old ProfileStore servers and new KeepBlox servers can run side by side during a rollout. A session hands over between them in both directions.
  • Switch back. A key KeepBlox wrote is still a ProfileStore record.

See Migrating from ProfileStore for the details.

Every library below ran unmodified in the same simulator, over seeds 1-20, with the same players and faults. The worst case over all seeds is shown. The benchmarks page has every scenario and the methodology.

KeepBlox ProfileStore ProfileService
Invariant violations 0 0 0
Progress a server crash loses (steps of play) 4 287 29
Data store reads per player-hour 13.1 13.6 122.0
Data store writes per player-hour 13.1 13.6 122.0
Slowest open after a crash (s) 9.1 46.6 63.7

On Roblox’s real services (the live check) a hand-over took 4.2-4.6 s and a crash takeover 11.6-12.9 s; live calls take 0.3-0.6 s each. A crashed KeepBlox server is known dead within about 9 seconds in the simulator: every server beats in MemoryStore every 4 seconds, and a beat that stands still for two beats means the server is gone. The same beat carries a snapshot of each changed profile (a large one as its edits since it was stored), so a crash loses about one beat of play instead of an autosave interval. How it works explains the mechanism.

local Players = game:GetService("Players")
local ServerScriptService = game:GetService("ServerScriptService")
local KeepBlox = require(ServerScriptService.KeepBlox)
local store = KeepBlox.store("Profiles", { template = { coins = 0 } })
Players.PlayerAdded:Connect(function(player)
local result = store:load(`u_{player.UserId}`, {
cancel = function()
return player.Parent == nil
end,
})
if not result.ok then
player:Kick(`Your data could not be loaded ({result.reason}). Please rejoin.`)
return
end
result.profile.Data.coins += 10 -- change it in place; KeepBlox saves it
end)
Players.PlayerRemoving:Connect(function(player)
local profile = store:profiles()[`u_{player.UserId}`]
if profile then
profile:release()
end
end)

The quick start walks through a complete setup.

Offline messages and edits

Send a gift to a player who is offline with store:message; it is handled exactly once. Edit a key from a support tool with store:edit, without kicking anyone. Messages and edits.

Trades

store:trade changes two profiles open on the same server together: both or neither. Trades.

Shared documents

KeepBlox.shared holds documents no server owns, changed atomically by any server. Shared documents.

Leaderboards

A number read from each profile, mirrored to an ordered data store and read back with store:leaderboard. Leaderboards.

Importers

Move from DocumentService, Lapis, DataKeep, DataStore2 or Suphi’s DataStore Module, one key at a time on its first load. Importing.

Purchases

KeepBlox.processReceipt grants a developer product once and never loses it. Purchases.

Schema and migrations

Describe the data with KeepBlox.schema, and move old data forward with numbered migrations. Give them a way back and writeVersion, and a release can be rolled back without locking anyone out. Schema and migrations.

Versions and rollback

List a key’s past versions, read one, and restore it safely. A restore names the purchases it took back, so none is lost quietly. Versions and rollback.

Compression

Profiles over a threshold are stored compressed, so data past the 4 MB limit still saves. Large profiles.

Studio modes

Play tests use the live store, memory only, or a read-only copy of live data. Studio and testing.

Every promise KeepBlox makes is checked by a spec in the repository. Guarantees lists each one with the spec that proves it.