agentleFS
luumenlabsluumenlabs/luau-skills/skills/luau/luau-performance/SKILL.md

luau-performance

Skill12 starsChanged 8 months agoMITView on GitHub

Use for Luau performance work focused on profiling hotspots, allocation-aware code structure, table and iteration costs, builtin and function-call fast paths, compiler/runtime optimization behavior, and environment constraints that change execution speed.

The file

Show its rules and text

We split this skill into the rules it gives an agent

31 rules. About 0 are common, 21 are distinctive, and 10 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈21

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 10

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill when the task is primarily about Luau runtime cost:

    line 10
  2. Distinctive:

    Do not use this skill when the task is mainly about:

    line 20
  3. Distinctive:

    Start with measurement. If the code is non-trivial, profile or benchmark before making optimization claims.

    line 28
  4. Very specific:

    Keep performance-sensitive modules in a pure environment.

    line 31
  5. Distinctive:

    Prefer stable table shapes, direct field access, direct builtin calls, and simple call graphs in hot code.

    line 32
  6. Distinctive:

    Use environment-specific compilation features only after measurement shows a likely win and the runtime actually supports them.

    line 33
  7. Very specific:

    If the task shifts into core language teaching, use luau-core.

    line 34
  8. Very specific:

    If the task shifts into types, inference, or annotations as the main subject, use luau-types.

    line 35
  9. Very specific:

    If the task depends on Roblox engine architecture instead of Luau execution behavior, hand off to the appropriate roblox/* skill.

    line 36
  10. Distinctive:

    If a request mixes performance work with out-of-scope topics, answer only the Luau runtime portion and exclude the rest.

    line 37
  11. Distinctive:

    avoid rebuilding tables every iteration,

    line 49
  12. Distinctive:

    avoid creating fresh closures in loops unless necessary,

    line 50
  13. Distinctive:

    avoid retaining tables or connections longer than needed.

    line 51
  14. Distinctive:

    use literals to create object-like tables with all known fields up front,

    line 53
  15. Distinctive:

    keep object layouts uniform across calls,

    line 54
  16. Very specific:

    use table.create only for array-like tables with known capacity.

    line 55
  17. Very specific:

    use generalized iteration for k, v in t do for normal table traversal,

    line 57
  18. Very specific:

    use ipairs only when stop-at-first-nil behavior is required,

    line 58
  19. Distinctive:

    use numeric loops when the index itself is needed or sequential writes are part of the algorithm.

    line 59
  20. Distinctive:

    Keep builtin fast paths obvious:

    line 60
  21. Very specific:

    call builtins directly, such as math.max(x, y) or string.byte(s, 1),

    line 61
  22. Distinctive:

    do not hide hot builtin calls behind unnecessary indirection,

    line 62
  23. Distinctive:

    prefer builtin function form over method form when fastcall behavior depends on it.

    line 63
  24. Distinctive:

    Keep call sites compiler-friendly:

    line 64
  25. Very specific:

    prefer local function for hot helpers,

    line 65
  26. Distinctive:

    avoid unnecessary mutation of captured values,

    line 66
  27. Distinctive:

    keep small helpers local to the module when that improves inlining opportunities.

    line 67
  28. Distinctive:

    Keep metatable usage cheap in hot code:

    line 68
  29. Very specific:

    avoid __index functions and deep lookup chains on critical paths.

    line 71
  30. Distinctive:

    Treat environment features as performance constraints:

    line 72
  31. Distinctive:

    Do not open other skill references unless the task clearly crosses into another skill's scope.

    line 85

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

luau-performance

When to Use

Use this skill when the task is primarily about Luau runtime cost:

  • Profiling code to find real hotspots before changing implementation details.
  • Reducing allocation churn, GC pressure, or closure creation in repeated paths.
  • Choosing faster table construction, lookup, append, and iteration patterns.
  • Making code cooperate with Luau fast paths for builtin calls, method calls, and imports.
  • Explaining how compiler and runtime optimizations affect hot functions.
  • Tuning a confirmed hot path while balancing readability and maintainability.
  • Accounting for sandbox or environment behavior only when it changes Luau execution or deoptimizes code.

Do not use this skill when the task is mainly about:

  • Teaching general Luau syntax, control flow, tables, or metatables from first principles.
  • Designing deep type-system abstractions, analyzer behavior, or advanced type utilities.
  • Roblox-specific replication, streaming, rendering, networking, physics, or other engine performance patterns.

Decision Rules

  • Start with measurement. If the code is non-trivial, profile or benchmark before making optimization claims.
  • Fix algorithmic cost before micro-optimizing bytecode-level details.
  • Prioritize changes that remove repeated work, repeated allocation, or repeated dynamic dispatch in hot paths.
  • Keep performance-sensitive modules in a pure environment. Avoid getfenv, setfenv, and loadstring where speed matters.
  • Prefer stable table shapes, direct field access, direct builtin calls, and simple call graphs in hot code.
  • Use environment-specific compilation features only after measurement shows a likely win and the runtime actually supports them.
  • If the task shifts into core language teaching, use luau-core.
  • If the task shifts into types, inference, or annotations as the main subject, use luau-types.
  • If the task depends on Roblox engine architecture instead of Luau execution behavior, hand off to the appropriate roblox/* skill.
  • If a request mixes performance work with out-of-scope topics, answer only the Luau runtime portion and exclude the rest.

Instructions

  1. Define the workload first:
    • what runs often,
    • what allocates often,
    • what is on the critical path,
    • what metric matters most: wall time, frame budget, or memory churn.
  2. Profile before rewriting. Use sampling or environment tooling to identify functions that actually dominate runtime.
  3. Optimize the largest validated bottleneck first. Do not spread micro-optimizations across cold code.
  4. Reduce allocation pressure in repeated paths:
    • avoid rebuilding tables every iteration,
    • avoid creating fresh closures in loops unless necessary,
    • avoid retaining tables or connections longer than needed.
  5. Shape tables for the runtime:
    • use literals to create object-like tables with all known fields up front,
    • keep object layouts uniform across calls,
    • use table.create only for array-like tables with known capacity.
  6. Choose iteration deliberately:
    • use generalized iteration for k, v in t do for normal table traversal,
    • use ipairs only when stop-at-first-nil behavior is required,
    • use numeric loops when the index itself is needed or sequential writes are part of the algorithm.
  7. Keep builtin fast paths obvious:
    • call builtins directly, such as math.max(x, y) or string.byte(s, 1),
    • do not hide hot builtin calls behind unnecessary indirection,
    • prefer builtin function form over method form when fastcall behavior depends on it.
  8. Keep call sites compiler-friendly:
    • prefer local function for hot helpers,
    • avoid unnecessary mutation of captured values,
    • keep small helpers local to the module when that improves inlining opportunities.
  9. Keep metatable usage cheap in hot code:
    • store data on the object itself,
    • point __index directly at a table,
    • avoid __index functions and deep lookup chains on critical paths.
  10. Treat environment features as performance constraints:
  • getfenv, setfenv, and loadstring can deoptimize imports and fast builtin handling,
  • debugging and breakpoints can alter observed runtime behavior in some environments,
  • native compilation, where supported, should be applied selectively and measured.
  1. Preserve practicality. Prefer the simplest change that removes measurable cost, even if a more aggressive rewrite is theoretically faster.

Using References

  • Open references/luau-performance-guide.md for the main Luau fast-path model: table access, imports, method calls, iteration, and allocation-aware table construction.
  • Open references/profiling-guide.md for profiler workflow, interpreting flame graphs, naming functions for attribution, and environment-specific profiling notes.
  • Open references/runtime-and-compiler-optimization-notes.md for compiler limits, inlining, constant folding, upvalues, closure caching, and selective native compilation guidance.
  • Open references/library-performance-sensitive-patterns.md for practical choices around math, string, table, iteration helpers, and array-oriented APIs.
  • Open references/sandbox-constraints-relevant-to-runtime-behavior.md for the environment rules that disable or weaken runtime optimizations.
  • Do not open other skill references unless the task clearly crosses into another skill's scope.

Checklist

  • A measurement plan or profiler result exists for the claimed hotspot.
  • The proposed change targets a path that runs often enough to matter.
  • Algorithmic cost has been considered before micro-tuning syntax.
  • Allocation churn is reduced where the code repeats.
  • Table shape and iteration strategy match the data pattern.
  • Builtin calls stay direct enough to preserve fast paths where possible.
  • Environment deoptimizers such as getfenv, setfenv, or loadstring are avoided in hot modules.
  • Any environment-specific compilation feature is justified by measurement, not guesswork.
  • The guidance stays within Luau execution behavior and avoids Roblox engine performance topics.

Common Mistakes

  • Optimizing unmeasured code because it "looks hot."
  • Using table.create for dictionaries instead of arrays.
  • Assuming pairs or ipairs are automatically faster than generalized iteration.
  • Rewriting obj:Method() into cached method locals even when Luau already optimizes method calls well.
  • Hiding builtin calls behind wrappers or indirect dispatch on a hot path.
  • Varying object table keys heavily and then expecting field lookup caching to stay effective.
  • Using getfenv only for reads and assuming it has no optimization cost.
  • Sprinkling native compilation directives everywhere without measuring memory, startup, or actual runtime wins.

Examples

Preallocate and fill arrays sequentially

local function buildSquares(count)
    local result = table.create(count)

    for i = 1, count do
        result[i] = i * i
    end

    return result
end

Keep builtins direct in hot code

local function clamp01(x)
    return math.min(math.max(x, 0), 1)
end

Use stable object layouts and direct __index

local Counter = {}
Counter.__index = Counter

function Counter.new(step)
    return setmetatable({
        value = 0,
        step = step,
    }, Counter)
end

function Counter:advance()
    self.value += self.step
    return self.value
end

Avoid deoptimizing the environment in performance-sensitive modules

local function magnitude2(x, y)
    return math.sqrt(x * x + y * y)
end

return magnitude2

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.