The error is caused by running out of local registers. You cannot have more than 200 local variables in a single scope. Note the module wasn’t designed to be forked or modified. You can certainly still do it but you will need to understand the backend and performance benefits (which is what the module was designed for) will not be guaranteed.
I noticed arrays and dictionaries can only have 65,535 elements before they cant be parsed anymore, how would I be able to bypass this limit?
Could I just split up the array into being fired multiple times and then piece those together? Asking because I can hit the limit of elements very fast with multidimensional arrays.
This library looks very promising. It would be interesting to see benchmarks on CFrames as I believe it is probably one of, if not, the most expensive one over regular remote events
You are correct, that is the limit. Your suggestion is the simplest solution. You could also change the limit by modifying the source code but you would have to use more than 2 bytes to store the length. I could send you a version with this modification if you are interested
Thanks! Unfortunately it’s very difficult to optimize performance on CFrames due to limitations of CFrame methods like :ToEulerAnglesXYZ and CFrame.Angles, etc. The problem is we are forced to use CFrame methods (the aforementioned is the fastest way to serialize CFrames as far as I know) which are much slower than buffer operations, so these costs are dominating. That said, QuickNet should be around 1.5x faster than RemoteEvents for CFrames and still have the same benefits as other types for bandwidth saving.
Modifying the actual source code to include the length feels a little hacky…
Plus I’d have to keep asking you for a modified version each update.
How would you suggest I’d detect if it goes over the buffer limit and send/receive it fragmented?
Hey, I’d like to bring up what Illinois_Roadbuff mentioned earlier in the thread (since you hadn’t given a response yet and I believe you might’ve perhaps missed it). Similar to his case, I was testing QuickNet on a baseplate before adopting it to my game. Requiring it on client took 38.3Mb of memory. Blink, in comparison only took around 0.01Mb.
Module Script “Shared” in ReplicatedStorage
local QuickNet = require(script.Parent.QuickNet)
local data = QuickNet.Data
return {
Event1 = QuickNet:register("Inventory",
{
{
id = data.NumberU16,
qty = data.NumberU32,
enchant = data.optional(
{
level = data.NumberU8,
id = data.NumberU8
}
),
category = data.String,
favorited = data.optional(data.Boolean)
}
}
)
}
Server Script “QuickNetTest” in ServerScriptService
local ReplicatedStorage = game:GetService("ReplicatedStorage")
print(gcinfo(), "Before! Server")
local QuickNetModule = require(ReplicatedStorage.QuickNet.Shared)
print(gcinfo(), "After! Server")
task.wait(3)
--while task.wait() do
QuickNetModule.Event1:FireAllClients(
{
{category = "SharkMeat", id = 123, favorited = true, qty = 324},
{category = "Sword", id = 123, favorited = true, qty = 3, enchant = {level = 255, id = 12}},
{category = "Sword", id = 13, favorited = true, qty = 2, enchant = {level = 25, id = 12}},
{category = "Sword", id = 1323, favorited = true, qty = 5, enchant = {level = 5, id = 12}},
{category = "Sword", id = 1243, favorited = true, qty = 4, enchant = {level = 235, id = 12}},
{category = "Sword", id = 123, favorited = true, qty = 3, enchant = {level = 255, id = 12}},
{category = "Sword", id = 123, favorited = true, qty = 3, enchant = {level = 255, id = 12}},
{category = "Sword", id = 123, favorited = true, qty = 3, enchant = {level = 255, id = 12}},
{category = "Sword", id = 123, favorited = true, qty = 3, enchant = {level = 255, id = 12}},
{category = "Sword", id = 123, favorited = true, qty = 3, enchant = {level = 255, id = 12}},
{category = "Sword", id = 123, favorited = true, qty = 3, enchant = {level = 255, id = 12}},
{category = "Sword", id = 123, favorited = true, qty = 3, enchant = {level = 255, id = 12}}
}
)
--end
Local Script “QuickNetTest” in StarterPlayerScripts
local ReplicatedStorage = game:GetService("ReplicatedStorage")
print(gcinfo(), "Before! Client")
local QuickNetModule = require(ReplicatedStorage:WaitForChild("QuickNet"):WaitForChild("Shared"))
print(gcinfo(), "After! Client")
QuickNetModule.Event1.OnClientEvent:Connect(function(data)
end)
Output (gcinfo to verify)
16:23:42.656 111 Before! Server - Server - QuickNetTest:2
16:23:42.706 475 After! Server - Server - QuickNetTest:4
16:23:43.114 198 Before! Client - Client - QuickNetTest:2
16:23:43.322 39616 After! Client - Client - QuickNetTest:4
Image of console showing QuickNet using unusual amounts of memory:
QuickNetTestPlace.rbxl (105.4 KB)
The test baseplate I used
not sure if its intended, but your module is silently swallowing up errors
if you do something like:
quicknetRemotefunction:InvokeServer()
error("error")
quicknetRemotefunction:InvokeServer()
workspace.objectThatDoesntExist.Parent = game.ReplicatedStorage
you won’t get an error message
I would also like to add that the buffer category itself takes up 40 MB in the client:
Additionally, I looked at the source code and I believe it has to do with the variable CLIENT_TEMP_BUFF_SIZE:
getClientQueue() is called twice, so therefore it creates two TempBuffer’s which take up 40 MB in total.

I think you just have to adjust it (as the comment says) if you do not want it taking too much client memory. I tested it again with a CLIENT_TEMP_BUFF_SIZE of 10 MB and the module only took 19.2 MB of client memory.
pretty sure quicknet has other variables that are meant to be adjusted, usually theres a comment right beside them
Well, that’s good to know that this wasn’t a bug. It would’ve be nice if the documentation explained these configs in the Quickstart section.
Thanks for pointing out what I missed!
This is normal behavior. In the interest of performance QuickNet pre-allocates memory (buffers and tables) to reduce dynamic allocations. Other modules like Blink allocate memory in-flight, so their memory usage does not show up until there is some workload. The memory usage you see should not be a concern. In my testing QuickNet typically uses much less memory than normal RemoteEvents and close to the same as others like Blink when under load.
Note by default QuickNet allocates way more memory than it ever realistically needs to ensure the benchmarks run correctly. In an actual game you will probably never fire millions of data every frame, so you can safely reduce the allocation by 10x or more without any issues. You can adjust this in some variables at the top of the main file.
Thank you for pointing this out. I’ve found the cause and I’m looking into a clean solution. Will release a patch soon.
v0.3.3: Fixed error swallowing in the invoke thread for response events
Apologies for the delay, I patched this a week ago but forgot to update the post
Nice module, I ended up modifying my copy to use xpcall for more detailed errors. Attaching a traceback to it makes debugging way easier since it preserves the script line numbers
God bless you and your family may you live in happiness forever thank you so much you amazing beautiful individual
I cannot with words describe how much I did not want to make a system like this myself and not even a week later I see this, try it out, and it is such a good experience.
Donation? Can I?
-
setEnumItems → addEnumItems: Instead of requiring a single call that provides every EnumItem used, EnumItems can now be attached individually in multiple different scripts on startup. This change improves usage in workflows where network definitions are localized to individual systems or services. That said, the old usage pattern still works.
-
Reworked logic for Once and Wait methods: more reliable behavior, more reused code and less logic in listener paths on both server and client.
Can you publish this to wally?



