What Is BungeeCord and Why Use It?

BungeeCord is a proxy software that unites multiple Minecraft servers under a single IP. Players connect to one address and move seamlessly between different servers such as lobby, survival and skyblock. A network architecture makes load distribution easier for large servers and gives you a modular setup.

BungeeCord vs Velocity

There are two main alternatives when choosing a proxy: BungeeCord (the classic solution developed by md_5) and Velocity (the modern alternative from the PaperMC team). The table below summarises the key differences:

FeatureBungeeCordVelocity
Developermd_5 / SpigotMCPaperMC
Protocol Support1.8 - 1.21+1.7.2 - 1.21+
Modern ForwardingNo (legacy IP forwarding)Yes (modern forwarding)
Plugin APIBungeeCord APIVelocity API (event-driven)
PerformanceGoodVery good (lower memory use)
Plugin EcosystemVery largeGrowing, but smaller
SecurityVia IPForwardingModern forwarding + secret key
Forge SupportLimitedBetter

Requirements and Preparation

To build a BungeeCord network you need the following minimum requirements:

  • Java 17+ — mandatory for BungeeCord and Paper 1.20+
  • At least 512 MB RAM — for the proxy alone (backend servers are separate)
  • Multiple Minecraft servers on the same machine or the same network
  • Different ports — each backend server must run on a unique port
  • Root/sudo access — required for firewall configuration

Downloading and Installing BungeeCord

You can download BungeeCord from the official Jenkins CI page. Always use the latest build.

Create a directory for the proxy

mkdir -p /opt/network/proxy && cd /opt/network/proxy

Download the BungeeCord JAR

wget -O BungeeCord.jar "https://ci.md-5.net/job/BungeeCord/lastSuccessfulBuild/artifact/bootstrap/target/BungeeCord.jar"

Once downloaded, run it once to generate the config files:

Start BungeeCord (config files are generated)

java -Xms256M -Xmx512M -jar BungeeCord.jar

After the first run, config.yml, locations.yml and the modules folder will have been created. To stop the proxy, type end in the console.

config.yml in Detail

BungeeCord's main configuration file is config.yml. Let us go through each setting in detail:

yaml
server_connect_timeout: 5000
remote_ping_cache: -1
forge_support: true
player_limit: -1
permissions:
  default:
    - bungeecord.command.server
    - bungeecord.command.list
  admin:
    - bungeecord.command.alert
    - bungeecord.command.end
    - bungeecord.command.ip
    - bungeecord.command.reload
timeout: 30000
log_commands: false
network_compression_threshold: 256
online_mode: true
disabled_commands:
  - disabledcommandhere
listeners:
  - query_port: 25577
    motd: '&6KEYDAL Network &7- &aOnline'
    tab_list: GLOBAL_PING
    query_enabled: false
    proxy_protocol: false
    forced_hosts:
      lobby.example.com: lobby
      survival.example.com: survival
    ping_passthrough: false
    priorities:
      - lobby
    bind_local_address: true
    host: 0.0.0.0:25565
    max_players: 500
    tab_size: 60
    force_default_server: true
ip_forward: true
groups:
  admin:
    - egemen
servers:
  lobby:
    motd: '&aLobby Server'
    address: 127.0.0.1:25566
    restricted: false
  survival:
    motd: '&2Survival Server'
    address: 127.0.0.1:25567
    restricted: false
  skyblock:
    motd: '&bSkyblock Server'
    address: 127.0.0.1:25568
    restricted: false

What the Important Settings Do

SettingDefaultDescription
online_modetrueMojang authentication. Must be true for a premium server.
ip_forwardfalseForwards the real IP to backend servers. Always set this to true.
player_limit-1Maximum players. -1 = unlimited.
timeout30000Connection timeout (ms). Increase it for slow connections.
network_compression_threshold256Packet compression threshold (bytes). 256 is optimal.
force_default_serverfalseSet to true and players always land in the lobby.
forge_supporttrueForge client support.
tab_listGLOBAL_PINGTab list mode: GLOBAL, GLOBAL_PING, SERVER.
log_commandsfalseCommand logging. Can be set to true for debugging.

Adding Backend Servers and IP Forwarding

Every backend server (lobby, survival, skyblock and so on) runs as a separate Minecraft server. For those servers to communicate correctly with BungeeCord, IP forwarding has to be configured.

The spigot.yml Setting

Apply this setting in every backend server's spigot.yml file:

yaml
settings:
  bungeecord: true

The server.properties Setting

In every backend server's server.properties file:

properties
online-mode=false
server-port=25566

Forced Hosts and Server Messages

The forced hosts feature lets you route different domain names to different servers. For example, a player connecting to lobby.example.com lands directly on the lobby server.

yaml
forced_hosts:
  lobby.example.com: lobby
  survival.example.com: survival
  skyblock.example.com: skyblock
  mc.example.com: lobby

To use this feature you need DNS records pointing each subdomain to the proxy IP address (an A record or an SRV record).

Security Settings

Network security is one of the most critical topics with BungeeCord. If you do not block direct access to the backend servers, players can bypass the proxy and connect with a spoofed IP.

Closing Ports with a Firewall

Leave the backend server ports (25566, 25567, 25568 and so on) open only to localhost:

Allow localhost access only

iptables -A INPUT -p tcp --dport 25566 -s 127.0.0.1 -j ACCEPT
iptables -A INPUT -p tcp --dport 25566 -j DROP

A simpler method for UFW users:

Close the backend ports to the outside

ufw deny 25566
ufw deny 25567
ufw deny 25568
ufw allow 25565

The IPWhitelist Plugin

If your backend servers run on different machines, you can use the IPWhitelist or BungeeGuard plugin to allow only connections coming from the proxy IP address.

yaml
# BungeeGuard config.yml (install on the backend server)
enabled: true
allowed-tokens:
  - 'PUT-A-RANDOM-TOKEN-HERE'

Checking OnlyProxyJoin

On backend servers the bungeecord: true setting in spigot.yml enables IP forwarding but does not block direct connections. Using a firewall or BungeeGuard on top of it is mandatory.

Performance Optimization

The performance of a BungeeCord proxy depends heavily on correct configuration. The following recommendations matter for high player counts:

  • network_compression_threshold: 256 — the optimal compression threshold. Values that are too low increase CPU usage.
  • timeout: 30000 — you can raise this to 45000 for slow network connections.
  • Java flags: -XX:+UseG1GC -XX:G1HeapRegionSize=4M -XX:+ParallelRefProcEnabled
  • remote_ping_cache: 10000 — caches ping results for 10 seconds, reducing backend load.
  • connection_throttle: 4000 — limits back-to-back connections from the same IP.
bash
#!/bin/bash
# BungeeCord startup script
java -Xms512M -Xmx512M \
  -XX:+UseG1GC \
  -XX:G1HeapRegionSize=4M \
  -XX:+UnlockExperimentalVMOptions \
  -XX:+ParallelRefProcEnabled \
  -XX:MaxGCPauseMillis=200 \
  -jar BungeeCord.jar

Plugin Compatibility

BungeeCord plugins are different from Spigot/Paper plugins. Plugins installed on the proxy side go into its plugins/ folder and operate across the whole network.

PluginTypeDescription
LuckPermsProxy + BackendNetwork-wide permission management
LiteBansProxy + BackendNetwork-wide ban/mute/kick
PremiumVanishProxy + BackendVanish mode, hidden network-wide
GeyserProxyLets Bedrock players connect to a Java server
BungeeTabListPlusProxyCustomisable tab list
ServerListPlusProxyDynamic MOTD and server list
BungeeGuardProxy + BackendSecure connection verification

Common Errors

The "If you wish to use IP forwarding" error

This error appears when the bungeecord: true setting is missing from spigot.yml on a backend server. Check this setting on every backend server.

The "Connection throttled" error

Lower the connection_throttle value in config.yml, or disable it by setting it to -1 (which carries a DDoS risk):

yaml
connection_throttle: 4000  # in ms, -1 = disabled

Players disconnect when switching servers

This problem usually comes from backend servers running different Minecraft versions. Make sure all backend servers are on the same version. Alternatively, you can add multi-version support with the ViaVersion plugin.