Find out exactly why your Roblox game broke.

Workshell puts every error, log, trace and exploit flag on the timeline of the player it happened to, and tells you which release shipped it. One binary, on your own server.

Below is one real session, recorded from a demo game with simulated players.

  1. Player 100796674 joinedsess-e3b27-806
    Server
    83bd996b
    Release
    cdab8c7
    Device
    Desktop · PH
    Membership
    Premium
    Length
    15m 40s
    Join
    4.02 s
    Errors
    1
    Quarantined
    16
    Flags
    5

The join took four seconds.

DataStore throttled twice before the third GetAsync worked. Time anything with Workshell.trace, then open any slow run span by span.

  • p50 and p95 for every traced operation
  • Server frame rate, heartbeat and memory alongside
player.join4.02 s · 9 spans
player.join4.02 s
datastore.load3.77 s
datastore.GetAsync1.38 s
datastore.GetAsync1.25 s
datastore.GetAsync1.13 s
inventory.build9 ms
character.spawn230 ms
character.loadAppearance196 ms
remote.sendInitialState5.8 ms

Two minutes in, they started flying.

Your anti-cheat reports it with one call, Workshell.flag, and Workshell.protect validates and rate-limits your remotes. Every flag stays on the player, the session and the security page.

flymediumreported by the game
noclipmediumreported by the game
client_floodmediumdetected by Workshell
item_dupehighreported by the game
speedhighkicked

Then the shop broke.

attempt to perform arithmetic (sub) on nil and number, grouped with 642 other events from 579 players. With a Rojo sourcemap, the frames point at your files, at the commit that shipped them.

  • First seen in release 102; flagged as a regression if it returns after a fix
  • Breadcrumbs and the session it happened in, one click away
  • Assign it, discuss it, open a linked GitHub issue
attempt to perform arithmetic (sub) on nil and numberclient
  1. 1
    Players.Player.PlayerGui.ShopUI.ShopController:210 updatePrice src/client/ShopUI/ShopController.client.luau:210
  2. 2
    Players.Player.PlayerGui.ShopUI.ShopController:64 src/client/ShopUI/ShopController.client.luau:64

Then they tried to flood your error list.

The same client started firing fake "injected" errors. Workshell kept 16, dropped the rest at the per-player limit, flagged the flood and quarantined what got through, so your issue list still leads with the shop bug.

injected 327121quarantined

16 events from player 100796674 in 2.5 s, the rest dropped at 15 a minute · kept out of Issues

Signed requests
A leaked ingest key can't forge or replay data.
Flood caps
Per player and per server, so spam can't bury real issues.
Text stays text
Player-supplied strings never render as HTML.
Encrypted secrets
Webhooks and tokens are AES-256-GCM at rest.

They left after 16 minutes. You still have all of it.

Every session keeps its timeline next to the player's frame rate, ping and memory. Attach your own metadata with Workshell.setUser, or store HMAC-hashed player ids instead of real ones.

The session's timeline: joined, the join trace's spans, fly, the shop error, noclip and the quarantined injected errors

The team works it out together.

The trace, the issue and the session go on a shared whiteboard, with notes pinned where things broke, until someone owns the fix.

A whiteboard: the shop issue, the slow join trace as a node graph, and sticky notes with the cause and the fix

Session ended

Recording starts with a few lines of Luau.

ServerScriptService/Workshell.server.luau
local Workshell = require(game.ReplicatedStorage.Workshell)
Workshell.init({
	url = "https://workshell.yourgame.dev",
	key = HttpService:GetSecret("workshell_key"),
})

Errors, output, sessions, server health, client performance and purchases are captured from there.

Your server
git clone https://github.com/Shellworks-Development/workshell
cd workshell
docker compose up -d   # or: make build && ./bin/workshell

Put it behind Caddy, nginx or a Cloudflare Tunnel so your game servers can reach it.

Server
One 16 MB Go binary
Storage
One SQLite file
Queue
In-process, or Redis for durability
License
Source available, free to self-host

Also included: live logs, release health, analytics and funnels, custom metrics, Discord and webhook alerts, a team inbox, and themes down to Catppuccin.

The same session in Workshell on a phone

The next session is already running.

Workshell installs as an app on your phone, so you can open it from anywhere. A hosted version is on the way; watch the repository to hear when it ships.