After you install a decent modpack, the Forge loading screen becomes a familiar sight — but there is a difference between a normal 3-minute wait and a 15-minute freeze that makes you wonder if something is broken. Most of that extra time is fixable. The fixes range from a single JVM argument to swapping one mod, and none require technical expertise.
This guide covers every working optimization verified for Minecraft Forge 1.21 and 1.21.1, with each fix explained by what it actually does — so you can apply the right one for your situation instead of blindly pasting a stack of flags and hoping for the best.
Version verified: Minecraft Forge 1.21 and 1.21.1, Java 21. Steps also apply to NeoForge 1.21.x.
Why Minecraft Forge Loads Slowly
Forge loading time is not random. Three specific processes account for roughly 85% of total load time, and each one is independently addressable.
Texture atlas stitching (40–60% of load time). Every mod brings its own textures — blocks, items, entities. Forge takes all of them and assembles one massive texture sheet called an atlas. A pack with 60 mods can produce 4,000+ individual PNG files that need to be read, decoded, and packed together. On a spinning hard drive, each file read requires the disk head to seek to a new position. This alone runs to 8–12 minutes on HDDs. The same pack on an NVMe SSD takes under 2 minutes for the same step. Even on fast storage, atlas stitching is the largest single time cost in a typical load.
DataFixerUpper initialization (20–30%). DFU is Minecraft’s built-in world migration system — it handles converting save data from old versions to the current format. The problem is that Minecraft initializes DFU for every possible migration path at startup, not just the ones your world needs. On a fresh install with no old worlds, this pre-computes several hundred migration chains that will never be used. LazyDFU and ModernFix both address this by deferring DFU initialization until it is actually needed, typically saving 30–90 seconds.
Memory pressure and garbage collection (15–25%). Forge loads every mod’s classes, models, and resources into memory simultaneously. If Java runs out of heap during loading, it triggers garbage collection — pausing the entire load process to reclaim memory. This shows up as periods where the loading bar freezes for 5–30 seconds at a stretch. Counterintuitively, over-allocating RAM also causes this: if you give Java 12GB when your pack only needs 6GB, the garbage collector has twice as much memory to scan each time it runs, increasing pause duration.
Understanding which bottleneck you are hitting determines which fix to prioritize. For most players, fixing RAM allocation and JVM arguments alone cuts 30–45% off load time before touching anything else.
Quick Start: 5 Fixes That Cover 80% of Cases
If you only do five things, do these. Combined, they cut load time by 30–50% on most systems:
- Install Java 21 — not 17, not 8 (Step 1)
- Match -Xms to -Xmx and use 4–8GB depending on pack size (Step 2)
- Replace JVM arguments with the G1GC string in Step 3
- Add ModernFix and FerriteCore to your mods folder (Step 4)
- Switch to ATLauncher or Prism Launcher if you are using the CurseForge app (Step 6)
| Player type | Start here | Add if still slow |
|---|---|---|
| Casual — few mods | Steps 1, 2, 3 | Step 4 (ModernFix only) |
| Modpack player (50–150 mods) | Steps 1–4 in order | Steps 5, 6, 7 |
| Modpack builder / heavy pack | All 7 steps | Profile first (Step 5) before Step 7 |
| Server admin | Steps 1, 2, 3 | Step 4 (server-safe mods only) |
Step 1 — Use the Right Java Version
Minecraft 1.21 requires Java 21. This is a hard requirement, not a suggestion — but the reason it matters for loading time goes beyond compatibility.
Java 21’s JIT (Just-In-Time) compiler handles the class-loading patterns Forge uses during startup measurably faster than Java 17. When Forge initializes a large mod, it triggers hundreds of class loads in rapid succession. Java 21’s compiler pipeline handles these bursts more efficiently, particularly the profiling and compilation stages that run while the loading bar is active. On some hardware, switching from Java 17 to Java 21 alone cuts loading time by 10–15%.
The common mistake: most systems default to Java 17, which was the LTS release before Java 21. Forge 1.21 runs on Java 17, but you leave JIT improvements on the table by not upgrading.
Download Eclipse Temurin 21 — a free OpenJDK distribution with no Oracle license strings — from adoptium.net. Install it, then point your launcher to the new executable:
- ATLauncher / Prism Launcher: Edit Instance → Settings → Java → Override Java path
- Official Minecraft Launcher: Installations → More Options → Java executable field
- CurseForge app: Settings → Minecraft → Java Settings → Override Java path
Confirm the switch by checking the launcher log for a line starting with “Java: 21.x.x” during load. If you see “17.x.x”, the override did not save correctly.
Step 2 — Allocate RAM Correctly
The formula that works across pack sizes: 3–4GB per 100 mods, minimum 4GB for any Forge install.
| Pack size | Recommended allocation |
|---|---|
| Forge only (0–10 mods) | 4 GB |
| Light modpack (10–50 mods) | 4–6 GB |
| Medium modpack (50–150 mods) | 6–8 GB |
| Heavy modpack (150–300 mods) | 8–10 GB |
| Mega modpack (300+ mods) | 10–12 GB |
The over-allocation problem. Setting Xmx to 12GB when your pack needs 6GB forces G1GC to scan twice as much memory every time it collects garbage during loading. Each scan shows up as a freeze on the loading bar. This is why bumping RAM from 8GB to 16GB sometimes makes loading slower — more heap means more scanning. Stay within the formula above.
Always match Xms to Xmx. With -Xms4G -Xmx4G, Java allocates all 4GB at launch and never needs to grow the heap during loading. With mismatched values like -Xms512M -Xmx8G, Java starts small and expands incrementally, triggering garbage collection multiple times during the Forge initialization sequence — exactly when pauses hurt most. Set them equal.
System RAM rule: Never allocate more than 50–60% of your total RAM to Java. On a 16GB system, cap at 8–10GB. Windows needs 2–4GB minimum, and the CurseForge Overwolf framework adds another 0.5–1GB on top of that.
Step 3 — Replace Your JVM Arguments
Most launchers default to minimal JVM arguments — sometimes just -Xmx2G. The string below replaces your existing arguments entirely. It is based on Aikar’s flags, battle-tested across thousands of Minecraft installations, with G1GC tuned for Minecraft’s specific memory allocation patterns.
Copy this complete string and paste it into your launcher’s JVM arguments field. Replace -Xmx6G and -Xms6G with your value from Step 2:
-Xmx6G -Xms6G -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=1For packs with 50+ mods, also append: -XX:ReservedCodeCacheSize=400M
What the key flags actually do — the mechanisms behind each:
- -XX:+AlwaysPreTouch: Forces Java to write to every allocated memory page immediately at startup rather than touching pages lazily when first used. Without this, the OS triggers thousands of minor page faults during Forge initialization — each one is microseconds, but thousands sum to several seconds of loading stutter. AlwaysPreTouch costs 2–4 seconds at the very start but eliminates this stutter throughout loading.
- -XX:+DisableExplicitGC: Some mods call System.gc() during their initialization routine, deliberately triggering a full garbage collection at the worst possible time. This flag turns those calls into no-ops without affecting automatic GC.
- -XX:G1HeapRegionSize=8M: Splits the heap into 8MB regions. Forge’s loading pattern creates many large short-lived objects — texture data, serialized class bytecode, resource buffers. Larger regions reduce the frequency of region boundary crossings and speed allocation for these objects.
- -XX:MaxGCPauseMillis=200: Tells G1GC to target pauses under 200ms. Without this, G1 may run 1–3 second pauses that make the loading bar freeze visibly.
- -XX:+ParallelRefProcEnabled: Processes weak and soft references in parallel during GC. Reference processing is normally single-threaded — this change alone can cut GC pause time significantly for large heaps.
- -XX:ReservedCodeCacheSize=400M: Prevents the JIT compiler from evicting compiled code when the cache fills. Forge loads hundreds of classes that the JIT compiles during initialization — without enough code cache, it discards them and recompiles later, burning time twice.
Optional — Shenandoah GC for Java 21 OpenJDK:
If you are running Eclipse Temurin or another OpenJDK build (not Oracle JDK), Shenandoah GC virtually eliminates GC pauses during gameplay at the cost of slightly higher sustained CPU usage. Startup improvement is roughly equivalent to G1GC. Use this instead of the string above, not alongside it:
-Xmx6G -Xms6G -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGuaranteedGCInterval=1000000 -XX:AllocatePrefetchStyle=1Step 4 — Install Performance Mods
These four mods are compatible with 99%+ of Forge modpacks and each targets a different part of the loading pipeline. Install all four unless you hit a specific conflict.
ModernFix (Forge 1.16.5–1.21.4+)
ModernFix redesigns Forge’s model loading system entirely. Instead of loading every block and item model at startup — including models for blocks that may never appear in a world — it switches to dynamic loading that initializes models on demand. Most modpacks load 40–60% faster with ModernFix installed. Packs with 300+ mods see even larger gains. Download: curseforge.com/minecraft/mc-mods/modernfix (190M+ downloads).
FerriteCore (Forge 1.16.5–1.21.x)
Reduces memory usage by 30–60% by optimizing how Minecraft stores block state property maps. A typical 1.16.4 modpack drops from 3.1GB to 1.1–1.2GB after GC with FerriteCore installed. Less memory in use during loading means fewer GC pauses and faster texture processing. Install it on both client and server. Download: curseforge.com/minecraft/mc-mods/ferritecore.
Smooth Boot (1Influence fork for Forge 1.21)
Without Smooth Boot, Forge’s startup task executors spawn every available thread simultaneously at maximum priority. On a 4-core CPU this starves the OS scheduler and the render thread responsible for updating the loading bar — the result is a bar that freezes completely for 30–60 seconds while the CPU is busy. Smooth Boot reconfigures thread count and priority to spread the work more evenly. Download: curseforge.com/minecraft/mc-mods/smooth-boot-1-21 (1Influence fork for 1.21 support).
Fastload (Forge 1.18.2–1.21.x)
While the first three mods improve launcher-to-main-menu time, Fastload cuts the time from clicking Play on a world to actually playing. It optimizes chunk initialization steps that normally run sequentially. Download: curseforge.com/minecraft/mc-mods/fastload.
If you are new to installing mods, see our step-by-step guide to installing Minecraft mods before continuing.
| Situation | Install these mods |
|---|---|
| Fresh Forge, few mods | ModernFix, FerriteCore |
| Medium modpack (50–150 mods) | All four above |
| Heavy modpack (150+ mods) | All four + Embeddium instead of OptiFine |
| Server only (no client mods) | ModernFix and FerriteCore only |
Compatibility note: ModernFix and OptiFine have known conflicts on some 1.21.x builds. If Forge crashes during the Mod Loading phase after installing both, remove OptiFine first and test. FerriteCore and Fastload are compatible with OptiFine.
Step 5 — Find Your Slowest Mod
After applying Steps 1–4, if loading still takes more than 4–5 minutes, a specific mod is almost certainly responsible. The Startup / Loading Profiler mod generates a report showing exactly how long each mod takes to initialize during the Forge loading sequence.
Install it from CurseForge (search “Startup / Loading Profiler” — supports Forge and NeoForge). After your next launch, open the results file in your Minecraft root folder — typically named loading-profile-results.txt or loading-log.log. Look for any mod taking more than 5 seconds. A normal mod initializes in under 2 seconds.
| Mod | Why it is slow | What to do |
|---|---|---|
| Just Enough Items (JEI) | Parses every recipe in the pack during initialization | Normal — inherent to its function. 1–3 min is expected. |
| Biomes O’ Plenty | Large biome and feature registry | Normal for large world-gen mods. No practical fix. |
| Tinkers’ Construct | Tool part and material registry | Normal. LazyDFU helps slightly. |
| Applied Energistics 2 | Crafting and network registry complexity | Normal for AE2. Inherent to the mod’s scope. |
| OptiFine | Shader pipeline + atlas override adds ~2 minutes | Replace with Embeddium + Oculus (see Step 7) |
| Any mod taking 10+ minutes | Likely a conflict or corrupted download | Remove and reinstall from a clean CurseForge download |
If the profiler shows multiple mods each taking 20–30 seconds with no single outlier, the bottleneck is memory pressure. Go back to Step 2 and reduce RAM allocation by 2GB, or verify that FerriteCore is installed and active.
Step 6 — Launcher Choice and Storage
The launcher you use adds overhead that is independent of your mods or JVM settings.
The CurseForge app runs on the Overwolf framework — a second rendering layer that injects into Forge’s process, maintains its own memory management, and consumes system resources that Java cannot reclaim. On low-end systems this adds 20–40 seconds to load time and increases idle RAM usage by 0.5–1GB. This overhead is present whether you use CurseForge’s mod downloader or not.
| Launcher | Load time impact | Why |
|---|---|---|
| ATLauncher | Fastest (baseline) | Minimal framework, direct Java execution, no injected layer |
| Prism Launcher | Equal to ATLauncher | Clean Qt frontend, no injection, fully open source |
| GDLauncher | Slightly slower | More UI overhead but still lean |
| CurseForge app | 10–20% slower | Overwolf injection and persistent background processes |
Migrating from CurseForge to Prism Launcher: In the CurseForge app, right-click your modpack and select Export Profile as a .zip. In Prism Launcher, click Add Instance → Import from zip and select that file. Your mods, configs, and world saves transfer intact.
SSD vs HDD: If your Minecraft installation is on a spinning hard drive, moving it to any SSD — even a budget SATA SSD — cuts atlas-stitching time roughly in half. Forge’s texture loading step reads thousands of small files in rapid succession, a workload that is specifically punishing for HDDs due to their rotational seek time. An NVMe SSD cuts loading time by 40–60% versus HDD on typical modpacks. This is the highest-impact hardware change you can make for Forge loading performance.
For in-game FPS improvements that complement these loading-time fixes, see our Minecraft Java Edition FPS optimization guide.
Step 7 — Remove or Replace OptiFine
OptiFine is one of the most installed Minecraft mods. On Forge 1.21.x it is also one of the most significant contributors to long startup times, adding approximately 2 minutes by performing its own texture atlas pass (duplicating work Forge already did), injecting a custom shader pipeline at launch, and conflicting with ModernFix’s model loader on some builds.
OptiFine made sense when it was the only performance option. In 2026 there are better alternatives for every feature it provides:
- Embeddium — Forge port of Sodium (the gold-standard Fabric renderer). Provides the same rendering improvements as OptiFine’s performance options — better frame rates, reduced draw call overhead — without the startup cost. Compatible with ModernFix and FerriteCore.
- Oculus — Forge shader mod that works alongside Embeddium. Replaces OptiFine shaders without the 2-minute load penalty. Compatible with most popular shader packs including BSL, Complementary, and Sildur’s.
- WI Zoom — If OptiFine’s zoom feature is the only reason you keep it, WI Zoom adds the identical zoom function with zero loading overhead.
Search for all three on CurseForge — they are actively maintained for 1.21.x. If your modpack lists OptiFine as a dependency, check whether a 1.21 version of the pack exists with Embeddium already substituted before assuming OptiFine is mandatory.
For a broader look at which mods are worth adding to any pack, see our Best Minecraft Mods 2026 guide, covering Forge, Fabric, and NeoForge options. If you are choosing a mod loader and considering Fabric for its faster loading, our Forge vs Fabric comparison breaks down the practical loading time differences between the two.
Troubleshooting
Forge takes 15+ minutes on first launch but 3 minutes after that.
Normal behavior. On first launch after installing mods, Forge generates the texture atlas and resource cache files and saves them to disk. These are reused on every subsequent launch. If first-launch time is extreme (30+ minutes), check available disk space — Forge needs roughly 2GB of temporary space during atlas generation. A nearly-full drive forces repeated disk flushes that multiply loading time significantly.
Load times got worse after adding the JVM arguments in Step 3.
Two likely causes: (1) Xmx is too high — reduce by 2GB increments until loading improves; the G1GC flags are tuned for moderate allocations and change behavior at extremes. (2) An unsupported flag for your JVM — some flags like -XX:+UseVectorCmov are unavailable on all JVMs. Start with only the core Aikar’s flags (first line of the string in Step 3), then add the remaining flags one at a time to isolate the problematic one.
The loading bar freezes at the same percentage every time.
A specific mod is failing during initialization and retrying repeatedly. Enable debug logging by adding -Dforge.logging.console.level=debug to your JVM arguments, launch the game, then search the log file for ERROR or WARN entries near the timestamp where the freeze occurs. Common causes: missing mod dependency, version mismatch, or corrupted mod JAR file. Download a fresh copy of the identified mod and replace it.
Forge loads fine but entering a world takes 5+ minutes.
World loading is a separate process from launcher loading. The main causes are chunk pre-generation (first entry to a new world) and biome system initialization from world-generation mods. Install Fastload (Step 4) if you have not already. For dedicated servers, running a chunk pre-generation mod before players connect moves this work to when no one is online rather than on first connection.
OutOfMemoryError despite having 16GB system RAM.
You have allocated too much Java heap. If -Xmx12G is set on a 16GB machine, Windows claims its 2–4GB minimum and background apps claim another 1–2GB — leaving nothing for the OS to breathe. The rule is: never allocate more than 50–60% of total RAM to Java. On 16GB, the recommended maximum is -Xmx8G. Hard ceiling is -Xmx10G.
Forge loads fine but stutters appear every 30–60 seconds in-game.
This is a garbage collection problem, not a loading problem. The JVM flags in Step 3 address it for most players. If stutters persist, install the Spark mod and run /spark gcmonitor to see GC pause frequency and duration in real time. If pauses exceed 200ms regularly, try reducing Xmx by 1–2GB (less heap to scan) or switch to Shenandoah GC (Step 3 optional section).
Frequently Asked Questions
Does having more mods always make loading slower?
Not linearly. Loading time correlates more with registry size than mod count. A pack with 200 cosmetic mods — hats, furniture, decorations — can load faster than a pack with 50 tech and world-gen mods, because registry-heavy mods like JEI, Applied Energistics 2, Tinkers’ Construct, and Biomes O’ Plenty each initialize complex data structures that have no shortcut. Use Loading Profiler (Step 5) to find out which category your pack falls into before assuming mod count is the problem.
Will these fixes affect gameplay performance or only loading time?
Most affect both. The JVM flags in Step 3 reduce in-game GC pauses — the brief freezes you sometimes get while building or exploring are often the same garbage collector that causes loading-bar freezes. ModernFix and FerriteCore reduce memory usage throughout the entire session, not just during loading. Smooth Boot only affects startup. Launcher and storage changes affect only loading and world entry.
I am on NeoForge, not Forge — do these steps work?
Yes. NeoForge is a fork of Forge and uses the same loading pipeline, JVM argument system, and resource loading sequence. All JVM argument fixes apply identically. ModernFix, FerriteCore, Smooth Boot, and Fastload all have dedicated NeoForge versions on CurseForge and Modrinth. Make sure you download the NeoForge variant for 1.21.x, as some mods now package Forge and NeoForge builds separately.
Sources
[1] brucethemoose, “Minecraft Performance Flags Benchmarks” (GitHub): https://github.com/brucethemoose/Minecraft-Performance-Flags-Benchmarks
[2] TheUsefulLists, “Java Arguments Optimization” (GitHub): https://github.com/TheUsefulLists/UsefulMods/blob/main/JavaArgumentsOptimization.md
[3] Minestrator, “How to optimise your server with performance mods (Forge)”: https://minestrator.com/en/blog/article/performances-mods-forge-minecraft-server
[4] Jangro.com, “The Ultimate Guide to Modded Minecraft Performance”: https://jangro.com/post/ultimate-modded-minecraft-performance-guide
[5] Minecraft Forum, “Any way to increase modpack boot speed?”: https://www.minecraftforum.net/forums/mapping-and-modding-java-edition/minecraft-mods/mods-discussion/3128642-any-way-to-increase-modpack-boot-speed
[6] GameTeam, “Minecraft 1.21.1 Server Performance: Optimization Tips”: https://gameteam.io/blog/minecraft-1-21-1-server-performance-optimization-tips/
