As seen in the gif above, the RequestCount for GamePassService is rapidly increasing on a live server. I’ve checked all the scripts in my game using the “Find All” feature in studio, and I don’t use GamePassService at all. I thought that it was MarketPlaceServuse:UserOwnsGamePassAsync() that was causing this and sure enough, I realised I was calling that function every frame multiplied by 4-10 players (oops). However, I just want to make sure that this is the issue? Shouldn’t MarketPlaceService’s RequestCount be increasing? Regardless, I’ve fixed this now but I’d like some confirmation on whether UserOwnsGamePassAsync is really what’s causing this. I searched around and couldn’t find anything, so I apologise if it this has been asked before.
It likely is the cause if you aren’t seeing the increasing number like you were before. UserOwnsGamePassAsync will send a GET request to the GamePassService. So it would make sense. You definitely don’t want to be hitting any services with each frame. HTTP requests from game servers are limited by bandwidth, and hitting this service as much as you were will definitely be an issue later if you need to make requests to other Roblox Services. Plus it’s good practice not to hit a service more than necessary.
It seems like this issue is still happening despite me implementing a fix (a cache thing) to prevent spam of the use of UserOwnsGamePassAsync. Does anyone know what else could be causing GamePassService to use GET requests? From the gif sent in the post, the average time also seems to be 2610000ms which is around 7 hours, which makes sense because servers around 7 hours old start to randomly break. I’m at a loss on what to do, I thought I’ve fixed this.
Can you post some code? We can probably diagnose it.
UserOwnsGamePassAsync is internally a web call, which is why it uses GET requests. I don’t think this incrementing counter is anything to be worrying about, but it’s worth asking: in what cases are you calling UserOwnsGamePassAsync?
You definitely don’t want to be using UserOwnsGamePassAsync every frame, or even every second. There’s no need to.
Do it once when they join for your gamepasses(or better yet save it to data when they originally buy it). That’s it.
Just keep track in the server using PromptGamePassPurchaseFinished. You could use a table to see if the player owns it.
Sample code
local Marketplace = game:GetService("MarketPlaceService")
local playerGamepasses = {}
local gamepasses = {
[253423] = "x2Coins",
[3456456] = "x2EXP",
}
game.Players.PlayerAdded:connect(function(player)
playerGamepasses[player] = {}
for id,name in pairs (gamepasses) do
if Marketplace:UserOwnsGamePassAsync(player.UserId,id) then
playerGamepasses[player][id] = true
print(player..Name, "owns gamepass",name)
end
end
end)
function addCoins(player,amount)
local ownsx2 = playerGamepasses[player][253423]
player.leaderstats.Coins.Value = player.leaderstats.Coins.Value + (ownsx2 and amount*2 or amount)
end
function gamepassPurchaseFinished(player,gamepassid,waspurchased)
if player and gamepassid and waspurchased then
if playerGamepasses[player] == nil then playerGamepasses[player] = {} end
playerGamepasses[player][gamepassid] = true
print(player.Name, "bought", gamepasses[gamepassid])
end
end
Marketplace .PromptGamePassPurchaseFinished:Connect(gamepassPurchaseFinished)
I’m worried about it because whenever the GET requests finally come through after 7 hours, it increases memory use of HttpCache and LuaHeap which causes 1 script to stop working (and that script is where UserOwnsGamepassAsync is called), which renders the game unplayable. Take a look at the memory usage for LuaHeap and HttpCache:
Edit: To answer your question, I use UserOwnsGamepassAsync whenever the player uses a business for the first time (it used to be called every time a player uses a business, but I fixed that which is the fix I was mentioning in my previous comment), or when they hire a manager (isn’t as frequent as using businesses), or when they buy an upgrade (again, not as frequent as using businesses). Whenever a business is used, a remote event is fired with the name of the business. This remote event can be fired every frame multiplied by the amount of players in the game. I know I should be fixing this, but this issue of memory piling up 6 hours after a server starts only started occurring after an update I made to the game. I’ll be posting some code later.
Yup, exactly the fix I implemented which I mentioned in my previous comment, yet it is still occurring. I’ll post some code when I’m able to.
Ohh, I see. I’ve never experienced this or have never consciously seen this while working with game passes, so that’s a curious question. The memory usage is also fairly concerning. Hope this isn’t happening elsewhere either.
Huge quote chunk, but I’m not sure what this means by “uses a business”. I’m sure it’s already been established and it should go without saying though that is not the greatest idea. Firing every frame was definitely a hard hitter but this is as well.
In terms of the cache fixed you attempted, what exactly did you do for that? What’s the flow of your caching system? You won’t need any code to explain that much, hopefully.
In the game, you can buy businesses and place them on slots on your plot. Once bought, you can click on these businesses and after a certain amount of time, you gain money and you can click the business again to earn more money.
Business usage is handled through a remote event, where the business’s name is fired to the server. When the server receives the remote event, the level of the business and the boosts from the player is then used to calculate the amount of cash to give to the player, which is done by changing a value object under the player’s Player instance. One of the boosts that is taken into account is a gamepass that doubles profit. This is where UserOwnsGamePassAsync is used.
There is another feature called “Managers”, which automatically uses the business it is specific to automatically. When a business called “Lemon stand” is upgraded to over level 300, the cooldown is 0s, and when the Lemon stand manager is active, the use business remote event is fired every .Heartbeat:Wait(). I know this should be reworked, but this is the last update I’m going to be working on for this game and I’ll be working on other things.
Now you can see why I was using UserOwnsGamePassAsync every frame. Once I realised that, I fixed it by adding a cache system. It’s quite simple. When a player’s gamepass ownership is first checked, UserOwnsGamePassAsync is called and it is stored in a table. Thereafter, any further checks for ownership would return the value stored in the table. When a player buys a gamepass, their cache is updated. When the player leaves, their cache is removed from the table. I thoroughly tested this and made sure that it’s working perfectly fine, but the issue is still happening. I’ll be taking another look at the scripts to make sure I didn’t miss anything, and to find possible fixes.
I was typing up something but I deleted it after realising how pointless and unhelpful it was. I honestly can’t discern a problem and I’ve never seen something like this before.
On the other hand, I dug up a bit on LuaHeap and HttpCache. LuaHeap seems to be general Lua memory allocations and it’s related to the garbage collector. This having a large value most likely equates to your code having a memory leak. May want to skim over your code. HttpCache is self explanatory and I’m willing to bank that on the caching behaviour of UserOwnsGamePassAsync.
If none of this means anything, then I’m going back to the sidelines. I don’t have any other guesses as to what’s causing this.
This is actually what I thought the issue was at first. Broken servers started popping up 2-3 days ago and I saw that LuaHeap was rapidly increasing in them. Ever since then, I’ve been trying to find ways to optimise my code. I’ve optimised it to the fullest extent and it was still happening. I then realised that that might not be the issue, so I went and took a look at other stats in the dev console, and saw that it was GamePassService causing the issue.
I’ve looked over my code and looked for every situation a gamepass is involved, nothing suspicious. I also tested the cache system again, and it works perfectly fine.
This never happened until I updated the game, so I checked the differences between the old game and new game using a text difference checker. The only new things I added that involves gamepasses has nothing to do with useBusiness and gamepass ownership isn’t checked frequently. The only possible reason I can think of is BadgeService, I award badges when necessary but I don’t check if the player owns them. Though BadgeService has its own label in the Networks tab, along with the fact that BadgeService isn’t used in the script which breaks when HttpCache and LuaHeap increases significantly.
I don’t know what to do