Skip to main content
Compressing Network Traffic with the Oodle Network Plugin

Compressing Network Traffic with the Oodle Network Plugin

·765 words·4 mins
A simple way to reduce network traffic — if you’re willing to spend a bit of CPU time.

Oodle Network
#

Unreal Engine 5 comes with Oodle Network built in — a library by Rad Game Tools designed for compressing network data. You can read more about it on the official page. A separate license is not required since Rad Game Tools is now part of the Epic Family.

The idea is straightforward: Oodle intercepts incoming and outgoing packets, learns from that data, and generates dictionaries that are later used to compress network messages before they’re sent over UDP. Essentially, the system remembers frequently repeating patterns and encodes them much shorter than their original representation.

Official documentation can be found here. I won’t go through the full setup process — instead, I’ll show what kind of results I got on simple tests and how compression affects overall performance.

Training Dictionaries
#

I slightly deviated from the official guide and recorded the packets using a built server instead of running the editor. After recording, I copied the captured data from the server into my Unreal Engine directory — these are the files that Oodle uses for training its dictionaries.

W:\TheGame\TheGame\Saved\Oodle
└───Server
    ├───Input
    │       PacketDump_UE5_0_7_2025.11.04-06.14.46_Input_1.ucap
    │       PacketDump_UE5_0_7_2025.11.04-06.14.46_Input_2.ucap
    │       PacketDump_UE5_0_7_2025.11.04-06.14.46_Input_3.ucap
    │       PacketDump_UE5_0_7_2025.11.04-06.14.52_Input.ucap
    │       PacketDump_UE5_0_7_2025.11.04-06.14.52_Input_1.ucap
    │       PacketDump_UE5_0_7_2025.11.04-06.14.52_Input_2.ucap
    │
    └───Output
            PacketDump_UE5_0_7_2025.11.04-06.14.45_Output.ucap
            PacketDump_UE5_0_7_2025.11.04-06.14.46_Output.ucap
            PacketDump_UE5_0_7_2025.11.04-06.14.46_Output_1.ucap
            PacketDump_UE5_0_7_2025.11.04-06.14.46_Output_2.ucap
            PacketDump_UE5_0_7_2025.11.04-06.14.46_Output_3.ucap

Dictionary training is done via the command line. For some reason, all output is logged with the Log verbosity level:

UE_LOG(OodleNetworkHandlerComponentLog, Log, TEXT("..."));

Because of that, you won’t see any messages in the console — only in the log file. Here’s the command I used to start the training process:

E:\Engine\Binaries\Win64\UnrealEditor-Cmd.exe W:\TheGame\TheGame.uproject -run=OodleNetworkTrainerCommandlet AutoGenerateDictionaries -CompressionTest
Generating dictionaries for Input folder
Generating dictionary for folder 'Input', outputting to: ...
Oodle trainer parameters:
- HashTableSize: 19
- DictionarySize: 4194304 (~4MB)
- Performing Trials: Yes
- DictionaryTrials: 3
- TrialRandomness: 200
- TrialGenerations: 1
- WriteDictionaryVersion: 9
Beginning dictionary generation...
- DictionaryPackets: 530412, Size: 28094424 (~26MB)
- DictionaryTestPackets: 530412, Size: 28095494 (~26MB), Overflowed: No
- TrainerPackets: 530412, Size: 28032284 (~26MB)
Dictionary generation may take a very long time (up to 7 mins for 1GB of packets).
Dictionary generation complete. Beginning Oodle state training...
Successfully processed packet captures, and wrote dictionary file.
Testing packet compression results...
Compression test results:
- CompressionTestPackets: 530411, Size: 28095912 (~26MB)
- Uncompressed: 28095912 (~26MB), Compressed: 14221937 (~13MB)
- Total Savings: 49.380760%
Successfully generated dictionary.
Generating dictionaries for Output folder
Generating dictionary for folder 'Output', outputting to: ...
Oodle trainer parameters:
- HashTableSize: 19
- DictionarySize: 4194304 (~4MB)
- Performing Trials: Yes
- DictionaryTrials: 3
- TrialRandomness: 200
- TrialGenerations: 1
- WriteDictionaryVersion: 9
DictionaryTestPackets overflowed into TrainerPackets (normal).
Beginning dictionary generation...
- DictionaryPackets: 365018, Size: 180712877 (~172MB)
- DictionaryTestPackets: 136180, Size: 67108992 (~64MB), Overflowed: Yes
- TrainerPackets: 593856, Size: 294049442 (~280MB)
Dictionary generation may take a very long time (up to 7 mins for 1GB of packets).
Dictionary generation complete. Beginning Oodle state training...
Successfully processed packet captures, and wrote dictionary file.
Testing packet compression results...
Compression test results:
- CompressionTestPackets: 365018, Size: 180287656 (~171MB)
- Uncompressed: 180287656 (~171MB), Compressed: 127685904 (~121MB)
- Total Savings: 29.176571%
Successfully generated dictionary.

The generated dictionaries are automatically included in the built package. After that, you can move straight on to testing.

Testing
#

The testing followed the same methodology as in the previous article. The main load came from replicating player movement and camera position — a typical scenario for a multiplayer environment.

After several runs, here are the inbound and outbound traffic results over a 5-minute test:

Without compression: In — 217 MB, Out — 918 MB
With compression: In — 157 MB, Out — 567 MB

Using Oodle Network reduced total network traffic by roughly one-third, which becomes especially significant when dealing with a large number of actively replicated actors.

The graphs show that traffic compression introduces some overhead, which should be taken into account during testing. Ideally, the compression process could be offloaded to a separate thread to reduce pressure on the game thread. However, in the current implementation this isn’t possible — the HandlerComponent processes packets right after they’re received and before they’re sent, both of which happen during WorldTick.

If your game changes patch to patch in appreciable ways, you need to retrain Oodle Network on new packet captures, and release new dictionaries with the patch.

It’s also important to remember that whenever the engine or your game’s networking code changes, the dictionaries need to be retrained on updated data. Ideally, this process should be integrated into your CI pipeline to automatically collect packets and retrain dictionaries as part of the build.