0Pricing
Lua Academy · Lesson

Writing JIT-Friendly Lua

Avoid JIT bailouts: keep types stable, minimize table resizing, use locals.

Writing JIT-Friendly Lua is a free Lua Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Lua Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Why JIT-Friendliness Matters

The JIT compiler works best on type-stable, predictable code. Unpredictable types and branching cause trace aborts and bailouts, reverting to the interpreter.

Keep Types Stable

A variable should always hold the same type. If a variable alternates between number and string, the JIT cannot specialize and must insert type checks everywhere.

-- BAD: type unstable
local x = 1
if cond then x = "one" end  -- JIT cannot specialize x

-- GOOD: separate variables
local xNum = 1
local xStr = "one"

Use Local Variables

Local variables are stored on the Lua stack (register-allocated by JIT). Global and upvalue access is slower. Cache globals as locals at the top of hot functions.

local sin = math.sin  -- cache as local
for i = 1, 1e6 do
  result = sin(i)  -- fast local access
end

Avoid Table Resizing in Loops

Pre-allocate tables to their expected size. Growing a table in a loop (crossing the next power-of-2 boundary) reallocates and copies the array, breaking JIT traces.

local t = table.new(1000, 0)  -- LuaJIT extension
for i = 1, 1000 do t[i] = i end

Avoid Mixed Array/Hash

Keep array parts as arrays (integer keys from 1). Mixing integer and string keys in the same table prevents array optimizations.

Avoid Closures in Hot Inner Loops

Creating a new closure on each iteration allocates memory and can cause GC pressure. Pre-allocate closures outside the loop.

-- BAD: closure created every iteration
for i = 1, 1e6 do
  local fn = function() return i end  -- allocation!
end

-- GOOD: use a local function outside
local function work(i) return i end
for i = 1, 1e6 do work(i) end

Avoid Polymorphic Calls

Calling different function objects through the same call site (different functions each iteration) creates a polymorphic call site the JIT cannot inline.

Avoid NYI (Not Yet Implemented) Features

Some Lua features are not implemented in LuaJIT's JIT (NYI): string.format with some specifiers, pcall inside JIT traces, pairs/next. Check jit.v output.

jit.v for Trace Verbosity

Enable verbose JIT output to see which traces are compiled and which abort.

-- Run script with: luajit -jv script.lua
-- Or in code:
jit.attach(function(event, ...)
  if event == "abort" then print("ABORT:", ...) end
end, "all")

Use Fixed-Size Arrays

When an array has a known fixed size, declaring it as a constant-size C array via FFI can be dramatically faster than a Lua table.

Profile Before Optimizing

Measure first. Premature optimization is the root of all evil. Profile to find the actual hot path before spending time on JIT-friendly rewrites.

JIT-Friendly Question

Why should you avoid creating closures inside hot inner loops?

Recap: JIT-Friendly Lua

Keep types stable, use locals, pre-allocate tables, avoid closures in hot loops, and check for NYI features with jit.v. Profile first — optimize only proven bottlenecks.

Frequently asked questions

Is the “Writing JIT-Friendly Lua” lesson free?

Yes — the full text of “Writing JIT-Friendly Lua” is free to read here on the web, and the Lua Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Lua Academy course, upgrade to CoddyKit PRO.

What will I learn in “Writing JIT-Friendly Lua”?

Avoid JIT bailouts: keep types stable, minimize table resizing, use locals. You practise Lua Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Lua Academy?

No prior experience is required. Lua Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Writing JIT-Friendly Lua” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Lua Academy lesson?

Yes. Every Lua Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. LuaJIT Architecture Overview
  2. Writing JIT-Friendly Lua
  3. Profiling with jit.p and perf
  4. Benchmarking Patterns
← Back to Lua Academy