Codectionary / Developer documentation / Luau

task scheduling and RunService

Use task scheduling for delayed or deferred work, and RunService when a feature genuinely depends on simulation or rendering steps. A delay is a minimum scheduling interval rather than an exact clock. Avoid doing work every frame when an event can report the change.

Syntax

task.delay(1, function()
    print("Ready after a scheduling delay")
end)

Examples

Run a finite reminder sequence

Script in ServerScriptService. Each reminder yields before the next one, and the loop ends after three. Actual elapsed time can exceed the requested one-second wait.

task.spawn(function()
    for remaining = 3, 1, -1 do
        print(remaining)
        task.wait(1)
    end
    print("Ready")
end)

Use delta time and disconnect

LocalScript in StarterPlayerScripts. This creates a local cosmetic marker and rotates it for three seconds. Multiplying by dt makes the intended angular speed independent of frame count.

local RunService = game:GetService("RunService")
local marker = Instance.new("Part")
marker.Anchored = true
marker.CanCollide = false
marker.Position = Vector3.new(0, 5, 0)
marker.Parent = workspace
local elapsed = 0
local connection: RBXScriptConnection?
connection = RunService.Heartbeat:Connect(function(dt)
    elapsed += dt
    marker.CFrame *= CFrame.Angles(0, math.rad(90) * dt, 0)
    if elapsed >= 3 then
        if connection then connection:Disconnect() end
        marker:Destroy()
    end
end)

Best practices

  • Do not use a busy loop without yielding; it can stall script execution.
  • Cancel delayed work or check its owner before accessing an object that may have been destroyed.
  • Use property/event signals for discrete changes, not a Heartbeat poll of every object.

At a glance

Purpose
Typed scripting and Roblox development
File extension
.luau
Runs in
Luau host; Roblox engine examples require Roblox Studio
Usually used with
Roblox APIs and Studio

Specifications & further reading

Related Luau documentation