> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/yakushabb/mirror-ryujinx/llms.txt
> Use this file to discover all available pages before exploring further.

# Profiled Persistent Translation Cache (PTC)

> Learn how PTC dramatically reduces game load times by caching translated code

The **Profiled Persistent Translation Cache (PTC)** is one of Ryujinx's most impactful performance features, saving translated ARM code to disk so games launch dramatically faster on subsequent runs.

<Info>
  **PPTC** (Profiled Persistent Translation Cache) is enabled by default. You'll see significant load time improvements after the second launch of any game.
</Info>

## What is PTC?

PTC addresses a fundamental challenge in emulation: code translation overhead.

### The Problem

Without PTC:

* Every game launch requires translating ARM code to x86/ARM64
* Translation happens on-demand during gameplay
* First launch has lengthy load times and stuttering
* **Every single launch** repeats this process

### The Solution

With PTC:

* Translated code is saved to disk after first runs
* Subsequent launches load pre-translated code instantly
* Eliminates translation overhead
* **Dramatic** reduction in load times (often 80-95% faster)

<CardGroup cols={2}>
  <Card title="First Run" icon="hourglass-start">
    Game launches slowly while building the translation cache
  </Card>

  <Card title="Second Run" icon="clock">
    Faster, but still profiling code execution patterns
  </Card>

  <Card title="Third Run+" icon="rocket">
    Full speed! Loads in seconds instead of minutes
  </Card>

  <Card title="Ongoing" icon="gauge-simple-high">
    Cache continuously improves with play time
  </Card>
</CardGroup>

## How PTC Works

### Translation Cache System

```csharp theme={null}
// From Ptc.cs
class Ptc : IPtcLoadState
{
    private const uint InternalVersion = 7010;
    public PtcProfiler Profiler { get; }
    public PtcState State { get; private set; }
}
```

### The Three-Stage Process

<Steps>
  <Step title="First Launch: Building">
    **Initial Translation & Profiling**

    * Game loads and translates ARM code on-demand
    * Translation overhead causes slower initial load
    * PTC profiler tracks which functions are executed
    * Code execution patterns recorded
    * No cache exists yet

    <Note>
      The first launch takes the longest. This is expected behavior as the cache is being built.
    </Note>
  </Step>

  <Step title="Second Launch: Profiling">
    **Optimized Translation with Profiling**

    * Previously translated code loads from cache
    * Load time noticeably faster
    * Profiler continues tracking "hot" functions
    * Identifies frequently-executed code paths
    * Cache expanded and refined

    <Info>
      You'll see improvement on the second launch, but the system is still learning optimal translations.
    </Info>
  </Step>

  <Step title="Third Launch+: Full Speed">
    **Maximum Performance Unlocked**

    * Complete cache with profiled optimizations
    * Functions translated at optimal quality levels
    * Near-instant load to title screen
    * Smooth gameplay without translation stutters
    * Cache continuously refined

    <Warning>
      You **must** launch the game to the title screen or beyond on the first two launches. Simply opening and immediately closing won't build the cache properly.
    </Warning>
  </Step>
</Steps>

## Profiling System

The "Profiled" part of PPTC:

### What Gets Profiled

```csharp theme={null}
// From PtcProfiler.cs
public class PtcProfiler
{
    public ulong StaticCodeStart { get; set; }
    public ulong StaticCodeSize { get; set; }
}
```

<CardGroup cols={2}>
  <Card title="Execution Frequency" icon="chart-line">
    How often each function is called (hot vs cold code)
  </Card>

  <Card title="Code Patterns" icon="diagram-project">
    Common execution paths and branch patterns
  </Card>

  <Card title="Static Code Regions" icon="memory">
    Game code that doesn't change (most executable code)
  </Card>

  <Card title="Optimization Targets" icon="bullseye">
    Functions that benefit most from high-quality compilation
  </Card>
</CardGroup>

### Optimization Levels

Based on profiling data, functions are compiled at different quality levels:

| Level      | When Used           | Characteristics                          |
| ---------- | ------------------- | ---------------------------------------- |
| **Tier 0** | First execution     | Fast compilation, basic optimization     |
| **Tier 1** | Frequently executed | Balanced compilation time and quality    |
| **Tier 2** | Hot paths           | Maximum optimization, slower compilation |

<Info>
  The profiler ensures "hot" code (executed frequently) gets the most aggressive optimizations, while rarely-used code uses faster compilation.
</Info>

## Cache Storage

### File Structure

```
Ryujinx/
├── games/
    ├── [TitleID]/
        ├── cache/
            ├── cpu/
                ├── 0/              # Active cache
                │   ├── [Version]-[Profile]
                ├── 1/              # Backup cache
                    ├── [Version]-[Profile]
```

### Cache Components

```csharp theme={null}
// From Ptc.cs - Cache file structure
private MemoryStream _infosStream;      // Function metadata
private List<byte[]> _codesList;        // Translated native code
private MemoryStream _relocsStream;     // Relocation information
private MemoryStream _unwindInfosStream; // Exception handling data
```

Each cache stores:

1. **Function Information**: Addresses, sizes, metadata
2. **Translated Code**: Native x86/ARM64 machine code
3. **Relocations**: Address fixups for dynamic linking
4. **Unwind Info**: Stack unwinding for exception handling

### Cache Versioning

```csharp theme={null}
private const uint InternalVersion = 7010;
```

Caches are versioned and include:

* **Internal Version**: Ryujinx translator version
* **Game Version**: Display version from game metadata
* **Profile Name**: Configuration profile identifier
* **Memory Mode**: Host-mapped, software MMU, etc.

<Note>
  When Ryujinx updates with translator changes, old caches are automatically invalidated and rebuilt.
</Note>

## Compression

```csharp theme={null}
private const CompressionLevel SaveCompressionLevel = CompressionLevel.Fastest;
```

PTC uses compression to reduce disk usage:

* **Algorithm**: Deflate compression
* **Level**: Fastest (prioritizes speed over size)
* **Typical Size**: 50-200 MB per game
* **Save Time**: Compressed during background save

## Performance Impact

### Load Time Comparison

<Tabs>
  <Tab title="Without PTC">
    ### Without PTC (Disabled)

    **Every Launch:**

    * 2-5 minutes to reach title screen
    * Stuttering during gameplay (shader compilation)
    * High CPU usage during translation
    * Repeated work every single time

    **Total time wasted across 10 launches:** 20-50 minutes
  </Tab>

  <Tab title="First Launch">
    ### First Launch (Building Cache)

    * 2-5 minutes to title screen
    * Some stuttering during gameplay
    * Profiler recording execution patterns
    * Cache built in background

    <Note>
      Similar to running without PTC, but this is one-time setup.
    </Note>
  </Tab>

  <Tab title="Second Launch">
    ### Second Launch (Refining)

    * 30-90 seconds to title screen (50-70% faster)
    * Reduced stuttering
    * Loading cached translations
    * Additional profiling refinement

    <Info>
      Already much faster, but not at peak performance yet.
    </Info>
  </Tab>

  <Tab title="Third+ Launch">
    ### Third Launch+ (Full Cache)

    * **5-15 seconds** to title screen (90-95% faster!)
    * Minimal to no stuttering
    * Smooth gameplay immediately
    * Optimized code paths active

    <Info>
      This is where PTC truly shines. Games that took minutes now load in seconds.
    </Info>
  </Tab>
</Tabs>

### Real-World Impact

| Game Example    | Without PTC | With PTC (3rd+ launch) | Improvement  |
| --------------- | ----------- | ---------------------- | ------------ |
| **Large RPG**   | 4-5 minutes | 10-15 seconds          | \~95% faster |
| **Action Game** | 2-3 minutes | 5-10 seconds           | \~93% faster |
| **Platformer**  | 1-2 minutes | 5-8 seconds            | \~90% faster |

<Info>
  Actual load times vary by game, CPU speed, and storage device. SSDs provide faster cache loading than HDDs.
</Info>

## Configuration

### Enabling/Disabling PTC

**Location:** Options → System → Enable PPTC

<Note>
  **Default:** Enabled (strongly recommended)
</Note>

### When to Disable PTC

Rarely needed, but consider disabling if:

* Debugging emulation issues
* Very limited storage space
* Testing translator changes (developers)
* Cache corruption suspected

<Warning>
  Disabling PTC means **every** game launch will have long load times and stuttering. Only disable if absolutely necessary.
</Warning>

## Cache Management

### Automatic Management

Ryujinx handles cache management automatically:

* **Backup System**: Previous cache backed up to `/1/` directory
* **Version Tracking**: Caches per game version
* **Corruption Detection**: Invalid caches automatically rebuilt
* **Background Saving**: Cache saved without blocking gameplay

### Manual Cache Clearing

To clear PTC for a specific game:

1. Close Ryujinx
2. Navigate to `Ryujinx/games/[TitleID]/cache/cpu/`
3. Delete the `0` and `1` directories
4. Launch game (will rebuild cache)

<Note>
  Clearing the cache is safe but will require rebuilding (2-3 launches to full speed again).
</Note>

## Low-Power Mode

```csharp theme={null}
// From Optimizations.cs
public static bool LowPower { get; set; } = false;
```

For systems with few CPU cores:

* **Default:** Disabled
* **When Enabled:** Reduces background translation threads
* **Trade-off:** Slightly longer cache building, less CPU usage
* **Recommended For:** Dual-core CPUs, laptops, battery-powered devices

## Technical Deep Dive

### Cache Loading Process

```csharp theme={null}
// From Translator.cs
public void Execute(State.ExecutionContext context, ulong address)
{
    if (Interlocked.Increment(ref _threadCount) == 1)
    {
        if (_ptc.State == PtcState.Enabled)
        {
            _ptc.LoadTranslations(this);
            _ptc.MakeAndSaveTranslations(this);
        }
    }
}
```

When a game starts:

1. **Check PTC State**: Is PTC enabled?
2. **Load Existing Cache**: Read from disk if available
3. **Restore Functions**: Load translated code into memory
4. **Update Function Table**: Map game addresses to native code
5. **Start Profiler**: Begin tracking for optimization
6. **Background Translation**: Translate new code as needed
7. **Save Updates**: Periodically save cache updates

### JIT Cache Integration

PTC works alongside the JIT cache:

```csharp theme={null}
// From JitCache.cs
internal static void Initialize(IJitMemoryAllocator allocator)
{
    // Allocate executable memory for translated code
}
```

* **Memory Cache**: Native code in executable memory pages
* **Disk Cache (PTC)**: Persistent storage of translations
* **Hybrid Approach**: Fast memory access with persistent storage

## Troubleshooting

<AccordionGroup>
  <Accordion title="Game still loads slowly after 3+ launches">
    * Verify PTC is enabled in Options → System
    * Check you launched to title screen (not just opened and closed)
    * Ensure sufficient disk space for cache
    * Try clearing the cache and rebuilding
    * Check storage device isn't failing
  </Accordion>

  <Accordion title="Cache taking excessive disk space">
    * PTC caches are typically 50-200 MB per game
    * Multiple game versions create separate caches
    * Check for multiple profiles creating duplicate caches
    * Delete old caches manually if needed
    * Consider clearing caches for games you don't play
  </Accordion>

  <Accordion title="Game crashes after PTC enables">
    * Cache may be corrupted
    * Clear PTC cache for that game
    * Update Ryujinx (old cache version mismatch)
    * Report bug if reproducible
  </Accordion>

  <Accordion title="PTC not saving between launches">
    * Check file permissions in games directory
    * Ensure Ryujinx can write to cache folder
    * Check antivirus isn't blocking cache files
    * Verify disk isn't full
  </Accordion>
</AccordionGroup>

## Best Practices

<CardGroup cols={2}>
  <Card title="Keep PTC Enabled" icon="toggle-on">
    Always leave PTC enabled unless debugging specific issues
  </Card>

  <Card title="Patience on First Launch" icon="hourglass">
    Let the first 2-3 launches complete fully to build optimal cache
  </Card>

  <Card title="Use SSD Storage" icon="hard-drive">
    Store Ryujinx on an SSD for faster cache loading
  </Card>

  <Card title="Clear Old Caches" icon="trash">
    Periodically clean caches for uninstalled games
  </Card>
</CardGroup>

## Technical Implementation

Key source locations:

* **PTC Core**: `src/ARMeilleure/Translation/PTC/Ptc.cs`
* **Profiler**: `src/ARMeilleure/Translation/PTC/PtcProfiler.cs`
* **Translator Integration**: `src/ARMeilleure/Translation/Translator.cs`
* **JIT Cache**: `src/ARMeilleure/Translation/Cache/JitCache.cs`

<Info>
  PTC represents one of the most significant optimizations in modern emulation, turning minutes of wait time into seconds.
</Info>

## Summary

PTC is a game-changer for Ryujinx:

* **Enabled by default** and strongly recommended
* **Three launches** to reach full performance
* **90-95% reduction** in load times after cache built
* **Automatic** background operation
* **Per-game** caching with version management
* **Minimal storage** cost (50-200 MB per game)

<Card title="Related: CPU Emulation" icon="microchip" href="/features/cpu-emulation">
  Learn more about the ARMeilleure JIT compiler that PTC caches
</Card>
