The Performance Audit workflow systematically identifies and resolves the most common performance bottlenecks in Roblox games: excessive part counts, CPU-heavy script patterns, memory leaks from unmanaged connections, and over-eager network traffic. It covers eight steps from initial project scan through applied fixes and a before/after comparison. Use this workflow when your game drops below target frame rate, when the MicroProfiler shows unexpected spikes, or as part of the Publish Checklist before going live. Trigger: “Audit performance”, “my game is lagging”, “optimize my game”, “FPS is low”, or as a pre-publish step.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/brockmartin/roblox-game-skill/llms.txt
Use this file to discover all available pages before exploring further.
Project Scan
Claude gathers baseline information and scans for known anti-patterns before diving into specific categories.All findings are recorded with file paths and line numbers for use in the priority report.
- Full Mode
- Standard Mode
- Offline Mode
Uses
get_project_structure to map the full source tree, then grep_scripts to scan for:wait(— deprecated; should betask.wait().Heartbeat:Connect(— count across all scriptsInstance.newinside loops — mass instantiation without poolingwhile true dotight loops without yieldinggame:GetServicecalled inside functions instead of cached at script top
Part Count Audit
Claude evaluates the workspace part count and physics complexity.
Beyond total count, Claude checks:
| Part Count | Status |
|---|---|
| Under 10,000 | Acceptable for most genres |
| 10,000–50,000 | Needs StreamingEnabled or aggressive culling |
| Over 50,000 | Critical — redesign required |
- Unanchored parts —
BasePartinstances whereAnchored == falsethat are not intentionally physics-driven. Each costs physics simulation time every frame. - MeshPart triangle counts — Any MeshPart exceeding 10,000 triangles is flagged for LOD or replacement.
- Transparency abuse — Parts with
Transparency = 1that still haveCanCollide = trueshould haveCanCollideandCanQuerydisabled and be removed from the render pipeline entirely. - Union complexity — Large CSG
UnionOperationinstances that could be replaced withMeshPartfor better GPU performance.
Script Audit
Claude reviews runtime script behavior for CPU-heavy patterns.
Example: deprecated API and service caching
| Pattern | Issue | Fix |
|---|---|---|
Multiple Heartbeat connections per script | Fragmented update logic | Consolidate into a single connection |
while true do faster than needed | Wastes CPU every tick | Throttle to task.wait(1/30) or task.wait(1/60) |
game:GetService inside function bodies | Repeated lookup every call | Cache as top-level locals |
wait() / spawn() / delay() | Deprecated; unreliable timing | Replace with task.wait() / task.spawn() / task.delay() |
String .. concatenation in hot paths | Creates garbage per concatenation | Use table.concat |
Deep FindFirstChild / WaitForChild chains | Fragile and slow | Cache references at initialization |
Memory Audit
Claude searches for memory leaks and resource retention issues.Undisconnected event connections are the most common leak in Roblox games. Claude scans for Claude also checks for:
:Connect( calls where the returned RBXScriptConnection is never stored or disconnected — especially inside PlayerAdded, CharacterAdded, and any function called repeatedly.Instance.new()calls where the instance is never parented or destroyed (orphaned in memory)Debris:AddItem()with lifetimes over 60 seconds, or not used at all for temporary effectsIntValue/ObjectValueinstances created dynamically but never destroyed- Lua tables that grow unboundedly (e.g., logging every frame without pruning)
Network Audit
Claude evaluates RemoteEvent firing patterns for bandwidth efficiency.
Example: throttled remote firing
| Issue | Description | Fix |
|---|---|---|
Remotes inside Heartbeat / tight loops | Fires every frame — floods bandwidth | Gate with a throttle timer |
| Large table payloads (50+ keys) | Expensive to serialize | Send only changed fields |
FireAllClients for player-specific data | Sends private data to everyone | Switch to FireClient |
Excessive SetAttribute on replicated instances | Causes network churn | Batch updates or use remotes |
Instance.new on server in hot paths | Replicates to all clients | Move VFX to client-side |
Priority Report
Claude compiles all findings into a tiered report.
| Severity | Threshold |
|---|---|
| Critical | Crashes, server lag above 100 ms, or client FPS below 30 on target hardware |
| High | Measurable frame drops, memory growth over time, or bandwidth spikes |
| Medium | Patterns that degrade under load (20+ players) |
| Low | Best-practice improvements with minor performance benefit |
Apply Fixes
For each finding, Claude either applies the fix directly or provides the corrected code.
- Direct fix — If MCP write access is available and the fix is safe (e.g., replacing
wait()withtask.wait()), Claude applies it and notes the change. - Code suggestion — For architectural changes (consolidating Heartbeat connections, implementing object pooling), Claude provides refactored code with explanation.
- Manual step — For Studio-only fixes (anchoring parts, reducing mesh complexity), Claude gives clear instructions for the user.
For a deeper look at the specific Luau optimization techniques behind these fixes — including object pooling patterns, caching strategies, and efficient data structures — see Performance Optimization.