Plugin localhost HttpService Limit Affected By Run Mode

Per the HttpService documentation, there is a limit of 500 requests per minute. However, this limit is actually 2,000 per minute for localhost. I made a small plugin to stream data from Studio while running knowing this, however this limit is actually 0 for the plugin running on the client instance and 500 on the server instance.

The script below can be used to figure out the limits of the HttpService in the given context:

local HttpService = game:GetService("HttpService")
local RunService = game:GetService("RunService")

local SuccessfulRequests = 0

xpcall(function()
	while true do
		HttpService:RequestAsync({
			Url = "http://localhost:8000",
		})
		SuccessfulRequests += 1
	end
end, function(ErrorMessage: string)
	warn(`Http request failed: {ErrorMessage}`)
end)

print(`Completed requests: {SuccessfulRequests}`)
print(`IsStudio: {RunService:IsStudio()}`)
print(`IsServer: {RunService:IsServer()}`)
print(`IsClient: {RunService:IsClient()}`)
print(`IsRunMode: {RunService:IsRunMode()}`)
print(`IsRunning: {RunService:IsRunning()}`)

This is configured to access a localhost server on port 8000. For Windows systems with Python 3, this can easily be done using python -m http.server in a terminal. Once the port is set, save it as a lua file to the Studio plugin folder, then open up a template or local file. This was tested with local files, not Team Create.

When run from a plugin not in run mode, you get the following expected output:

Http request failed: Number of requests exceeded limit
Completed requests: 2000
IsStudio: true
IsServer: true
IsClient: true
IsRunMode: false
IsRunning: false

From the server plugin, you get only 500 (not 2,000).

Http request failed: Number of requests exceeded limit
Completed requests: 500
IsStudio: true
IsServer: true
IsClient: false
IsRunMode: true
IsRunning: true

And from the client plugin, you get 0.

Http request failed: Http requests can only be executed by game server
Completed requests: 0
IsStudio: true
IsServer: false
IsClient: true
IsRunMode: false
IsRunning: true

Expected behavior

localhost has historically had a higher limit for use with request-heavy local plugins with local server components. I made a special (currently unreleased) plugin that was expecting to be able to stream motion data at about 30hz (1800 requests per minute), but the limit of 500 requests only gets me about 8hz. While looking into this more, I also realized that the server version is the only one that can stream this data, which I was expecting from the client version. I expected the limit to be the same across all contexts, but there are actually 3 different limits.

Thanks for the report! We will look into it

2 Likes