This article is out of date!
You can find the new version of this article here, which is a bit more future proof and is more accurate to how Roblox currently works. It also addresses some incorrect or inaccurate information from this article
Hello developers! I feel like I havenāt really been seeing much content related to remotes, network throttling, etc, and Iāve both encountered, and seen a lot of issues with remote data taking place across multiple games. I thought that Iād share what I know from my own experimentation and what I have seen. I apologize if some information is not fully accurate. Please correct me if Iāve gotten something wrong, and if you have some information you think should be added, definitely say so!
Remote Data Transfer
Remotes transfer their data at a rate of 30 times per second (30 tps). They can transfer at 50kbps per player (~1706 bytes per transfer). This is the soft limit of data transfer across remotes, and hitting this limit will cause data to be queued. If this queue backs up, it can artificially inflate what I call āperceived ping.ā Perceived ping is essentially how responsive your remotes appear. If you have too much data queuing up, actions appear to happen slower and slower, eventually taking seconds or more.
Preventing Remote Queuing
Preventing data queuing is a super important topic for all games. Iāve seen many games which run into data queuing issues which appears like server lag even though the server is running at 60hbps. Preventing this is thankfully pretty simple: Just donāt send too much data.
Firstly you want to make sure you arenāt making too many remote requests. You can technically make more than 30 requests per second and still be fine since data can be batched into one network frame. Whatās important is that youāre sending under the 1706 byte limit in one network frame. Unfortunately there are no tools available to measure how much data youāre transferring across your remotes, so itās important that you gauge things accurately enough that you can stay under this limit.
Gauging Remote Data Size & Staying Under the Limit
Usually itās not important to try and find the size of data accurately. We can use a few simple rules to help us stay under the limit:
- Do not make too many requests. You should limit frequent requests, or requests which occur per frame to use very small amounts of data, such as a few numbers or small strings.
- Only send large tables once. After youāve sent your table, you can sync values as they are changed within the table. For example, if the player has a list of items they own, you should only send this table once at the start of the game, and then tell the client to add or remove certain entries.
- Create item/object registries. You should give certain objects and items unique identifiers or names which the client can use to identify them. You can send these items in one big list, or keep them in shared modules between the client and server.
- Do not send a lot of stuff at once unless the player has just joined. Try to spread out lots of information over a few seconds if you nee to.
Extra (estimating actual data size)
For those that want to gauge data size as accurately as you can while being safe we can make some loose assumptions of how Roblox transfers data types. We can expect that numbers are transmitted as 64 bit floats (8 bytes) and we can expect strings to be sent as a list of bytes. We can assume that tables and arrays use the format commonly seen in other areas of Roblox: 4 bytes for the length of the array, then 1 + keyLength + valueSize
bytes for entries. For arrays, this will be zero. Weāll want to give some extra leeway for other information that might be included, so we can give each value as well as the overall request a few extra bytes (e.g. 2).
Replication Lag
Replication lag, similar to remotes, causes a ton of either FPS lag, or latency. This frequently occurs in games which build lots of terrain at once, such as Eclipsis, which to this day struggles with replication lag. Replication lag can be caused by mass ancestry or property changes, mass deletion or creation of instances, and other stuff as well.
Mitigating Replication Lag
Donāt Initialize Properties After Parenting
This means donāt use the second argument of Instance.new
, and donāt set a lot of properties after youāve parented instances. This argument is actually deprecated for this very reason. Setting a lot of properties on a replicable instance can cause a ton of replication lag since each property change is individually replicated.
Instances which are parented to nil, Cameras, ServerStorage, ServerScriptService, and other locations which do not replicate to the client also do not send property and ancestry changes to the client. This is important because it prevents the client from being overloaded with too many property changes before youāre done creating your objects.
Group Your Instances
When creating, or even deleting objects, such as terrain, buildings, etc, you should group up a lot of objects into instances before parenting. Parenting a lot of objects at once can cause a lot of replication lag just like mentioned above. Generally itās important that you balance the number of groups youāre parenting with the amount of instances within them.
Yielding (e.g. waiting for RunService.Heartbeat) between groups is an extremely effective way of preventing crashing and freezing when replicating a ton of instances. Sending too many groups, or too large groups will freeze the client, or cause high latency. Grouping instances effectively prevents the player from experiencing any extremely low FPS (which effectively slows down the rate at which replication data is processed, thus causing even more lag in the process) as well as preventing high latency from too much data being transferred at once.