3 min read

Source: Roblox Creator Hub · CC BY 4.0 · View source · Code samples: MIT Imported 2026-10-03. Formatting adapted for this site.

Transparent batching

Some APIs are capable of transparent batching, meaning the engine can automatically combine multiple concurrent API calls into fewer HTTP requests behind the scenes.

You don't need to use a different API or supply different arguments. Simply start multiple calls concurrently instead of waiting for each one to finish before starting the next.

Why use transparent batching

Many Roblox APIs communicate with backend services over HTTP and are subject to rate limits. Making many requests in a short period of time can increase latency and may cause some requests to be throttled or fail.

Transparent batching reduces the number of HTTP requests sent by the engine. Instead of sending a separate HTTP request for every API call, the engine groups nearby concurrent calls into fewer network requests automatically. This improves performance for your players and reduces the likelihood of hitting rate limits.

For example, if your code performs 20 product lookups at the same time, transparent batching can combine those calls into just one or two HTTP requests instead of sending 20 separate requests.

Use concurrent calls

Transparent batching only works when multiple calls to the same supported API are started concurrently. If each call waits for the previous one to finish, the engine sends a separate HTTP request for each call instead of batching them together.

Instead of starting calls one at a time:

-- Serial: slow, one HTTP request at a time
local MarketplaceService = game:GetService("MarketplaceService")

for _, productId in productIds do
    local info = MarketplaceService:GetProductInfoAsync(productId, Enum.InfoType.Product)
    print(info.Name)
end

Start them concurrently:

-- Concurrent: the engine combines these into fewer HTTP requests
local MarketplaceService = game:GetService("MarketplaceService")

local results = {}
local remaining = #productIds

local function fetch(productId)
    local success, info = pcall(function()
        return MarketplaceService:GetProductInfoAsync(productId, Enum.InfoType.Product)
    end)

    if success then
        results[productId] = info
    else
        warn("Failed:", productId, info)
    end

    remaining -= 1
end

for _, productId in productIds do
    task.spawn(fetch, productId)
end

while remaining > 0 do
    task.wait()
end

Both examples produce the same results, but the concurrent version allows the engine to automatically batch multiple API calls into fewer HTTP requests, making the operation faster and reducing the likelihood of hitting rate limits.

Supported methods

The following methods currently support transparent batching:

Service Method
Class.MarketplaceService Class.MarketplaceService:GetProductInfoAsync()|GetProductInfoAsync (Enum.InfoType.Product, Enum.InfoType.GamePass, and Enum.InfoType.Bundle)
Class.MarketplaceService Class.MarketplaceService:UserOwnsGamePassAsync()|UserOwnsGamePassAsync
Class.AvatarEditorService Class.AvatarEditorService:GetItemDetailsAsync()|GetItemDetailsAsync
Class.AssetService Class.AssetService:GetBundleDetailsAsync()|GetBundleDetailsAsync

Best practices