roblox-performance
Performance diagnosis and optimization - MicroProfiler, Script Profiler, Developer Console, Scene Analysis, Luau heap and memory categories, memory leaks, network/replication cost, rendering and physics cost, streaming, native codegen, Parallel Luau with Actors. Use when a game lags, stutters, drops FPS, crashes on mobile, has high ping, or before optimizing hot code.
How do I install this agent skill?
npx skills add https://github.com/el4cteo/roblox-skills --skill roblox-performanceIs this agent skill safe to install?
- Gen Agent Trust Hubpass
This skill provides technical documentation and Luau code examples for optimizing Roblox game performance. It covers the use of built-in engine tools such as the MicroProfiler, Script Profiler, and Parallel Luau without any security risks.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
What does this agent skill do?
Roblox performance
Measure before optimizing. Identify whether the bottleneck is server compute, client compute (CPU/GPU), memory, network, or load time, then use the matching tool.
Tools
| Tool | Open | Use for |
|---|---|---|
| Developer Console | F9 (in game) | Errors, server/client memory by category, network, script activity. Works in live servers. |
| MicroProfiler | Ctrl+Alt+F6 (⌘⌥F6); Dev Console for server | Per-frame timing; spikes; dump a frame for detail. |
| Script Profiler | Studio / Dev Console | Which functions consume Luau time (sampling). |
| Luau heap snapshots | Dev Console → Memory → Luau Heap | What tables/closures/instances are held and by what (leaks). |
| Scene Analysis | Studio | Script memory, unparented instances (leaks), instance composition, audio/animation memory, triangles. Also SceneAnalysisService via Studio MCP. |
| Performance Stats / Debug Stats | Ctrl+Alt+F7 / Shift+Ctrl+F1–F5 | Live CPU/GPU/memory/network overlays. |
| Network Simulation | Studio (Alt+S) | Test with latency, jitter, packet loss. |
| Performance dashboard | Creator Hub | Live aggregate FPS, server heartbeat, memory, crash rates by device. |
Label your own code in the MicroProfiler and memory views:
--!strict
local RunService = game:GetService("RunService")
debug.setmemorycategory("EnemyAI") -- memory allocated by this thread is attributed to "EnemyAI"
RunService.Heartbeat:Connect(function(_deltaTime)
debug.profilebegin("EnemyAI.think") -- shows as a labeled bar in the MicroProfiler
-- ... work ...
debug.profileend()
end)
Targets
- Client: 60 FPS on mid-range phones (≈16.6 ms/frame); many players are on low-end Android.
- Server: heartbeat near 60 Hz;
Stats(workspace:GetRealPhysicsFPS(), Dev Console Server Stats). - Memory: mobile clients crash from OOM first. Keep client memory well under ~1–1.5 GB on low-end
devices; watch
PlaceMemory,LuaHeap,GraphicsTexture,Sounds,Animationcategories.
Most common problems → fixes
| Symptom | Usual cause | Fix |
|---|---|---|
| Memory grows over time | Leaked connections, tables keyed by players/instances, destroyed-but-referenced instances, unparented instances | Disconnect/clean up per player & per character; clear tables on PlayerRemoving; use Scene Analysis "unparented instances" and heap snapshots. |
| Server lag with many players | Per-player loops each frame, while true do task.wait() end loops, heavy remote handlers, physics of many unanchored parts | Event-driven code, one scheduler loop, throttled think rates, anchor static parts, server-own fewer assemblies. |
| Client FPS drops | Too many parts/draw calls, shadows from many lights, transparency/particles overdraw, per-frame UI updates | Merge/instance meshes, CastShadow = false on small parts, fewer shadowed lights, limit particles, update UI on change only. |
| Spikes every N seconds | Autosave/GC bursts, synchronized loops across players, big Clone()s | Stagger with random offsets; pool objects; spread work across frames. |
| High ping / rubber banding | Remote spam, large payloads, replicating many property changes | Batch, delta-compress, throttle; tween on clients; see roblox-networking. |
| Long join times | Huge place, many unique assets, no streaming | Streaming, SLIM LOD, fewer unique meshes/textures, ContentProvider:PreloadAsync only for critical assets. |
Luau hot paths
- Cache services, instances, and
RaycastParamsoutside loops; avoidFindFirstChild/GetDescendantsper frame. ReplaceGetDescendantsscans with tags (CollectionService) or maintained sets. - Use
deltaTimefromHeartbeat/PreSimulationrather thantask.wait()loops for per-frame work. - Avoid creating closures/tables per frame in hot loops; reuse buffers with
table.clear. --!native(whole script) or@native(per function) for math-heavy code; typed parameters help the native compiler. Don't blanket-enable: compile time and a global native-code memory limit.--!optimize 2is how Roblox compiles live games already; don't rely on Studio timings for micro-benchmarks.
Rendering and assets
- Parts: fewer, larger parts;
MeshParts with sharedMeshIdare instanced (cheap); unions (PartOperation) can be expensive — check triangle counts in Scene Analysis. RenderFidelity = Automatic/Performancefor detailed meshes;CollisionFidelity = Box/Hullfor decorative meshes;CanCollide/CanQuery/CanTouch = falsefor pure decoration.- Lights: limit shadow-casting
PointLight/SpotLight/SurfaceLight; limitParticleEmitter.Rateand particle size (overdraw);Beam/Trailcounts. - Textures/images: reuse, keep resolutions reasonable (1024² max for most);
SurfaceAppearancesparingly. - Enable streaming (
roblox-architecture),Model.LevelOfDetail = SLIMfor static models, and letStreamOutBehavior = Opportunisticfree memory.
Physics
- Anchor everything that doesn't need to move. Welded decorative parts on moving assemblies add cost.
- Fewer, simpler collisions (
CollisionFidelity, collision groups to skip pairs);CanTouch = falsewhereTouchedisn't needed. - Avoid setting
CFrameof unanchored parts every frame; use constraints or anchor + CFrame. workspace:BulkMoveTo(parts, cframes, Enum.BulkMoveMode.FireCFrameChanged)to move many anchored parts.- Adaptive timestepping (
PhysicsSteppingMethod = Adaptive) reduces physics CPU.
Parallel Luau
Scripts under different Actor instances can run in parallel:
--!strict
-- Script parented under an Actor (one Actor per logical unit, e.g. per NPC group or chunk).
local RunService = game:GetService("RunService")
local results: { number } = {}
RunService.Heartbeat:ConnectParallel(function(_deltaTime)
-- Parallel phase: read-only access to most instances, pure computation, thread-safe APIs (raycasts).
for i = 1, 100 do
results[i] = math.noise(i / 10, os.clock())
end
task.synchronize()
-- Serial phase: write to instances, fire events, call thread-unsafe APIs.
end)
task.desynchronize()/task.synchronize()switch phases;ConnectParallelstarts in parallel.- Scripts in the same Actor run serially relative to each other: split work across many Actors.
- Can't
requireor modify most instances while desynchronized. Communicate withActor:SendMessage/BindToMessageParallelorSharedTable(SharedTableRegistry). - Good fits: raycast validation, procedural generation, pathfinding-adjacent math, large simulations. Bad fits: tiny tasks (sync overhead), instance-heavy work.
Profiling walkthrough and memory-leak hunting: references/profiling.md.
Related skills
roblox-architecture (streaming), roblox-networking (bandwidth), roblox-physics, roblox-npc-ai,
roblox-studio-mcp (Roblox's rbx-perf-profiling/scene analysis via MCP).
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/el4cteo/roblox-skills/roblox-performance">View roblox-performance on skillZs</a>