Skip to main content
This page covers all JVM-related configuration options for optimizing your Minecraft server’s Java runtime performance.

Memory Configuration

By default, the image declares an initial and maximum Java memory-heap limit of 1 GB. There are several ways to adjust memory settings.

Basic Memory Settings

MEMORY
string
default:"1G"
Sets both initial (Xms) and max (Xmx) memory heap settings of the JVM.Supports formats:
  • Absolute sizes: 1G, 2G, 2048M, 512M
  • Percentages: 50%, 75%
INIT_MEMORY
string
Independently sets the initial heap size (Xms). Overrides MEMORY for initial size.
MAX_MEMORY
string
Independently sets the max heap size (Xmx). Overrides MEMORY for max size.
environment:
  MEMORY: 2G

Percentage-Based Memory

Percentage-based heap sizing allows control over heap size relative to container memory limits without absolute values.
Percentage based heap sizing uses -XX:InitialRAMPercentage for INIT_MEMORY and -XX:MaxRAMPercentage for MAX_MEMORY. See this article for details.

Automatic JVM Memory Calculation

To let the JVM calculate heap size from the container’s declared memory limit, unset MEMORY with an empty value:
docker run -d -e MEMORY="" ...
By default, the JVM will use 25% of the container memory limit as the heap limit.
The settings above only set the Java heap limits. Memory resource requests and limits on the overall container should also account for non-heap memory usage. An extra 25% is a general best practice.

General JVM Options

JVM_OPTS
string
Space-delimited, raw JVM arguments passed to the Minecraft Server invocation. For standard JVM options like -Xmx, -Xms, etc.
JVM_XX_OPTS
string
Space-delimited JVM arguments for -XX options. The JVM requires -XX options to precede -X options.
JVM_DD_OPTS
string
Comma-separated list of name=value or name:value pairs for system properties. Shorthand for passing multiple -D arguments.
docker run -d -e JVM_OPTS="-XsomeJVMOption -DpropName=value" ...

System Properties Shorthand

Instead of passing multiple -D arguments in JVM_OPTS, use JVM_DD_OPTS:
environment:
  JVM_OPTS: -Dfml.queryResult=confirm -Dname=value
The colon syntax is provided for management platforms like Plesk that don’t allow = inside a value.

Optimized JVM Flags

Aikar’s Flags

Aikar’s research provides optimal JVM flags for GC tuning, important for servers with many concurrent users. PaperMC also explains what these flags do.
USE_AIKAR_FLAGS
boolean
default:"false"
Enable Aikar’s optimized GC flags for Minecraft servers.
docker run -d -e USE_AIKAR_FLAGS=true ...
When MEMORY is greater than or equal to 12G, the Aikar flags are automatically adjusted according to the article’s recommendations.

MeowIce’s Flags

MeowIce’s flags are an updated set based on Aikar’s flags with optimizations for Java 17 and above.
USE_MEOWICE_FLAGS
boolean
default:"false"
Enable MeowIce’s optimized JVM flags (Java 17+)
USE_MEOWICE_GRAALVM_FLAGS
boolean
default:"false"
Enable GraalVM-specific optimizations when using MeowIce flags. Only applies when USE_MEOWICE_FLAGS=true.
Example
environment:
  USE_MEOWICE_FLAGS: "true"
  USE_MEOWICE_GRAALVM_FLAGS: "true"

Flare Profiling Flags

Flare is a profiling suite built into Pufferfish/Purpur and available as a plugin for other server types.
USE_FLARE_FLAGS
boolean
default:"false"
Enable JVM flags required for Flare profiling suite
docker run -d -e USE_FLARE_FLAGS=true ...

SIMD Optimization Flags

SIMD (Single Instruction, Multiple Data) operations are supported by Pufferfish and Purpur for performance optimization.
USE_SIMD_FLAGS
boolean
default:"false"
Enable support for optimized SIMD operations
docker run -d -e USE_SIMD_FLAGS=true ...

Remote JMX Monitoring

Enable remote JMX for profiling with tools like VisualVM or Java Mission Control.
ENABLE_JMX
boolean
default:"false"
Enable remote JMX monitoring
JMX_HOST
string
IP/hostname of the Docker host running the container
JMX_PORT
number
default:"7091"
JMX port to expose
docker run -d \
  -e ENABLE_JMX=true \
  -e JMX_HOST=$HOSTNAME \
  -p 7091:7091 \
  itzg/minecraft-server

OpenJ9 Specific Options

The OpenJ9 image tags include specific optimization variables:
TUNE_VIRTUALIZED
boolean
default:"false"
Enable optimization for virtualized environments. OpenJ9 images only.
TUNE_NURSERY_SIZES
boolean
default:"false"
Configure nursery sizes where initial size is 50% of MAX_MEMORY and max size is 80%. OpenJ9 images only.
OpenJ9 Example
environment:
  TUNE_VIRTUALIZED: "true"
  TUNE_NURSERY_SIZES: "true"

Complete Example

compose.yaml
services:
  mc:
    image: itzg/minecraft-server:latest
    environment:
      EULA: "TRUE"
      TYPE: PAPER
      VERSION: "1.20.4"
      
      # Memory Configuration
      INIT_MEMORY: 2G
      MAX_MEMORY: 8G
      
      # Optimized Flags
      USE_AIKAR_FLAGS: "true"
      
      # Additional JVM Options
      JVM_DD_OPTS: "fml.queryResult=confirm"
      
      # JMX Monitoring
      ENABLE_JMX: "true"
      JMX_HOST: ${HOSTNAME}
      
    ports:
      - "25565:25565"
      - "7091:7091"
    volumes:
      - ./data:/data

Best Practices

Memory Allocation: Start with 2-4GB for small servers (1-10 players). Increase to 6-8GB for 10-20 players, and 10-16GB for larger servers.
Aikar’s Flags: Recommended for most production servers running Java 11 or higher. Automatically adjusts for servers with 12GB+ memory.
MeowIce’s Flags: Recommended for Java 17+ servers. Provides better performance than Aikar’s flags on modern Java versions.
Always allocate container resources higher than heap size to account for non-heap memory usage (metaspace, code cache, thread stacks, etc.).

Build docs developers (and LLMs) love