How to prevent dataloss

Hello guys , i have a game with around 2-4k player active and im facing with one problem that is some people loss their vehicle i wonder why and how to prevent it ? here’s my script .

local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("PlayerData")

local debounceTable = {}  

local function onPlayerJoin(player) 
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "OwnedCars"
	leaderstats.Parent = player


	local cars = {
		"HondeEX5",
		"HondeWave100",
		"Kasaki 150sp",
		"Lagenda115zr",
		"Lajak",
		"Rzx Milinium",
		"Wave125i Drag",
		"Light Lz",
		"Yamha Soleriz",
		"Yamha 125rz",
		"Sniper150Drag",
		"Yamha Sniper135 v1",
		"Honde Deo",
		"Honde Nsr500",
		"Icikiwir",
		"Yamha Yzr500",
		"Honde Wave 125r",
		"Kasaki Pdk R1",
		"Dukatti SuperSport S",
		"Kasaki Serpico",
		"Yamha X1r",
		"Vesp 150ss",
		"Dukatti 1299",
		"Yamha Sniper v2",
		"Suzuka Raider 150",
		"Kasaki Ninja H2",
		"Yamha R6 v2"
		
		
	}

	for _, car in ipairs(cars) do
		local carValue = Instance.new("BoolValue")
		carValue.Name = car
		carValue.Parent = leaderstats
	end

	local playerUserId = "Player_" .. player.UserId
	local data = playerData:GetAsync(playerUserId)

	if data then
		for _, car in ipairs(cars) do
			leaderstats[car].Value = data[car] or false
		end
		print("DataLoaded")
	else
		print("New user or new motorcycle")
	end
end

local function createTable(player)
	local playerStats = {}
	for _, stat in pairs(player.OwnedCars:GetChildren()) do
		playerStats[stat.Name] = stat.Value
	end
	return playerStats
end

local function onPlayerExit(player)  
	debounceTable[player.UserId] = debounceTable[player.UserId] or false
	if debounceTable[player.UserId] then
		return
	end
	debounceTable[player.UserId] = true

	local playerStats = createTable(player)
	local success, err = pcall(function()
		local playerUserId = "Player_" .. player.UserId
		playerData:SetAsync(playerUserId, playerStats) 
		print("DataSaved")
	end)

	if not success then
		warn(err)
	end

	wait(15)
	debounceTable[player.UserId] = false
end

game:BindToClose(function()
	for _, player in ipairs(game.Players:GetPlayers()) do
		onPlayerExit(player)
	end
end)

game.Players.PlayerAdded:Connect(onPlayerJoin)
game.Players.PlayerRemoving:Connect(onPlayerExit)

I would like to note that if the DataStoreService errors for whatever reason while attempting to retrieve the data, you are not catching it. If your data does not load, you are then still saving data that hasn’t loaded. This means that the player is losing all of their data.

When loading data, you could use a system that retries if it fails. If the system does not load any of their data, you could add the player to a dictionary that notes that. During saving, you can check that dictionary to see if their data had been loaded. If it was loaded, then save. If not, don’t save anything.

local playerData =  game:GetService("DataStoreService"):GetDataStore("PlayerData")

local function AddCar(ownedCars,model)
	local value = Instance.new("BoolValue",ownedCars)
	value.Name = model
	value.Value = true
end
local function RemoveCar(ownedCars,model)
	local car = ownedCars:FindFirstChild(model)
	if car then car:Destroy() end
end
local function onPlayerJoin(player) 
	local data = playerData:GetAsync(player.UserId) or {[0]="Yamha 125rz"}
	local ownedCars = Instance.new("Folder",player)
	ownedCars.Name = "OwnedCars"
	for _,v in pairs(data) do
		AddCar(ownedCars,v)
	end
	ownedCars.Parent = player
end

local function onPlayerLeave(player)
	local cars = {}
	for _,v in pairs(player.OwnedCars:GetChildren()) do
		table.insert(cars,v.Name)
	end
	playerData:SetAsync(player.UserId,cars)
end

game:BindToClose(function()
	for _, player in ipairs(game.Players:GetPlayers()) do
		onPlayerLeave(player)
	end
end)

game.Players.PlayerAdded:Connect(onPlayerJoin)
game.Players.PlayerRemoving:Connect(onPlayerLeave)

Can you explain it with more detail?

Alright i will try , gotta make sure