Six minutes to get into GTA Online. One minute and ten seconds to get into story mode. Same machine, same drive, same game. In February 2021, a programmer who goes by t0st decided that gap had to have a cause you could point at, not just a feeling you could complain about. He opened Task Manager, then a stack sampler, then a disassembler, and found it: a 10MB JSON catalog of about 63,000 purchasable items, parsed in a way that recalculated a string length for every item, and then checked for duplicates that could not exist. Two small hooks later, his load time was 1 minute 50 seconds. Rockstar confirmed the finding, paid him 10,000 dollars through its bug bounty program as an exception, and shipped loading improvements in Title Update 1.53 on March 16, 2021.
At a glance
Symptom: GTA Online on PC took about 6 minutes to load on t0st's machine, while story mode took about 1 minute 10 seconds
Machine (author self-test): AMD FX-8350 CPU, NVIDIA GeForce GTX 1070 GPU, Kingston SA400S37120G SSD, 16 GB DDR3 RAM
Bottleneck: one CPU core maxed out for about four minutes while disk, network and GPU usage sat near zero
Root cause 1: parsing a 10MB JSON catalog of about 63,000 items, the parser's sscanf path called strlen again and again, recounting the string for each item
Root cause 2: after parsing each item, the game scanned the whole stored list comparing hashes, a quadratic check totalling 1,984,531,500 comparisons, for data that was already unique
Fix: cache the string length and return the cached value; skip the duplicate check and insert items directly
Result (author self-test): duplicate-check fix alone, 4 minutes 30 seconds; JSON parser fix alone, 2 minutes 50 seconds; both together, 1 minute 50 seconds, a 69.4 percent reduction
Official outcome: Rockstar Title Update 1.53 (March 16,
2021) lists improvements to PC loading times and thanks t0st; t0st reported a 10,000 dollar bug bounty awarded as an exception
Warning: the proof of concept injects a DLL and hooks game functions while the game runs. Its README says it is not meant for casual use and that online modification might get an account suspended. Do not run it on a live account
The symptom: a 6 minute load that hardware could not explain
t0st's benchmark, measured from the Rockstar logo until in game and excluding Social Club login time, was simple and damning. Story mode loaded in about 1 minute 10 seconds. Online mode loaded in about 6 minutes flat. Other players' reports pointed the same way: high-end PCs still needed about 2 minutes for online mode, while their story mode loads stayed near a minute. A faster drive did not close the gap, which is the first clue that the bottleneck was not the drive at all.
Task Manager gave the second clue. After the first minute, which loads resources shared by story and online modes, GTA Online maxed out a single CPU core for about four minutes and did nothing else. Disk usage was none. Network usage dropped to basically zero after a few seconds, apart from rotating info banners. GPU usage was zero. Memory usage was completely flat. When a game is not reading, not downloading, not rendering and not allocating, but one core is burning, the problem is code running in a loop.
A single-threaded bottleneck also explains why the pain varied so much between machines. A CPU with stronger single-thread performance chewed through the same wasted work faster, while extra cores, a faster SSD or a better GPU could not help at all, because the work was never parallel, never disk-bound and never GPU-bound. If your game loads slowly and your hardware upgrades do nothing, check whether one core is doing all the work before you blame the drive.
Profiling without source code
t0st did not have Rockstar's source code, so a normal instrumenting profiler was out. He used stack sampling instead: dump the running process's stack and instruction pointer at set intervals, then add the samples up into a calling tree. The tool he used was Luke Stackwalker, a Windows stack sampler that had not been updated in over ten years at the time. With no debugging symbols, he had to group nearby addresses by eye. Two hot spots stood out, not one.
To read the actual code he dumped the game's memory while it executed the part he wanted, because the shipped instructions were obfuscated, then disassembled the de-obfuscated dump. One sampled address carried a label: strlen. The next frame up was labeled vscan_fn, and t0st concluded with stated confidence, not certainty, that the caller was sscanf. That honesty matters. The labels he assigned during reversing are his own, and the article says so. What he could verify by sampling the running process was what the code was parsing: JSON, about 10 megabytes of it, holding about 63,000 item entries, apparently the net shop catalog of everything purchasable in GTA Online.
Problem one: strlen, called 63,000 times too many
Most sscanf implementations call strlen, t0st writes, and he is fair about it: he did not know that before this investigation, and he does not blame the developer who wrote the parsing code for assuming sscanf would scan byte by byte and stop at a null terminator. But the consequence was brutal. Every time the parser moved to a new item, it recalculated the length of the string from scratch. Across about 63,000 items, that is about 63,000 length calculations where one would do, each one walking a long string.
The fix is almost embarrassing in its simplicity, and that is the point. Hook strlen, wait for a long string, cache its start and length, and if strlen is called again with a pointer inside that string's range, return the cached value by computing end minus str. A guard unloads the hook when the remaining length gets small, so the hook does not interfere with unrelated code afterward. The lesson generalizes far beyond this game: any parsing loop that asks for the length of an unchanged buffer on every iteration is paying a linear cost inside what should be a linear pass, and the bill arrives multiplied by the number of items.
The core of t0st's published strlen hook, quoted from nee.lv (February 28,
2021) and the public proof of concept repository tostercx/GTAO_Booster_PoC, is: hook strlen; when a string longer than the 20000 cap appears, save its start and end; on later calls with a pointer inside that range, return end minus str, and disable the hook once the remaining length falls below half the cap. This is a binary-level hook, not Rockstar source code.
Problem two: nearly 2 billion checks for duplicates that did not exist
The second hot spot sat right next to the first, called in the same if statement. After parsing an item, the game stored it in an array-like list. Each entry held a hash and an item pointer. But before storing, the code checked the entire list, one by one, comparing the new item's hash against every hash already stored. With about 63,000 entries, that is (n squared plus n) divided by 2, which t0st works out as 1,984,531,500 checks. He names the structure not_a_hashmap, because it holds hashes without being a hash map at all: a real hash map would look each key up in near-constant time instead of scanning everything.
Then came the detail that turns a performance bug into a punchline. The list is empty before the JSON loads, and every item in the JSON is unique. The duplicate check was guarding against something the input data had already ruled out. Worse, the code already had a function to insert items directly. The fix was to skip the check and use it. Two lessons follow. First, a quadratic algorithm hides comfortably inside a small feature until the data grows: 63,000 items sounds modest until you square it. Second, a correctness check is only worth its cost if the invariant it guards can actually be violated. When the input guarantees uniqueness, the check is pure overhead, and the honest fix is to remove it or replace the linear scan with a real hash map, both options t0st himself suggested to Rockstar.
The results: each fix alone, then both together
This is where the case earns its status as evidence rather than anecdote, because t0st measured the fixes separately. On his machine, the original online load was about 6 minutes flat. With only the duplicate-check patch, it fell to 4 minutes 30 seconds. With only the JSON parser patch, it fell to 2 minutes 50 seconds. With both patches, it fell to 1 minute 50 seconds. The combined improvement is (360 minus
110) divided by 360, or 69.4 percent.
Read those numbers carefully, because they correct a common misreading. Neither fix alone explains the whole story, and the JSON parsing fix mattered more than the duplicate check on this machine. A team that had only fixed the hash scan would still have left players waiting nearly three minutes. Profiling both hot spots, and measuring each fix in isolation, is what made the conclusion trustworthy. All of these timings are t0st's self-tests on one dated machine, not a controlled benchmark across hardware. PC Gamer's later retest after the official patch is a separate data point: Wes Fenlon went from 3 minutes 15 seconds to 2 minutes on his own machine, and Phil Savage reached just over a minute without a timed before-figure. Those confirm the direction, not the exact 69.4 percent. Rockstar itself published no percentage and no implementation details for its official fix, so this article does not claim the official patch is identical to the proof of concept.
The official fix: confirmation, bounty, and Title Update 1.53
The timeline is short, which is part of why the case is still cited. t0st published on February 28,
2021. On March 15, 2021 he updated the post: Rockstar had confirmed a fix was coming, and he had been awarded 10,000 dollars through its HackerOne in-game bounty as an exception, because that program usually covers security issues. On March 16, 2021, Rockstar released GTAV Title Update 1.53, whose PC notes include the line: Improvements to PC loading times, with the note, Thanks to t0st for his contributions around this part of today's title update. t0st retested the official update on the same hardware and reported the fix worked, from the Rockstar logo to fully online in just under two minutes on his retelling of the run.
One correction to a number that sometimes circulates: some secondary coverage inflated the bounty or attached it to the wrong update. The primary source, t0st's own update, says 10,000 dollars, awarded as an exception through the in-game bounty, and the patch notes tie the thanks to Title Update 1.53. This article uses those figures.
What to take into your own project
Profile startup before you optimize anything else. A single core at 100 percent while disk, network and GPU idle is a code smell, not a hardware shortage
Measure each suspect separately. t0st's split timings showed the parser fix mattered more than the dedupe fix; fixing only the louder complaint would have left most of the wait in place
Never compute a stable length inside a loop. Cache it, or pass a length alongside the pointer, and watch for standard library calls that hide a length computation inside them
Question every guard whose invariant the data already guarantees. If the input is unique by construction, a duplicate scan is not safety, it is a tax, and it grows quadratically
If a scan must stay, use a real hash map. A list of hashes is not a hash map, and naming it like one does not make lookups cheap
Prove the diagnosis with the smallest possible intervention before rewriting. A hook that caches one value and skips one check turned a theory into a 69.4 percent measured improvement, which is what made Rockstar act in about two weeks
Do not ship a binary hook as a player-facing fix. t0st's proof of concept exists to demonstrate a bug to developers; its README warns it is not for casual use and that online modification risks suspension. The correct destination for this kind of work is the developer's own patch, which is exactly where it ended up
Sources and evidence notes
Sources: t0st, How I cut GTA Online loading times by 70 percent, nee.lv, February 28, 2021, with updates March 15 and 16, 2021; tostercx/GTAO_Booster_PoC on GitHub, public archived proof of concept created February 28, 2021; Rockstar Games, GTAV Title Update 1.53 notes, March 16, 2021, improvements to PC loading times with thanks to t0st; PC Gamer, March 2021, Rockstar's confirmation, the 10,000 dollar bounty as an exception, and retest timings (Fenlon 3 minutes 15 seconds to 2 minutes; Savage just over a minute, no timed baseline); Eurogamer and Digital Foundry, March 2021, corroboration only. Evidence boundaries: all load timings are single-machine self-tests or media retests, not controlled benchmarks; Rockstar disclosed no implementation details, so the official fix is described only as loading improvements, not as t0st's code; the proof of concept is a binary-level hook, not official source; t0st's reversing labels are his own and are marked as such in his write-up.
Multiplayer Not Laggy but Keeps Kicking You Out? How Factorio Desyncs Really Happen
Why Did My Balatro Save Load With the Wrong Stats After Corruption?
This article contains no affiliate links. All load timings are attributed to their sources in the text; no new benchmark, frame rate or test result has been invented for this article.

