Match history DataStore using imitated "Foreign Keys"

I want to make a Match History system that shows some basic information and is stored under a certain id that is also saved in a users personal data. So data would look something like this:
This would be the theoretical data after a User with UserId 500 1v1’s a User with the UserId of 1125 two times in a row with different results.

local userId = 500
UserMatchHistory[userId] = {"AEDOJGYGQI", "A6LP5GMHN4"} --User has played two matches
	
MatchHistory = {
	["AEDOJGYGQI"] = {
		Scores = {
			Alpha = 2000,
			Bravo = 6000
		},
		
		PlayerData = {
			[500] = {
				Kills = 25,
				Deaths = 12,
				Team = "Alpha"
			}
			
			[1125] = {
				Kills = 12,
				Deaths = 25,
				Team = "Bravo"
			}
		}
	},
	
	["A6LP5GMHN4"] = {
		Scores = {
			Alpha = 2000,
			Bravo = 6000
		},
		
		PlayerData = {
			[500] = {
				Kills = 12,
				Deaths = 25,
				Team = "Alpha"
			}
			
			[1125] = {
				Kills = 25,
				Deaths = 12,
				Team = "Bravo"
			}
		}
	}
}

Will I run out of data making this a waste of time?

I don’t think so, this is a very cool system I encourage you to do it seems like a great feature, and data-wise, from what I know, roblox doesn’t limit how much data you can use. I mean even the way you did it seems organised.
The only limitations in concern of datastore are how many times you can use the :SetAsync(), and how much data you can send per :SetAsync(). Since all keys and scopes and all get saved as strings, it counts how much data saved in the length of the strings, the exact numbers and more info in this wiki page.

Maybe just a little suggestion, work on this feature after the first release of your game, so after the beta and all that; and that is if you don’t have time but if it’s easy go on

My concern is more along with the “Maximum number of characters”. One of those match history nodes will be generated after the end of each game with approximately 24 players data.

What I recommend doing, is trying this out, and see if it spits out an error. If so, it should give you an error code, you can see the list of all error codes and see what’s wrong than you can tell if it’s too much data or another problem

Make use of DataStore scopes. You’re going to hog a lot of DataStores for this though. Assuming you’re using a typical DataStore style of a DataStore which calls GetAsync using a UserId as a key to fetch a table of rounds, just get a DataStore that passes the match ID as the scope.

You may want to partition your data for something like “match history past month” rather than all time, since you would undoubtedly run into maximum characters. Gauging how often your players play is something you’ll need to consider.

You could alternatively just make your own server, which the only bottleneck would be the 500 requests per minute rate limit for HttpService and if your Roblox game server can successfully send a request to your web server. Your Roblox game server would send a request directly to your server, so all of the management lies on you.