Title Logo



With the patch today, we now have 4 ranked playlists to choose from (3 permanent and one rotating). To celebrate the occasion, I'm pleased to announce the addition of public ESR and CSR leaderboards to the site.


The leaderboards will track any CSR or ESR that is seen by Halo Query in a match played in the last 7 days. That includes players beyond the ones that were explicitly being searched for — anyone who was involved in the match will get their skill levels added to the leaderboard. That means when you load up your profile page and your 200 most recent matches are fetched to render your skill charts, almost 1600 entries are potentially being added to the leaderboard.

That graph at the top of the board shows the distribution of skills as recorded by Halo Query. Each bar can be clicked to jump to the corresponding page in the leaderboard.

If you're logged in to Halo Query, you'll also see a new "Leaderboard" button in the player search and your user menu. Clicking this will jump you directly to that player's page on the leaderboard.

However, being logged in is not a requirement to view the page, so share the link as much as you like. Happy grinding!

By popular demand (2 whole people!), I've added the ability to save and share the queries you build on the "Matches" page. As you modify the filters, columns, or page size, you will notice that the URL of your browser will update. That URL will now contain all the data anyone would need to run the exact same query at a later date, so you can share it with your friends or bookmark it in your browser for later.

Let's walk through a quick example. I use a specific gametype to do my warmups, and I like to be able to see my progress (or lack thereof) over time. I need a query that shows me all my games of that gametype, so I set up a filter for matches played with that Game Variant.

Bot FFA Training Filter

The URL in my browser now contains a whole mess of characters that represent this particular filter. The relevant part will look something like: &filters=%7B%22and%22%3A%5B%7B%22%3D%3D%22%3A%5B%7B%22var%22%3A%22Game+Variant%22%7D%2C%22Bot+FFA+Training%22%5D%7D%5D%7D

Now I want to share a column layout. The "Shyway's Bot Training" preset (relevant Shyway video) is a good start, but I'd like to make a few tweaks to it. First I select the preset from the Column options to use it as a starting point.

Shyway's Bot Training Preset

Then I flip the preset to "Custom". This gives you all of the columns of whatever preset you were just on, but now you can modify them to suit your needs. Personal preference, there are a few columns in the preset that I don't care about, and I'd like to add a few that are important to me. I'm going to drop Deaths, Assists, and Damage Taken, swap Kills and Damage for their 'per minute' counterparts, and add the Duration column so I know if I cut a warmup short.

Custom Bot Training

Our URL will now contain a bunch of numbers that describe the column layout I've selected. In this case, it looks like so: &columns=11641134627437484456082978756924276810 Fun fact, there are currently 193 different columns you can activate, and that jumble of numbers can represent any combination you choose. There are 2193 possibilities to choose from!

Query's looking good. I'll be on the HCS circuit in no time (I hear Complexity might have a roster slot open).

Note that query URLs are inherently tied to whatever gamertag you're currently querying. If you share the query with someone else, it'll load up whatever gamertag you were looking at when you ran the query, so if someone wants to run the query for their account instead, they'll need to change the gamertag once the page loads.

As of today, I'm removing the stat "PSR" from the site. In short, it's not showing us anything that couldn't be better represented by reviewing its component parts individually. Everything I show on this site is supposed to be computed directly from Halo's API data and PSR was the one glaring exception.

PSR was calculated by combining PSR-K and PSR-D to try to give you an "overall match performance" metric. PSR-K and PSR-D are computed directly from the API data, no assumptions on my part, and I have every confidence in their usefulness as statistics.

In order to calculate PSR, however, I need to make an assumption about the relative importance of kills and deaths. While initially I figured that a simple 50/50 split would be sufficient, it has become abundantly clear that is not the case - the actual mixture is not even. Given that there is no data on what the correct ratio should be (and that it may fluctuate from one game type to the next), I think the responsible thing to do is to stop guessing.

You might ask "Does ESR have this same problem?". The answer is actually yes, but if you look at some ESR-K and ESR-D values, you'll see why it doesn't matter. Here's a few of mine for instance:


The difference between the two is so small that it doesn't matter how you weight them, the result is going to be effectively the same.

That just leaves the question of what metric to use in PSR's place. I mentioned that I cannot accurately deduce the mixture of PSR-K and PSR-D. That's true, but I can definitely give you an semi-accurate anecdotal-based guess: Kills are way more important. I've had plenty of users in the discord ask me why their ESR isn't rising, and never once has it been that they were dying too much. If you want to gauge your performance over time, follow your PSR-K value.

I've been attempting to work out how ESR adjusts based on match performance, and one of things that kept bugging me was the seeming randomness of CTF ESR. A good performance would decrease it, and bad performances might increase it. Very confusing stuff.

It finally dawned on me that CTF 3 Flag and CTF 5 Flag are being treated as two different ESR values. In hindsight, this should have been obvious, given that u/SecureStreet's original post on reddit from which the "by game mode" ESR graph is based had the two game types split. They appear to be highly correlated, so it was easier for the mistake to hide for this long.

Anyway, the end result is that there's an extra category on the profile page. That's all for now!

I'm testing out showing ESR as an average of your most recent ESRs by game type (rather than whatever your last 10 were), since I think it'll help in cases where you get served a large group of, say, strongholds matches that artificially deflate your ESR.

For now, ESR-10 will remain in the header of the profile page and as the primary display in the "Skill History" chart, but I've replaced it with the new metric in the "Expected Skill Rank by Mode" chart.

I'll probably leave it like this for a few weeks and then axe one or other. If anyone has any strong feelings on either one of those metrics, let me know in the Discord.

UPDATE: I know I said weeks, but yeah, I like this way better. I've replaced ESR-10 with ESR-A everywhere on the profile page. Additionally, I've adjusted the colors on the player profile charts to be a bit more readable.

As of 4:54 PM EST today, @HaloSupport tweeted out that a fix has been applied to ranked CSR rewards. Correspondingly, as of about 3:15PM EST, I see matches appearing with counterfactual values more in line with pre-update values. I've restored the original PSR computations accordingly.

I wouldn't expect 343 to retroactively update ranks or game data from the period when this issue was present, so any matches from the launch of CU29 to this point are just going to have some bizarre looking data forever. Best thing we can do is generate new data (aka, play the game) and put this fiasco behind us.

Discord Server


I've created a Discord server for Halo Query. At the moment, it's just me in here, which is kinda depressing. So stop by to discuss the site, suggest features, and troubleshoot any bugs you may be encountering, I'll be happy to help.

Invite Link

Looks like there was a rank reset with the CU29 update, and 343 slipped something into the sauce. Death counterfactuals are making an incredibly flat skill curve for all levels. As a result, PSR-D (and thus, PSR) values are super out of whack. I checked, the call isn't coming from our house: the API values are being correctly processed, its just that they're getting delivered to us in a broken state. Look for a 343 fix in the new few days, I'd guess.

UPDATE: In an attempt to make PSR usable, I've temporarily removed PSR-D from the calculation across the site.

We're Live!


I'm declaring the end of the Alpha testing phase. For you, the only practical change is that we're no longer operating on a whitelist and anyone can use Halo Query. Feel free to share it with anyone you like!

From a technical perspective, it means I've implemented the features that I intended to when I started building this. That doesn't mean I'm done working on Halo Query though. Lord knows we've got some bugs I need to work out, to say nothing about the hideous UI I've concocted here. More is to come (always).

To everyone who has been using the site during the Alpha, you've provided valuable telemetry for helping me track down issues. Big shout-out to those who actually gave me real feedback too, you know who you are.