Skip to content
← All news
7 min read

GTA Online was slow for 7 years because of just 2 bad lines of code

In 2021, a programmer named t0st reverse engineered GTA Online's PC loading screen, found a JSON parser rescanning a 10MB file and a duplicate check running billions of pointless comparisons, and cut load times by up to 70 percent. Rockstar confirmed it and paid him $10,000.

One CPU core pinned at 100 percent for six minutes, doing nothing but bad math on a shop list.

For seven years, GTA Online players sat through five to ten minute loading screens and blamed the usual suspects: a huge open world, slow internet, an old hard drive. In February 2021, a programmer going by t0st opened a profiler instead of a support ticket and found the real cause: one CPU core pinned at 100 percent for minutes, burning cycles on a badly written item list parser. Two fixes later, load times dropped by up to 70 percent. Rockstar confirmed the bug, shipped an official patch, and paid t0st $10,000 through its bug bounty program, a program normally reserved for security holes.

What the profiler actually showed

t0st started where anyone would: Task Manager. During a loading screen, the GPU sat mostly idle. The SSD wasn't being hammered. Network traffic dropped off within seconds. But one CPU core stayed pinned at 100 percent for several minutes straight. Whatever GTA Online was doing during that wait, it wasn't waiting on hardware. It was making the CPU do unnecessary work, and that ruled out the usual explanations before the real investigation even started: not the open world's size, not peer to peer networking, not a slow drive.

To find out what that one core was actually doing, t0st reached for Luke Stackwalker to sample the stack, a borrowed copy of IDA Pro to disassemble the relevant code, and x64dbg with the MinHook library to patch functions at runtime and time them directly. That's reverse engineering a shipped, obfuscated game binary with no source code and no symbols, which is most of why this took days instead of an afternoon.

Two bugs, one JSON file

GTA Online's item catalog, every vehicle, weapon, piece of clothing, and upgrade sold in game, ships as a single 10MB JSON file with around 63,000 entries. Both bugs lived in how that one file got loaded.

The first bug was in how the game measured strings while parsing. Each time it read a value out of the JSON with sscanf, it called strlen on the string first, and strlen doesn't know where a string ends until it walks every character looking for the terminator. Called once, that's fine. Called once per field, across 63,000 items with multiple fields each, it means re-walking a huge chunk of that 10MB buffer over and over for work that had already been done a moment earlier.

The second bug showed up right after parsing. Every time GTA Online read a new item, it checked whether that item already existed by comparing it against every item already stored, one at a time, instead of using a hash map to check in constant time. With 63,000 items, every one of them already unique, that's roughly 63,000 multiplied by itself, close to 2 billion comparisons that could never find a match, because there was nothing to match.

for item in json_items:                 # 63,000 entries, 10MB file
    strlen(remaining_buffer)            # rescans from here to EOF, every field
    value = sscanf(...)

    for existing in already_inserted:   # linear scan against everything so far
        if existing == item: skip
    already_inserted.append(item)

The fix that changed nothing about the game

t0st never had GTA's source, so the patch worked at the binary level: hook the slow functions at runtime, cache the string length instead of recalculating it, and skip the duplicate check entirely, since every item was already guaranteed unique. Nothing about the game's data or behavior changed. Only the wasted work went away.

VersionLoading time
Original GTA Online~6 minutes
Duplicate check fixed~4 min 30 sec
JSON parsing fixed~2 min 50 sec
Both fixes applied~1 min 50 sec
Same PC, same connection, same save file. Only the code path changed.

Fixing the duplicate check alone saved about a minute and a half. Fixing the JSON parsing alone saved more, close to 3 minutes. Both together took the load from around 6 minutes down to 1 minute 50 seconds, a 69 to 70 percent cut.

Rockstar noticed

t0st published the writeup on February 28, 2021, and it spread fast enough to reach Rockstar directly. Instead of staying quiet, Rockstar confirmed the bug and said a fix was coming in a future title update. On March 15, 2021, Rockstar paid t0st $10,000 through its bug bounty program. The official patch shipped the next day, March 16, 2021, and testing it on the same hardware landed close to the same improvement t0st's own patch had already shown.

This was never a security bug, and t0st's own patch was a proof of concept binary patch shared publicly, not what shipped to players. Rockstar called the payout an exceptional case precisely because its bug bounty program is built for security vulnerabilities, not performance bugs. The fix every player got came from Rockstar's own engineers, working off what the writeup pointed at, not from t0st's exact code.
Two bugs in the same loop, both scaling with the size of the file instead of the size of the work.

Why a bad loop beat good hardware

None of this needed a faster GPU, a better SSD, or fiber internet. A gaming PC that can render an open world at 60 frames per second was still helpless against a loop that rescanned a 10MB buffer thousands of times and ran billions of comparisons that could never succeed. Software wasted the CPU faster than better hardware could work around it.

It also took profiling to find, not guessing. Task Manager alone ruled out hardware bottlenecks. Only a stack sampler and a disassembler pointed at the exact two functions burning the wait. Without measuring, a six minute load screen looks like the internet's fault, or the drive's fault, or the world's fault, which is exactly what millions of players assumed for seven years.

Why a build studio cares

We build MVPs and websites against a clock: 24 hours for a site, 48 for a working product with auth and payments wired in. That timeline only holds if we profile before we guess. A slow page load, a stalled API call, a laggy dashboard, almost never turns out to be the hardware, the framework, or the database engine. It's usually one loop doing more work than it needs to, the same shape as GTA Online's duplicate check.

t0st's writeup is also a clean argument for building things that can be profiled at all. A binary with no symbols and no source still gave up its bottleneck to a stack sampler and a disassembler, because the wasted work showed up as one CPU core pinned at 100 percent. If your own systems can't tell you which function is burning the wait, that's worth fixing before the wait itself is.

Next step: read t0st's original writeup for the full disassembly walkthrough, and PC Gamer's report on Rockstar's official response and patch. If a slow load, a stalled dashboard, or a laggy API is costing your users time and you want a second pair of eyes on where the CPU is actually going, write to us at hello@gattyworks.com.

GamingPerformance EngineeringReverse EngineeringGTAOnlineRockstarGameDevPerformanceEngineeringReverseEngineeringBugBountySoftwareEngineeringPCGamingGTA5CodeOptimization
04 · BRIEF

Ready to ship?

Send a brief. You will get a written reply, a fixed quote, and a delivery date within 24 hours. If we miss that window, the website fee on your first project is refunded in full.

24h reply, or 100% website fee refunded
Average reply under 4 hours. Always inside 24.