So if you read the code, you can tell that it saves when the value has been changed.

I noticed that it was a mistake to use it like that, the system was overloading with save requests.

I've tried making a PlayerRemoving function and it did work, I probably formatted it wrong.

local players = game:GetService("Players")
local datastore = game:GetService("DataStoreService")
local ds1 = datastore:GetDataStore("AirValueSaver")
local ds2 = datastore:GetDataStore("CoinsValueSaver")
local ds3 = datastore:GetDataStore("StorageValueSaver")

players.PlayerAdded:connect(function(player)
	local folder = Instance.new("Folder")
	folder.Name = "leaderstats"
	folder.Parent = player
	
	local folder2 = Instance.new("Folder")
	folder2.Name = "Go_info"
	folder2.Parent = player
	
	local currency1 = Instance.new("IntValue")
	currency1.Name = "Air"
	currency1.Parent = player.leaderstats
	currency1.Value = ds1:GetAsync(player.UserId) or 0
	ds1:SetAsync(player.UserId, currency1.Value)
	
	local currency2 = Instance.new("IntValue")
	currency2.Name = "Coins"
	currency2.Parent = player.leaderstats
	currency2.Value = ds2:GetAsync(player.UserId) or 0
	ds2:SetAsync(player.UserId, currency2.Value)
	
	local info_currency1 = Instance.new("IntValue")
	info_currency1.Name = "StorageLevel"
	info_currency1.Parent = player.Go_info
	info_currency1.Value = ds3:GetAsync(player.UserId) or 0
	ds2:SetAsync(player.UserId, info_currency1.Value)
	
	currency1.Changed:connect(function()
		ds1:SetAsync(player.UserId, currency1.Value)
	end)
	currency2.Changed:connect(function()
		ds2:SetAsync(player.UserId, currency2.Value)
	end)
	info_currency1.Changed:connect(function()
		ds3:SetAsync(player.UserId, info_currency1.Value)
	end)	
end)