Windows Setup

How to Set Up a Minecraft Server on Windows: A Dev Guide

Tech Setup5 min read
TS

Tech Setup

Reviewed August 1, 2026

How to Set Up a Minecraft Server on Windows: A Dev Guide

Introduction

Running a Minecraft server locally or on a Windows virtual private server (VPS) is a great exercise in network routing, process management, and resource allocation. While Minecraft's underlying Java architecture is straightforward, turning it into a stable, production-grade instance requires configuring JVM flags, managing headless environments, and handling OS-level persistence.

This guide targets developers and power users who want a robust setup. We will bypass the official, resource-heavy graphical server utility and build a lean, command-line-driven Minecraft server on Windows, optimized for performance and availability.


Prerequisites and Environment Preparation

Before downloading binaries, ensure your host environment meets the necessary runtime requirements.

1. Java Development Kit (JDK)

Minecraft Java Edition runs on the Java Virtual Machine (JVM). Modern versions of Minecraft (1.18+) require Java 17. For the latest releases (1.20.x and 1.21.x), Java 21 is mandatory.

Verify your current Java installation via PowerShell:

java -version

If Java is missing or outdated, install the latest OpenJDK (Temurin build by the Eclipse Foundation is recommended for production environments) using winget:

winget install EclipseAdoptium.Temurin.21.JDK

Note: Restart your terminal session after installation to ensure system environment variables (JAVA_HOME and PATH) update correctly.

2. Network Topology and Static IPs

To allow external connections, your host machine needs a static local IP address. If you are hosting on a home network, you will also need to configure port forwarding later.

Identify your current network configuration:

ipconfig

Note your IPv4 Address and Default Gateway for your router configuration step.


Step 1: Directory Structure and Server Binaries

As a best practice, isolate your server files in a dedicated directory rather than running them from user downloads or temporary folders.

  1. Open PowerShell and create a dedicated workspace:
mkdir C:\minecraft-server
cd C:\minecraft-server
  1. Download the official server .jar file. You can automate this using curl:
# Replace the URL with the specific version jar you require
Invoke-WebRequest -Uri "https://piston-data.mojang.com/v1/objects/c9df48efed58511c60f10629ae994d6345482270/server.jar" -OutFile "server.jar"

(Always fetch the direct download link for the exact Minecraft version from the official launcher or reliable mirrors).


Step 2: Initializing and Accepting the EULA

Running the server jar for the first time will generate the necessary configuration files, including the End User License Agreement (EULA).

Execute the jar via the command line to generate files:

java -Xmx1024M -Xms1024M -jar server.jar nogui

You will notice the process terminates immediately, generating several files in C:\minecraft-server, most notably eula.txt. Mojang requires explicit consent to their EULA before the server engine will spin up.

Open eula.txt in your text editor of choice (e.g., Notepad or VS Code):

code eula.txt

Change the boolean flag from false to true:

#By changing the setting below to TRUE you are indicating your agreement to our EULA (https://aka.ms/MinecraftEULA).
#Sat Oct 14 12:00:00 UTC 2023
eula=true

Save and close the file.


Step 3: Crafting the Startup Script

Running Minecraft with default JVM memory flags leads to garbage collection (GC) stutters and eventual out-of-memory crashes as chunk generation scales. We need to allocate a dedicated heap and tune the Garbage Collector.

Create a file named start.bat in your server root directory:

New-Item -ItemType File -Name "start.bat"

Populate start.bat with optimized JVM flags. This configuration allocates 6GB of RAM (adjust -Xmx and -Xms based on your total system RAM and expected player load) and utilizes the G1 Garbage Collector, which is heavily optimized for low-latency server environments:

@echo off
REM === Minecraft Server Startup Script ===

:: Set window title for process identification
title Minecraft Server

:: Java executable path (leave as 'java' if added to system PATH)
set JAVA="java"

:: Memory Allocation (e.g., 6G minimum and maximum)
set MIN_RAM=6G
set MAX_RAM=6G

:: JVM Flags for G1GC Optimization
set JVM_OPTS=-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4

%JAVA% -Xms%MIN_RAM% -Xmx%MAX_RAM% %JVM_OPTS% -jar server.jar nogui

pause

Save the batch file. Run it manually once to verify the server spins up cleanly and generates the world, logs, and plugins (if running Paper/Spigot) directories. Type stop in the console to safely shut down the instance.


Step 4: Configuring server.properties

The core configuration file for your server is server.properties. Open it to tune gameplay mechanics, networking, and performance parameters.

code server.properties

Key properties to modify for a robust developer or private setup:

PropertyRecommended ValueDescription
server-port25565Default listening port. Change if running multiple instances.
max-players20Adjust based on your hardware constraints.
view-distance10 to 12Higher values increase CPU/RAM load and network bandwidth.
simulation-distance8Keeps tick processing close to players, saving vital CPU cycles.
online-modetrueSet to false only if running an offline/LAN network behind a proxy like Velocity/BungeeCord.
enable-rcontrueEssential for remote administration and automated scripting.
white-listtrueRestricts access to authorized UUIDs only.

Step 5: Network Configuration and Port Forwarding

If your server is hosted on a local machine and you want external players to connect, you must configure network ingress.

Windows Defender Firewall Rule

By default, Windows blocks incoming connections on arbitrary ports. Create an inbound rule to allow traffic on port 25565:

Open PowerShell as Administrator and run:

New-NetFirewallRule -DisplayName "Minecraft Server Inbound" -Direction Inbound -LocalPort 25565 -Protocol TCP -Action Allow

Router Port Forwarding

  1. Log into your local router's administration panel (using your Default Gateway IP).
  2. Navigate to the Port Forwarding or Virtual Server section.
  3. Forward external port 25565 (TCP and UDP) to your server's static internal IPv4 address on port 25565.
  4. Retrieve your public IP address (via curl ifconfig.me) to share with remote users.

Step 6: Advanced Production Setup (Running as a Windows Service)

Relying on an interactive PowerShell window or batch script means the server dies if the user logs out. For production environments, run the Minecraft server as a background Windows Service using NSSM (Non-Sucking Service Manager).

  1. Install NSSM via winget:
winget install NSSM.NSSM
  1. Launch the graphical service configuration utility:
nssm install MinecraftServer
  1. In the NSSM configuration GUI:

    • Path: C:\Program Files\Eclipse Adoptium\jdk-21.x.x\bin\java.exe (or your absolute java path)
    • Startup directory: C:\minecraft-server
    • Arguments: -Xmx6G -Xms6G -XX:+UseG1GC -jar server.jar nogui
  2. Click Install service.

You can now manage the server lifecycle natively via PowerShell:

# Start the server silently in the background
Start-Service MinecraftServer

# Check service status
Get-Service MinecraftServer

# Stop the server safely
Stop-Service MinecraftServer

Step 7: Automated Backups via PowerShell

Data corruption during chunk saves or unexpected crashes can ruin worlds. Implement a scheduled backup script using Windows Task Scheduler and PowerShell.

Create a script named backup.ps1 in C:\scripts\backup.ps1:

$SourceDir = "C:\minecraft-server\world"
$BackupDir = "C:\minecraft-backups"
$Timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm"
$Destination = "$BackupDir\world_$Timestamp.zip"

if (!(Test-Path $BackupDir)) {
    New-Item -ItemType Directory -Path $BackupDir
}

# Safely issue a save-off command via RCON if configured, or zip directly for local testing
Compress-Archive -Path $SourceDir -DestinationPath $Destination -CompressionLevel Optimal

# Retention policy: Delete backups older than 7 days
Get-ChildItem -Path $BackupDir -Filter "*.zip" | Where-Object { $_.CreationTime -lt (Get-Date).AddDays(-7) } | Remove-Item

Write-Host "Backup completed successfully: $Destination"

To automate this hourly or daily, register it as a Windows Scheduled Task via PowerShell:

$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-ExecutionPolicy Bypass -File C:\scripts\backup.ps1"
$Trigger = New-ScheduledTaskTrigger -Daily -At 3AM
Register-ScheduledTask -TaskName "MinecraftDailyBackup" -Action $Action -Trigger $Trigger

Verification and Monitoring

With your server up and running, verify operational health:

  1. Check Logs: Inspect the latest log outputs in C:\minecraft-server\logs\latest.log for memory warnings, slow tick rates (Can't keep up! Is the server overloaded?), or plugin loading errors.
  2. Client Connection: Open Minecraft Java Edition, navigate to Multiplayer -> Add Server, and input your local IP (or 127.0.0.1 if testing locally) or public IP.
  3. Resource Utilization: Monitor JVM heap usage using Windows Task Manager or Resource Monitor to ensure your -Xmx allocations match actual system loads under stress.