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

Hi there,

Just wanted to clarify the limits here.
Clients are not able to make Http requests, as the error message shows. The HttpService documentation explicitly states “HttpService allows HTTP requests to be sent from game servers.”

For the 500 vs 2000 limit depending on run mode, 500 is publicly documented as the universal limit. We raised the limit to 2000 for Studio because we found that it was safe to do and was valuable for developers, but it’s more of an added bonus. We will continue to reevaluate request limits and see if we can increase capacity here.

Not sure if you’ve seen it yet but the new WebStreamClient may be of use for you in plugin development- another comment shares how they were able to tackle a similar use case.

1 Like

The bug is more-or-less that this 2,000 limit disappears in favor of 500 when in run mode (as in, a plugin gets 2,000 when not in run mode, but only 500 when in run mode). However, streaming data like you linked is exactly what I wanted in the first place and mitigates the need to resolve this. I am not sure how I missed the announcement, but thanks for linking it - I will be migrating to it within a week.

1 Like