Skip to main content
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.
PPTC (Profiled Persistent Translation Cache) is enabled by default. You’ll see significant load time improvements after the second launch of any game.

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)

First Run

Game launches slowly while building the translation cache

Second Run

Faster, but still profiling code execution patterns

Third Run+

Full speed! Loads in seconds instead of minutes

Ongoing

Cache continuously improves with play time

How PTC Works

Translation Cache System

// 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

1

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
The first launch takes the longest. This is expected behavior as the cache is being built.
2

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
You’ll see improvement on the second launch, but the system is still learning optimal translations.
3

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
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.

Profiling System

The “Profiled” part of PPTC:

What Gets Profiled

// From PtcProfiler.cs
public class PtcProfiler
{
    public ulong StaticCodeStart { get; set; }
    public ulong StaticCodeSize { get; set; }
}

Execution Frequency

How often each function is called (hot vs cold code)

Code Patterns

Common execution paths and branch patterns

Static Code Regions

Game code that doesn’t change (most executable code)

Optimization Targets

Functions that benefit most from high-quality compilation

Optimization Levels

Based on profiling data, functions are compiled at different quality levels:
LevelWhen UsedCharacteristics
Tier 0First executionFast compilation, basic optimization
Tier 1Frequently executedBalanced compilation time and quality
Tier 2Hot pathsMaximum optimization, slower compilation
The profiler ensures “hot” code (executed frequently) gets the most aggressive optimizations, while rarely-used code uses faster compilation.

Cache Storage

File Structure

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

Cache Components

// 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

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.
When Ryujinx updates with translator changes, old caches are automatically invalidated and rebuilt.

Compression

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

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

Real-World Impact

Game ExampleWithout PTCWith PTC (3rd+ launch)Improvement
Large RPG4-5 minutes10-15 seconds~95% faster
Action Game2-3 minutes5-10 seconds~93% faster
Platformer1-2 minutes5-8 seconds~90% faster
Actual load times vary by game, CPU speed, and storage device. SSDs provide faster cache loading than HDDs.

Configuration

Enabling/Disabling PTC

Location: Options → System → Enable PPTC
Default: Enabled (strongly recommended)

When to Disable PTC

Rarely needed, but consider disabling if:
  • Debugging emulation issues
  • Very limited storage space
  • Testing translator changes (developers)
  • Cache corruption suspected
Disabling PTC means every game launch will have long load times and stuttering. Only disable if absolutely necessary.

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)
Clearing the cache is safe but will require rebuilding (2-3 launches to full speed again).

Low-Power Mode

// 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

// 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:
// 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

  • 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
  • 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
  • Cache may be corrupted
  • Clear PTC cache for that game
  • Update Ryujinx (old cache version mismatch)
  • Report bug if reproducible
  • 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

Best Practices

Keep PTC Enabled

Always leave PTC enabled unless debugging specific issues

Patience on First Launch

Let the first 2-3 launches complete fully to build optimal cache

Use SSD Storage

Store Ryujinx on an SSD for faster cache loading

Clear Old Caches

Periodically clean caches for uninstalled games

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
PTC represents one of the most significant optimizations in modern emulation, turning minutes of wait time into seconds.

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)

Related: CPU Emulation

Learn more about the ARMeilleure JIT compiler that PTC caches

Build docs developers (and LLMs) love