Wiki 9Minecraft Wiki 9Minecraft

RakNet Protocol and Add-on Network Limits

How Bedrock's underlying UDP transport affects custom packets, synced properties, and pack downloads.

5Sections
2Code examples
3Known errors

RakNet is the UDP-based transport layer that Minecraft Bedrock Edition uses for all communication between the server and connected clients. While add-on creators cannot construct raw RakNet frames directly, every custom script event, entity property update, and resource pack transfer passes through this protocol. Understanding how RakNet batches, fragments, and prioritizes traffic is essential when debugging client disconnects, script message limits, and high-latency desynchronization in multiplayer worlds.

What RakNet Does in Bedrock

Standard UDP does not guarantee that packets arrive in order, or at all. Minecraft Bedrock layers a modified version of the RakNet library over UDP (defaulting to port 19132 for IPv4 and 19133 for IPv6) to provide optional reliability and ordering channels without the heavy connection overhead of TCP. When a player joins a Dedicated Server or Realm, RakNet handles the initial unconnected ping, connection handshake, and Maximum Transmission Unit (MTU) negotiation before a single game packet is exchanged.

Once the RakNet session is established, the game wraps compressed batches of Bedrock game packets inside RakNet frames. As an add-on developer, you do not open sockets or read byte streams. Instead, your JSON declarations and Script API calls generate high-level game packets that the engine queues into RakNet reliability channels on the next server tick.

Reliability ModeBehaviorTypical Add-on Traffic
UnreliableSent once; dropped packets are never resent.High-frequency particle spawns and minor visual updates.
ReliableGuaranteed to arrive, but may arrive out of order.One-off ambient sound triggers and non-sequential state notifications.
Reliable OrderedGuaranteed to arrive in the exact sequence sent.Script messages, dynamic property sync, entity definitions, and resource pack chunks.

How Add-on Data Travels Over RakNet

Almost everything you build in a Behavior Pack that has a visual or client-side counterpart must cross the RakNet bridge. When you define an entity in JSON, its identifier, runtime components, and synced Actor Properties (defined under the properties object in your entity description) are serialized into game packets. When a property changes on the server—either through an event response or a Script API call—the server queues an update packet into a reliable RakNet channel so client-side Render Controllers and Animation Controllers can read the new value via Molang.

Resource and Behavior Packs themselves are also transferred directly over the RakNet connection when a player joins a server with required packs enabled. Because RakNet must slice these archives into tiny chunks that fit within the negotiated MTU size (typically around 1200 to 1400 bytes), bloated pack sizes directly delay the player login sequence and saturate the connection queue before the world even finishes loading.

MTU Fragmentation and Script Message Payloads

During the initial handshake, RakNet discovers the largest packet size that can travel between the server and client without being dropped by routers along the path. If an add-on generates a game packet larger than this MTU—even after Bedrock applies compression—RakNet must split the payload into multiple fragments. In Reliable Ordered mode, if a single fragment is lost to network jitter, the client cannot process the packet or any subsequent ordered packets in that channel until the missing fragment is resent.

The most common way add-on developers trigger severe RakNet fragmentation is by sending massive JSON strings through Player.sendMessage, World.sendMessage, or script event payloads. The engine enforces hard byte limits on script messages to prevent buffer overflows, so if your script needs to push large state tables, you must chunk the payload across ticks or compress the keys yourself.

BP/scripts/network_batcher.js
import { system, world } from "@minecraft/server";

const MAX_SAFE_CHARS = 512;
const messageQueue = [];

export function queueLargeStateSync(targetId, payloadObject) {
    const rawJson = JSON.stringify(payloadObject);
    const totalChunks = Math.ceil(rawJson.length / MAX_SAFE_CHARS);

    for (let i = 0; i < totalChunks; i++) {
        const slice = rawJson.slice(i * MAX_SAFE_CHARS, (i + 1) * MAX_SAFE_CHARS);
        messageQueue.push({
            target: targetId,
            header: `${i + 1}/${totalChunks}`,
            body: slice
        });
    }
}

// Drain one chunk per tick to avoid flooding the RakNet reliable queue
system.runInterval(() => {
    if (messageQueue.length === 0) return;
    const nextPacket = messageQueue.shift();
    
    for (const player of world.getAllPlayers()) {
        if (player.id === nextPacket.target) {
            player.sendMessage(`[SYNC:${nextPacket.header}]${nextPacket.body}`);
            break;
        }
    }
}, 1);

Reducing Bandwidth with Entity Properties

Before the introduction of synced entity properties and client_sync options, creators often synced server states to the client by rapidly mutating entity variants, mark_variants, or triggering dummy events every tick. Doing this forces the server to construct and transmit full entity metadata update packets over RakNet, which quickly overwhelms the outbound buffer when dozens of custom entities are active.

When designing entities in modern Bedrock versions, always declare explicit properties in the entity description and set client_sync to true only for values that the Resource Pack genuinely needs to render animations, particles, or geometry changes. Leave server-only tracking variables as Dynamic Properties in script, or set client_sync to false in JSON so they never touch the network stack.

BP/entities/turret.json
{
  "format_version": "1.20.80",
  "minecraft:entity": {
    "description": {
      "identifier": "wiki:turret",
      "is_spawnable": true,
      "is_summonable": true,
      "properties": {
        "wiki:heat_level": {
          "type": "int",
          "range": [0, 100],
          "default": 0,
          "client_sync": true
        },
        "wiki:internal_ammo_count": {
          "type": "int",
          "range": [0, 500],
          "default": 250,
          "client_sync": false
        }
      }
    },
    "components": {
      "minecraft:physics": {},
      "minecraft:health": {
        "value": 40,
        "max": 40
      }
    }
  }
}

Outbound Connections with @minecraft/server-net

It is important to distinguish between the game's internal RakNet traffic and external network requests made by your scripts. Players connect to the server exclusively over RakNet (or WebRTC/NetherNet in certain peer-to-peer multiplayer scenarios), and add-ons have no API to intercept or inject raw RakNet frames into that stream.

If you are building an add-on specifically for Bedrock Dedicated Server (BDS) and need to communicate with an external web backend or database, you use the @minecraft/server-net module. This module operates entirely over standard TCP/HTTP on the server host machine and does not route traffic through the players' RakNet connections.

Which versions this applies to

Applies to all Bedrock Edition versions. Entity properties with client_sync are stable in format_version 1.20.40 and higher without experimental toggles. The @minecraft/server-net module is restricted to Bedrock Dedicated Server and requires explicit permission in server configuration.

When it does not work

What you seeWhyThe fix
Clients are kicked from the server with "Disconnected from Server" or "Packetveneering / Bad Packet" during intense script activity.Your script or command system queued too many reliable updates (such as spawning hundreds of particles individually, spamming sendMessage, or mutating synced entity properties on dozens of entities in a single tick), overflowing the RakNet reliable send buffer.Spread heavy loops across multiple ticks using system.runInterval or generator functions with system.runJob, and disable client_sync on entity properties that do not drive client-side visuals.
Script throws an exception when calling sendMessage or triggering a scriptevent with a large string.The engine enforces strict character and byte limits on individual message payloads before handing them to the network serializer to prevent abusive RakNet packet fragmentation.Break large serialized strings into smaller chunks (under 512 bytes per message) and reassemble them on the receiving end, or store the data server-side using setDynamicProperty instead of transmitting it.
Players get stuck on "Locating Server" or "Downloading Packs" when joining a server with your add-on.Uncompressed textures, high-bitrate OGG audio files, or thousands of tiny JSON files in your Resource Pack are being transferred slice-by-slice over RakNet's ordered channel, causing timeouts on high-latency connections.Compress PNG textures, convert ambient audio to mono at a lower sample rate, remove unused vanilla template files from your pack, and host the pack via an external CDN link in BDS configuration if possible.

Reference, straight from the game files

Read out of the game itself, so the ids match the version you are building for.