# Game Server Startup Script Audit & Optimization - Complete Guide

**Status:** Ready to Execute  
**Priority:** Tier 3 - Performance Optimization  
**Time Estimate:** 1 hour (all 11 servers)  
**Last Updated:** 2026-02-17

---

## Overview

Comprehensive audit and optimization of JVM startup flags for all 11 Minecraft servers. Modernize flags, optimize memory allocation, and improve performance using current best practices for Java 17/21.

**Benefits:**
- Reduced lag and improved TPS
- Better garbage collection performance
- Optimized memory usage
- Fewer crashes and OOM errors
- Future-proofed for modern Java versions

---

## Current Server List (11 Servers)

**TX1 Dallas (5 servers):**
1. Vanilla 1.21.11
2. All The Mons
3. Stoneblock 4
4. Society: Sunlit Valley
5. Reclamation

**NC1 Charlotte (6 servers):**
6. The Ember Project
7. Minecolonies: Create and Conquer
8. All The Mods 10
9. Homestead
10. EMC Subterra Tech
11. Hytale (non-Minecraft)

---

## Modern JVM Optimization Strategy

### Java Version Considerations

**For Minecraft 1.20+:** Java 17 or 21 (recommended)  
**For older modpacks:** Java 17 minimum  
**Never use:** Java 8 (outdated, poor performance)

---

## Recommended JVM Flags (2024-2026 Best Practices)

### For Servers with 8-16GB RAM (Most Servers)

```bash
java -Xms8G -Xmx8G \
  -XX:+UseG1GC \
  -XX:+ParallelRefProcEnabled \
  -XX:MaxGCPauseMillis=200 \
  -XX:+UnlockExperimentalVMOptions \
  -XX:+DisableExplicitGC \
  -XX:+AlwaysPreTouch \
  -XX:G1NewSizePercent=30 \
  -XX:G1MaxNewSizePercent=40 \
  -XX:G1HeapRegionSize=8M \
  -XX:G1ReservePercent=20 \
  -XX:G1HeapWastePercent=5 \
  -XX:G1MixedGCCountTarget=4 \
  -XX:InitiatingHeapOccupancyPercent=15 \
  -XX:G1MixedGCLiveThresholdPercent=90 \
  -XX:G1RSetUpdatingPauseTimePercent=5 \
  -XX:SurvivorRatio=32 \
  -XX:+PerfDisableSharedMem \
  -XX:MaxTenuringThreshold=1 \
  -Dusing.aikars.flags=https://mcflags.emc.gs \
  -Daikars.new.flags=true \
  -jar server.jar nogui
```

**These are Aikar's Flags (2024 edition) - proven optimal for Minecraft.**

---

### For ATM10 (16GB+ RAM, Memory-Hungry Modpack)

```bash
java -Xms16G -Xmx16G \
  -XX:+UseG1GC \
  -XX:+ParallelRefProcEnabled \
  -XX:MaxGCPauseMillis=200 \
  -XX:+UnlockExperimentalVMOptions \
  -XX:+DisableExplicitGC \
  -XX:+AlwaysPreTouch \
  -XX:G1NewSizePercent=30 \
  -XX:G1MaxNewSizePercent=40 \
  -XX:G1HeapRegionSize=16M \
  -XX:G1ReservePercent=20 \
  -XX:G1HeapWastePercent=5 \
  -XX:G1MixedGCCountTarget=4 \
  -XX:InitiatingHeapOccupancyPercent=15 \
  -XX:G1MixedGCLiveThresholdPercent=90 \
  -XX:G1RSetUpdatingPauseTimePercent=5 \
  -XX:SurvivorRatio=32 \
  -XX:+PerfDisableSharedMem \
  -XX:MaxTenuringThreshold=1 \
  -Dusing.aikars.flags=https://mcflags.emc.gs \
  -Daikars.new.flags=true \
  -jar server.jar nogui
```

---

### For Vanilla (Lightweight, 4-6GB RAM)

```bash
java -Xms4G -Xmx4G \
  -XX:+UseG1GC \
  -XX:+ParallelRefProcEnabled \
  -XX:MaxGCPauseMillis=200 \
  -XX:+UnlockExperimentalVMOptions \
  -XX:+DisableExplicitGC \
  -XX:+AlwaysPreTouch \
  -XX:G1HeapRegionSize=8M \
  -XX:G1ReservePercent=20 \
  -XX:G1HeapWastePercent=5 \
  -XX:G1MixedGCCountTarget=4 \
  -XX:InitiatingHeapOccupancyPercent=15 \
  -XX:G1MixedGCLiveThresholdPercent=90 \
  -XX:SurvivorRatio=32 \
  -XX:+PerfDisableSharedMem \
  -XX:MaxTenuringThreshold=1 \
  -jar server.jar nogui
```

---

## Flag Explanations

### Memory Allocation

**-Xms and -Xmx (ALWAYS SET EQUAL)**
- `-Xms8G` - Initial heap size
- `-Xmx8G` - Maximum heap size
- **Critical:** Must be equal to avoid heap resizing overhead
- **Rule:** Allocate 80% of available RAM to Minecraft

**Why equal?** Prevents Java from dynamically resizing heap (causes lag spikes)

---

### Garbage Collection (G1GC)

**-XX:+UseG1GC**
- Use G1 Garbage Collector (best for Minecraft)
- Designed for large heaps (>4GB)
- Low pause times
- Better than CMS, ZGC, or Shenandoah for MC

**-XX:MaxGCPauseMillis=200**
- Target max GC pause time: 200ms
- Lower = more frequent but shorter pauses
- 200ms is sweet spot for Minecraft

**-XX:+ParallelRefProcEnabled**
- Process references in parallel
- Reduces GC pause time

---

### G1GC Tuning

**-XX:G1NewSizePercent=30**  
**-XX:G1MaxNewSizePercent=40**
- Young generation size: 30-40% of heap
- Optimized for Minecraft's object creation patterns

**-XX:G1HeapRegionSize=8M (or 16M for large heaps)**
- Size of G1 heap regions
- 8M for <16GB heaps
- 16M for 16GB+ heaps

**-XX:G1ReservePercent=20**
- Reserve 20% of heap to prevent full GC
- Safety margin for allocation spikes

**-XX:InitiatingHeapOccupancyPercent=15**
- Start concurrent GC when heap is 15% full
- Earlier start = smoother collection

---

### Performance Flags

**-XX:+AlwaysPreTouch**
- Pre-touch all memory at startup
- Prevents lazy allocation lag during gameplay

**-XX:+DisableExplicitGC**
- Ignore System.gc() calls from mods
- Prevents mods from triggering GC unnecessarily

**-XX:+PerfDisableSharedMem**
- Disable JVM performance data collection
- Reduces disk I/O

**-XX:MaxTenuringThreshold=1**
- Promote objects to old generation quickly
- Optimized for Minecraft's object lifecycle

---

## Deprecated Flags to REMOVE

**Remove these if found in current startup scripts:**

```bash
# REMOVE - Outdated
-XX:+UseConcMarkSweepGC   # Use G1GC instead
-XX:+CMSParallelRemarkEnabled
-XX:+CMSIncrementalMode
-XX:+CMSClassUnloadingEnabled

# REMOVE - Deprecated in Java 17+
-XX:+AggressiveOpts
-XX:+UseAdaptiveSizePolicy  

# REMOVE - Can cause issues
-XX:+UseStringDeduplication  # Can cause memory leaks
-Xmn (explicit young gen size)  # Let G1 manage it

# REMOVE - Not helpful
-server  # Default in modern Java
```

---

## Server-Specific Recommendations

### Vanilla 1.21.11
**RAM:** 4GB (Xms4G -Xmx4G)  
**Reason:** Vanilla is lightweight  
**Special:** None needed

### All The Mons (Cobblemon)
**RAM:** 8GB (Xms8G -Xmx8G)  
**Reason:** Moderate mod count  
**Special:** None

### Stoneblock 4
**RAM:** 8GB (Xms8G -Xmx8G)  
**Reason:** Skyblock with tech mods  
**Special:** None

### Society: Sunlit Valley
**RAM:** 8GB (Xms8G -Xmx8G)  
**Reason:** Moderate modpack  
**Special:** None

### Reclamation
**RAM:** 8GB (Xms8G -Xmx8G)  
**Reason:** Moderate modpack  
**Special:** None

### The Ember Project
**RAM:** 10GB (Xms10G -Xmx10G)  
**Reason:** Large modpack  
**Special:** None

### Minecolonies: Create and Conquer
**RAM:** 12GB (Xms12G -Xmx12G)  
**Reason:** Minecolonies is RAM-hungry  
**Special:** May need more if colonies grow large

### All The Mods 10 (ATM10)
**RAM:** 16GB (Xms16G -Xmx16G)  
**Reason:** Kitchen sink modpack, very large  
**Special:** G1HeapRegionSize=16M for large heap  
**Note:** Known memory leak - monitor closely

### Homestead
**RAM:** 8GB (Xms8G -Xmx8G)  
**Reason:** Moderate modpack  
**Special:** None

### EMC Subterra Tech
**RAM:** 10GB (Xms10G -Xmx10G)  
**Reason:** Tech-focused modpack  
**Special:** None

---

## Implementation Procedure

### Phase 1: Backup Current Scripts (5 min)

```bash
# On TX1 and NC1
cd /var/lib/pterodactyl/volumes

# Backup all startup scripts
for server in */; do
  if [ -f "${server}start.sh" ]; then
    cp "${server}start.sh" "${server}start.sh.backup.$(date +%Y%m%d)"
  fi
done
```

---

### Phase 2: Update via Pterodactyl Panel (40 min)

**For each server:**

1. Log into panel.firefrostgaming.com
2. Navigate to server
3. Go to **Startup** tab
4. Edit **Java Arguments** field
5. Replace with recommended flags (from above)
6. Click **Save**
7. Restart server
8. Monitor for 10 minutes

**Test checklist per server:**
- Server starts successfully
- Players can join
- TPS remains stable (use `/tps` or `/forge tps`)
- No errors in console
- Memory usage is stable

---

### Phase 3: Monitor Performance (15 min)

**Check after 24 hours:**
- TPS average (should be 19.5-20)
- GC pause times (check logs)
- Memory usage patterns
- Player reports of lag

**Tools:**
- Pterodactyl console
- `/tps` command in-game
- Server logs for GC messages

---

## Pterodactyl Startup Variable

**In Pterodactyl, the startup command looks like:**

```
java {{JAVA_ARGS}} -jar {{SERVER_JARFILE}} nogui
```

**The {{JAVA_ARGS}} variable is where you paste the optimization flags.**

**Example for 8GB server:**

```
-Xms8G -Xmx8G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true
```

---

## Common Issues & Solutions

### Server Won't Start After Update

**Issue:** Server crashes on startup

**Check:**
- RAM allocation doesn't exceed available RAM
- Java version is compatible (17 or 21)
- No typos in flags

**Fix:**
- Restore backup: `start.sh.backup.YYYYMMDD`
- Reduce RAM allocation
- Verify Java version: `java -version`

---

### Worse Performance After Update

**Issue:** TPS lower than before

**Possible causes:**
- RAM allocation too high (swapping to disk)
- G1HeapRegionSize wrong for heap size
- Java version incompatibility

**Fix:**
- Reduce RAM allocation by 2GB
- For <16GB heap, use `G1HeapRegionSize=8M`
- For 16GB+ heap, use `G1HeapRegionSize=16M`

---

### Memory Leaks (ATM10)

**Issue:** Memory usage keeps climbing

**ATM10 specific:** Known memory leak in some versions

**Solution:**
- Increase restart frequency (use staggered restart system)
- Monitor memory usage via Pterodactyl
- Alert when usage hits 90%
- Restart before OOM

---

## Performance Testing

### Before Optimization (Record Baseline)

For each server, record:
- Average TPS (check over 1 hour)
- Memory usage (initial, average, peak)
- GC frequency and pause time
- Player complaints

### After Optimization (Compare)

Same metrics after 24 hours:
- TPS should improve by 0.5-2
- Memory usage should be more stable
- GC pauses should be shorter
- Fewer lag spikes

---

## Documentation Template

**After updating each server, document:**

```
Server: [Name]
Date: 2026-02-17
Previous Flags: [paste old flags]
New Flags: [paste new flags]
RAM: [old] → [new]
Java Version: [version]

Performance:
- TPS Before: X.X
- TPS After: X.X
- Improvement: +X.X TPS
- Notes: [any observations]
```

Save in: `docs/reference/startup-optimization-log.md`

---

## Rollback Procedure

**If optimization causes problems:**

```bash
# Via Pterodactyl panel:
1. Go to Startup tab
2. Restore previous flags from backup
3. Save and restart

# Or via SSH (if needed):
cd /var/lib/pterodactyl/volumes/[uuid]/
mv start.sh.backup.YYYYMMDD start.sh
# Restart via panel
```

---

## Additional Optimizations (Optional)

### CPU Affinity (Advanced)

Pin specific servers to specific CPU cores for better performance:

```bash
taskset -c 0-7 java [flags...] -jar server.jar nogui
```

**Example:** Pin ATM10 to cores 0-15 (first 16 cores)

### Huge Pages (Advanced)

Enable huge pages for better memory performance:

```bash
# Add to JVM flags
-XX:+UseTransparentHugePages
```

---

## References

- **Aikar's Flags:** https://mcflags.emc.gs (official source)
- **G1GC Documentation:** https://docs.oracle.com/en/java/javase/17/gctuning/
- **Minecraft Optimization Guide:** https://github.com/brucethemoose/Minecraft-Performance-Flags-Benchmarks

---

**Fire + Frost + Foundation = Where Love Builds Legacy** 💙🔥❄️

---

**Document Status:** COMPLETE  
**Ready to Execute:** When Pterodactyl panel access available (1 hour)  
**Risk Level:** LOW (easy rollback via backups)  
**Expected Improvement:** +0.5 to +2 TPS per server
