getgc
Retrieves all objects currently tracked by the Luau garbage collector.
function getgc(includeTables?: boolean): {function | userdata | table}Synopsis
How it works
The executor iterates the Luau garbage collectorGarbage collectorLuau uses an incremental tri-color mark-and-sweep GC. Objects are white (unreached), gray (reached, children not scanned), or black (fully scanned). The GC runs incrementally across frames to avoid pauses.'s internal linked listLinked listA data structure where each element (node) contains a pointer to the next element. The Luau GC uses a linked list (global_State->allgc) to track all allocated objects for mark-and-sweep collection. of tracked objects (
GCObject chain). Every live Luau object — closures, userdataUserdataA Luau type for C-allocated memory blocks. Roblox Instances, Vector3s, CFrames, and other engine types are userdata with metatables providing their API. Cannot be created from Luau directly., and optionally tables — is collected into a returned array. This provides a snapshot of the entire managed heap.VM internals
Luau's GC maintains a
global_State struct with a linked listLinked listA data structure where each element (node) contains a pointer to the next element. The Luau GC uses a linked list (global_State->allgc) to track all allocated objects for mark-and-sweep collection. head pointer allgc. Every heap-allocated object (GCObject) is linked through its next field:
typedef struct GCObject {
GCObject* next; // linked list pointer
uint8_t tt; // type tag (LUA_TFUNCTION, LUA_TTABLE, ...)
uint8_t marked; // GC tri-color mark bits
uint8_t memcat; // memory category for profiling
} GCObject;
getgc() walks global_State->allgc, checking each object's tt field:LUA_TFUNCTION(6) — both LClosureLClosureA Luau closure — a function compiled from Lua/Luau source code. Contains a pointer to its Proto (bytecode prototype) and an array of UpVal pointers for captured variables. and CClosureCClosureA C closure — a function implemented in native C/C++ code (lua_CFunction). Contains a C function pointer and an array of TValue upvalues. Roblox built-in functions like print are C closures.LUA_TUSERDATA(7) — includes Roblox InstanceInstanceThe base class for all Roblox objects (Parts, Models, Scripts, GUIs, etc.). Instances form a tree hierarchy (the DataModel). In Luau, they appear as userdata with shared metatables. wrappersLUA_TTABLE(5) — only whenincludeTablesis true
Performance
A typical Roblox game has 50,000–200,000+ GC objects. With
includeTables=true, the returned array can be enormous because tables vastly outnumber other types. The allocation itself can trigger a GC cycle. Best practice: call once, filter immediately by type() or upvalueUpvalueA variable captured from an enclosing scope. When a function references a local variable from an outer function, that variable becomes an upvalue — stored in an UpVal struct that persists even after the outer function returns. inspection, discard the array, and never call in a loop tighter than once per second.Usage
Find all live functions
local gc = getgc(false)
for _, obj in ipairs(gc) do
if type(obj) == "function" then
print(debug.info(obj, "sln"))
end
endFind a hidden table
local gc = getgc(true)
for _, obj in ipairs(gc) do
if type(obj) == "table" and obj.secretKey then
print("Found hidden table:", obj.secretKey)
end
endParameters
includeTables boolean? optionalWhen true, tables are included in the returned array in addition to functions and userdata.
Returns
{any} An array of all live objects currently tracked by the garbage collector.
Performance Note
Enumerating the GC with tables enabled can be expensive. Avoid calling this frequently in loops.