Skip to main content

Fluix

Every object ready before demand arrives.

Fluix

Adaptive, demand-smoothed object pooling for Roblox.

Documentation · Creator Store

Version: V1.0.0

Fluix is a per-instance generic object pool for Roblox Luau. It tracks acquisition demand with an exponential moving average, pre-warms and gradually shrinks the pool to match real usage, and exposes hot/cold priority tiers, cross-pool borrowing, per-object TTL, and lifecycle signals — all with zero allocations on the acquire/release hot path.


Install

Get Fluix from the Roblox Creator Store, drop the module into ReplicatedStorage, and require it:

local Fluix = require(ReplicatedStorage.Fluix)

No external dependencies. One require.


Quick Start

local Fluix = require(ReplicatedStorage.Fluix)

local BulletPool = Fluix.new({
    Factory = function() return Bullet.new() end,
    Reset   = function(b) b:Reset() end,
    MinSize = 32,
})

-- Pre-allocate 20 objects before gameplay starts
BulletPool:Seed(20)

-- Acquire with an optional inline initialiser
local bullet = BulletPool:Acquire(function(b)
    b.Position = spawnPos
    b.Velocity = direction * speed
end)

-- Return when done
BulletPool:Release(bullet)

Configuration

FieldTypeDefaultDescription
Factory() -> TrequiredAllocates a fresh object
Reset(T) -> ()requiredClears an object before re-pooling
MinSizenumber8Floor the cold pool never shrinks below
MaxSizenumber256Hard cold-pool ceiling
Alphanumber0.3EMA smoothing coefficient (0–1)
Headroomnumber2.0Pool target multiplier over smoothed demand
SampleWindownumber0.5Demand measurement interval in seconds
PrewarmBatchSizenumber16Max allocations per Heartbeat tick
ShrinkGraceSecondsnumber3.0Surplus duration before eviction begins
IdleDisconnectWindowsnumber6Consecutive idle windows before dormancy
HotPoolSizenumber0Dedicated hot sub-pool capacity (0 = off)
TTLnumbernilMax seconds an object may be live (nil = off)
MissRateThresholdnumbernilMiss rate 0–1 that triggers a warn() (nil = off)
OnOverflow(T) -> ()nilCalled when the pool is full on Release
BorrowPeers{ Pooler }{}Sibling pools to borrow from on a miss

Signals

Each pool instance exposes a Signals table of VeSignal connections:

SignalFires withDescription
OnAcquireobj: TObject left the pool
OnReleaseobj: TObject returned to the pool
OnMissobj: TFactory fallback used (pool was empty)
OnGrowadded, totalPool expanded
OnShrinkremoved, totalPool contracted
BulletPool.Signals.OnMiss:Connect(function(obj)
    warn("Pool miss — consider raising MinSize or Headroom")
end)

API

Lifecycle

MethodDescription
Fluix.new(config)Create a new pool
pool:Seed(n)Pre-allocate n objects
pool:Acquire(initFn?)Get an object, with optional inline init
pool:Release(obj)Return an object
pool:ReleaseAll()Force-return every live object
pool:Pause()Disconnect Heartbeat without destroying state
pool:Resume()Reconnect Heartbeat
pool:Drain()Evict all pooled objects (does not touch live)
pool:Destroy()Destroy the pool

Peers

MethodDescription
pool:RegisterPeer(other)Add a sibling pool to borrow from
pool:UnregisterPeer(other)Remove a sibling pool

Inspection (zero-allocation)

MethodDescription
pool:GetLiveCount()Objects currently out
pool:GetPoolSize()Objects in the cold pool
pool:GetHotSize()Objects in the hot sub-pool
pool:GetTotalAvailable()Hot + cold (acquirable right now)
pool:GetDemandEMA()Smoothed acquisitions-per-window
pool:GetTargetSize()EMA-derived pre-warm target
pool:GetMissCount()Lifetime total pool misses
pool:IsActive()true if Heartbeat is live
pool:IsDestroyed()true if Destroy() has been called
pool:IsOwned(obj)true if obj is currently live in this pool
pool:GetStats()Table of all stats

Benchmarks

Measured on Roblox server, 60 sample frames, 20 warmup frames. Throughput = acquire+release pairs per second. Round-trip latency = µs per acquire→release cycle.

ProfilePeak ops/sRT µsMiss%
Hot(16) + cold2,485,8000.400.0%
Cold-pool only2,268,6030.440.0%
Cross-pool borrow1,927,6740.0%
Miss-only (factory)707,2141.41100.0%

ReleaseAll per-object cost: ~0.37–0.49 µs/obj across ×100 to ×20,000 objects.

Heartbeat overhead: < 0.001 ms (within noise floor).


License

MIT — Copyright © 2026 VeDevelopment