Massive Lag spikes with 30+ people in game

Hello, I am currently trying to figure out why my game is having massive lag spikes when their are about 30+ people in the game, It’s been about 2ish days and I still haven’t found the reason.

I conducted multiple tests, one in the main game, one in the basic no map game and another game that is similar with no issues with 80 players.

Clip 1 (main game): https://www.youtube.com/watch?v=1hCYMPuFTZw&ab_channel=iTzEmail
Clip 2 (no map): https://www.youtube.com/watch?v=2IMyhTCliY4&ab_channel=iTzEmail
Clip 3 (similar game with 80 players): https://www.youtube.com/watch?v=iZRHnYbdRq0&ab_channel=iTzEmail

The 2 clips with our game had about 40 players each nearing the end, you can easily tell when the lag starts.

We also noticed that when a bunch of players join at the same time, a massive lag spike happens. I looked into MicroProfiler and noticed this when the player joins (not sure if it means anything or not)


Any help will be very appreciated!

2 Likes

Hard to tell from just the info given, but the most likely cause of this is that the server starts to lag out because you got players probably running server scripts and what happens is that each player that joins then makes a duplicate of that server script they are running which puts more load on the server, if you can think of any script with maybe loops inside the startercharacter that is a server script or maybe when the player joins you have a loop start running on the server or anything not just a loop really. If you want to make a performant game with lots of players take the load off of the server and start working on transferring code that is run by the player into client scripts (local scripts) instead of server scripts. This include, remote events.

2 Likes

Use script usage profiler from f9 console menu.

1 Like

Everything is pretty much client sided unless it’s supposed to be on the server such as data, etc. Pretty much when each player joins, there is a PlayerManager module in ServerScriptService which creates a new player module for each player, this holds things such as requesting teams, assigning overhead tags, etc. As far as I’m aware, there aren’t any loops within those 2 scripts, so I really have no clue.

1 Like

Watch the first 2 clips and you’ll see me using them. You clearly only looked at the 2 microprofiler images I gave and not the videos.

1 Like

I didn’t watch the videos no.
Does it show high percentage for some (server) scripts?

1 Like

When I was tracking them, I didn’t really see anything out of the blew but I’m also not an expert on it so I’m not sure if anything was bad or not, which is also why I provided the clips.

1 Like

This is the playeradded function in PlayerManager if you woud look to see it

function PlayerManager:PlayerAdded(player : Player)
	if self.clients[player] then
		return self.clients[player]
	end
	
	if not player then
		repeat task.wait(.1) until player
	end

	local loaded = Instance.new("BoolValue", player)
	loaded.Name = "_LOADED"
	
	self.clients[player] = playerModule.new(player)
	
	local client = self.clients[player]
	if not client then
		player:Kick("Could not get client. Please rejoin")
		return
	end
	
	task.wait(1)

	--/ Datastore check
	local dataStore = DataService:Retrieve(player)
	if not dataStore then
		local maxAttempts, attempts = 5, 0
		for i = attempts, maxAttempts do
			if dataStore then
				break
			end
			task.wait(5)
			dataStore = DataService:Retrieve(player)
			attempts += 1
		end
		if not dataStore then
			local str = string.format("Could not retrieve %s data within %s attempts", player.Name, attempts)
			warn(str.." | Player Manager")
			player:Kick(str)
			return
		end
	end
	
	--/ Connections
	player.CharacterAdded:Connect(function(character)
		srv.run.PostSimulation:Wait()
		
		Collision.Set(character)
		
		local team = player.Team and player.Team.Name
		local isMenu = team and team == "Menu"
		if isMenu then
			task.spawn(function()
				local hrp = character:WaitForChild("HumanoidRootPart", 4)
				if not hrp then
					return
				end
				hrp.Anchored = true
			end)
		end
		
		local humanoid = character:WaitForChild("Humanoid")
		humanoid.Died:Connect(function()
			task.wait(4.5)
			if character and character:IsDescendantOf(workspace) then
				character:Remove()
			end
		end)
		
		task.spawn(function()
			self:UpdateSpawnLocation(player)
			
			--/ Give players their teams tools
			client:AssignLoadout()
		end)
		
		client:AssignTag()
	end)
	
	player.CharacterAppearanceLoaded:Connect(function(char)
		for _,child : BasePart? in char:GetChildren() do
			if child:IsA("CharacterMesh") then
				child:Destroy()
			elseif child:IsA("Accessory") then
				local Handle: BasePart? = child:FindFirstChild("Handle") :: BasePart
				if Handle then
					Handle.CanQuery = false
				end
			end
		end
	end)
	
	--/ Robux Spent
	client.robuxSpent = dataStore.RobuxSpent
	
	--/ Setup leaderstats
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player

	local kills = Instance.new("IntValue")
	kills.Name = "KOs"
	kills.Parent = leaderstats

	local money = Instance.new("IntValue")
	money.Name = "Cash"
	money.Parent = leaderstats
	money.Value	= dataStore.Cash
	
	self.PlayerLoaded:Fire(player, dataStore, client)
	self.Client.PlayerLoaded:Fire(player)
	
	loaded.Value = true
end
1 Like

I see than it can be either some sort of memory leak or the player data is too much for the server.

example of a memory leak would be not disconnecting things like connections or not cleaning up after players leaves if the players had anything associated to them.

you can look up more examples of memory leaks if needed, a lot of times it goes unnoticed and can cause a pile up. Which common after either a lot of people are in the game and the longer the server is up.

Can also be network receive (replication) lag.

This van also be checked from the f9 menu.

Roblox automatically disconnects all player connections when the player leaves. I also try to disconnect any connections for the player.

1 Like

Adding on to this, I did see at one point in the scripts profiler a unknown script usage activity of 43% to 86%

Consistently spiking up/down

1 Like

This is also pretty sure shown in the 2 clips, I would very much recommend scanning through them because you’re just telling me stuff I am already aware of.

In the second clip, you can see when a bunch of people join in, a bunch of Total Data KB/s get spammed.

1 Like

Yes I also saw that, but I have no idea what scripts those are. I know roblox just displays random scripts it can’t display as Unknown. Any idea what they could be?

1 Like

Honestly, it could be from some sort of free model or “backdoor” from a plugin, this includes plugins for everyone work on the game. (I would absolutely not go full terminator mode) this is just a worst case scenario. It could also be that maybe your map has some unanchored parts, its also know that having a lot of humanoids together causes lag.
image

I’ll send you a link of a guide that goes over most performance impacting practices.

In our game, we pretty much have a bunch of free model vehicles but as far as I am aware they’re fine as they were in our previous game which ran fine with 60 people. I do not believe it’s the map as in the clip with no map, it also has unknown spiking a ton.

1 Like

Yeah, no clue if your other games were working fine with the same assets thats a real head scratcher. The first topic explains what unknown could be, so good luck, sorry I couldn’t be of more help :sob:

2 Likes

Don’t worry, like I said any help is appreciated, atleast you’ve been responding, usually on some of my posts just nobody responds.

Gaps in graph indicate too much data is being sent and some has to be dropped.
Possible causes of high replication bandwidth are server-sided part position, attribute, property etc. updates.

Make sure to check your scripts for constant (every frame) updates to properties. Those are automatically replicated to every client by the engine.

I think I found what it was, it was a module I was using for the weapons called SecureCast, I think it was just too much for every client. I did a 30 player test like 10 minutes ago and it went pretty well, no lag at all. Later I’ll try and get a test with 50

2 Likes