My game suffers from lag spikes, how do I optimize it?

Hello, everyone!

I am an amateur builder and I’m currently working on a map for a Roblox game.
The map is nice and I like it but for some reason, despite the fact that my PC is good enough to bear its high amount of parts, I get crippling lag spikes that won’t allow me to make my way to the end of the parkour.
They happen about once every 3 seconds and they are so severe that my fps drop down to 20 or even 10 (from up to 300!), which is a great issue for me.

Now, I’ve heard from a friend of mine that my game is not well optimized but I don’t know how to optimize it, could someone help me by telling me how to fix the lag?

Here’s the link to the game in case you want to check it out:
https://www.roblox.com/games/4651934577/Darkness-Among-Us

I’d really appreciate it if you could help me, thank you for reading and have a nice day!

7 Likes

What is the part count? Because if that’s too high that’s probably the problem.

As of now, the map contains 8543 parts.

1 Like

I can almost guarantee that’s the reason then, do you know any ways you could cut down on parts?

Yeah, I could just remove some decorations but how many would I need to get rid of?

Idk, I don’t do building that often, I just know that 8000+ is a lot
EDIT: (I WAS VERY WRONG!!!)

1 Like

Thanks for your help I’ll try to remove as many as I can :pray:

try turning on StreamingEnabled in workspace properties

nope, same lag spikes unfortunately

I’m on mobile unfortunately so I can’t give particular advice on your map, but I’ll throw out some building optimization tips that helped our game.

We have maps that spans upwards of 30,000 - 60,000 parts that doesn’t lag the game that much, even on mobile and without streaming enabled.


  1. Make sure you anchor everything that doesn’t rely on player interaction. Physics and collision is the biggest performance hogger.
  2. If using Future or ShadowMap, each part has a property called “CastShadow”. Turn this off if this part doesn’t really need shadows. Shadow calculations are heavy on the user’s device.
  3. If there are scripts in the game, turning off CanTouch for parts that doesn’t need to be interacted with game code helps.
  4. Do you have meshparts or unions? Turn their render fidelity to performance or automatic. If you have complicated mesh geometry as well, its also wise to change their collision fidelity to box or hull if colliding with them wont be as important for gameplay.
  5. Make sure light sources in your game doesn’t all have shadows turned on. Again, big performance hog. Only enable shadows to the ones that really needs it.
  6. Use the same size parts/meshes with similar properties and copy paste to kingdom come. No seriously, Roblox caches the information of similar part properties and caches it to memory. If you have 6000 of the same sized part or mesh with like the same material, properties, etc, Roblox only needs to download 1 of the same part/mesh since all of them are the same size, saving you a looooot on memory usage. Rotation and positioning these copies are ok, as long as don’t change its size, the memory usage will remain optimized.
  7. Lastly, if you’ve done all above and still experiencing lag, a good tool to diagnose why and when your lagging is the microprofiler tool. I believe the hotkey is ctrl+f6 when you are testing but you may need to look it up. I won’t go into much details on what this tool does but I recommend searching the devhub or devforum about it; it solved pretty much 80% of our lag problems once you know what to look for. Its a little advanced and complicated but its a powerful tool.

UPDATED March 11, 2023
Seems like this post is still getting the occasional likes so I’m going to throw out some additional tips that are now available to us:

  1. For things that don’t need to be physically interacted with (maybe small, insignificant items or faraway objects that players will never touch), you can turn Anchored on, CanCollide off, CanTouch off, & CanQuery off. This will make that part have extra optimization by having no engine-specific logic attached to it.
  2. If your game is built for it, use StreamingEnabled. It’s pretty alright nowadays (our games personally use them) and it has much more customization than the last time I made this post. Not only will it make your game load a lot faster, but users with lower memory devices will benefit greatly from this. Just make sure your scripts are built for this mode.
30 Likes

Just tried it out - do you have any code running in this place? It feels like the performance issues are due to some line of code looping too often more than anything. The lag spikes are happening about every 3 seconds without camera or player movement. Nothing in your Memory Usage > Place Memory suggests it’s anything to do with part counts or anything visual. Check for any loops in your code that happen too often. For a proof, remove all code temporarily and see that performance returns to expected amounts :slight_smile:


This is false. 8543 Parts is absolutely a miniscule amount. You can even see this in Place Memory; it barely hit over 100mb total. This is not the issue, please correct or remove your post as it causes confusion. For clarification, read that @TeamSwordphin has had maps with 30-60 thousand objects without issue. I can echo that with my own past experiences as well.

Unioning Parts just to have less Parts is VERY BAD for performance!!! Please do not suggest this, as it causes a lot of game breaking problems and can absolutely ruin a map. Please edit or remove your post so nobody treats it as advice.

9 Likes

Thank you so much, I’ll try to follow as many tips as i can!!! :heart:

Yes, there are lots of scripts! Thank you for your advice! :smiley: :+1:

Lag spikes occur due to many reasons.

If you lag spikes are server lag (characters not moving/stuck in place without FPS loss, high memory usage but no FPS drops) , check your script memory for high MB-using scripts. This tends to be the case 99.9% of the time.

If your lag spikes are client lag (FPS drops, desyncing), check your script memory for high MB using scripts (client memory not server memory) and try and figure out what sections of your map could be possibly causing the FPS drops.

2 Likes

Something similar is happening to me too, and you say your part count is 8k+, also similar to mine.

Seems like its a weird bug, for me also drops form a stable 60+ FPS to like 10 and i dont know why because it just started happened randomly lol.

In case you dont have same bug as me, just follow the optimization tips people already provided you.

2 Likes

Swordphin you seem very knowledgeable, what type of things can take down server memory? My game increases after a while.

You should create a new topic to not de-rail this one, but what you are experiencing is called memory leaks. A very rudimentary example is making a forever, non-ending loop of creating something but you aren’t destroying it once you are done.

For example,

while task.wait() do
     local part = Instance.new("Part")
     part.Parent = workspace
end

--- These parts are useless, we aren't going to use it, and they are just piling up over time

Lingering connection lines also contribute to memory leaks (albeit more negligible), such as not disconnecting previous events before making a new one.

Example:

local touchPart = workspace.Part --- Define our part to touch
local player = game.Players.LocalPlayer

--- This makes a new touched listener every time the player respawns, creating a memory leak as long as the part still exists
player.CharacterAdded:Connect(function()
     touchPart.Touched:Connect(function() 
          print("I touched this part!")
     end)
end)

Another well-known memory leak is not cleaning up tables. For example, you are keeping track of player scores using the player’s name as the key but not removing it when they leave.

local scores = {}

game.Players.PlayerAdded:Connect(function(player)
     scores[player.Name] = 0
end)

--- Every time a player joins, a new key is made and created.
--- However, we aren't removing that key once the player leaves
--- Causing a memory leak due to unused memory

In conclusion, delete what you don’t need. Disconnect what you no longer need. Clean and clear tables from information you no longer need.

Thanks alot, pretty much all I needed but will tables not get garbage collected?

They get garbage collected like any other variables as long as there isn’t a hard reference to them.

Example:

do
     local table = {"hi", "apples"}
     print(table)
end

--- Table will be cleaned up since its no longer referenced and out of the scope

You’d want any tables you are using to be manually cleaned by removing any keys or references you no longer need in them, or letting the lua GC do it automatically by making sure nothing references that table anymore.

2 Likes