Why a Spring Boot Application Often Starts Faster with `java -jar` Than from IntelliJ IDEA
It is not unusual for developers to observe a mildly perplexing phenomenon: a Spring Boot application appears to start faster when executed from the command line using java -jar myapp.jar than when launched directly from IntelliJ IDEA. At first glance, this seems counterintuitive. One might reasonably assume that a so-called “uber-jar” (or fat jar), which packages the application alongside all of its dependencies into a single archive, would incur additional overhead during startup—perhaps due to decompression or archive handling.
In practice, the opposite frequently occurs. The explanation lies not in archive extraction, but in classpath topology, runtime instrumentation, and subtle differences in JVM execution environments. Understanding these mechanisms requires a closer look at how Spring Boot launches applications and how the JVM behaves under different conditions.
The Uber-Jar Is Not Fully Extracted
The most common misconception is that running a Spring Boot fat jar involves unzipping the entire archive before the application can start. This assumption is incorrect.
When executing:
java -jar myapp.jar
Spring Boot delegates startup to its own launcher, typically org.springframework.boot.loader.JarLauncher. This launcher does not extract the archive to disk. Instead, it constructs a specialized classloader capable of resolving nested JAR entries directly from within the archive. Classes and resources are loaded lazily, as they are requested by the JVM. The archive is treated as a structured container rather than a compressed bundle that must be fully expanded.
There is, therefore, no significant “unzipping” phase that would systematically slow down execution. If anything, this consolidated packaging can reduce certain filesystem costs.
Classpath Topology and Filesystem Overhead
The most consequential difference between IDE execution and packaged execution is the structure of the classpath.
When running from IntelliJ IDEA, the classpath typically consists of compiled classes located in target/classes (or build/classes) alongside a large number of individual dependency JARs resolved from the local Maven or Gradle cache. It is not uncommon for a moderately sized Spring Boot application to reference several hundred classpath entries.
Each class resolution performed by the JVM may involve filesystem lookups across these numerous locations. On systems where filesystem metadata operations are relatively expensive—such as Windows environments with active antivirus scanning or network-mounted drives—this fragmented classpath structure can introduce measurable overhead during class loading and Spring’s extensive classpath scanning.
By contrast, a fat jar consolidates application classes and dependencies into a single archive. While internally structured, it presents a smaller number of filesystem entry points to the operating system. The reduction in directory traversal and metadata resolution can, in certain environments, lead to faster class discovery and resource loading.
What appears to be additional packaging complexity may in fact simplify the underlying I/O behavior.
The Impact of Debug Agents and IDE Instrumentation
Another frequently overlooked factor is the presence of debugging agents. When an application is launched from IntelliJ IDEA, even in “Run” mode, the JVM is often started with the Java Debug Wire Protocol (JDWP) agent enabled. This typically appears as a -agentlib:jdwp=... argument in the JVM configuration.
The presence of a debug agent subtly alters JVM behavior. The runtime must preserve additional metadata to support breakpoints and step execution. Certain optimizations may be slightly constrained, and class loading can involve additional bookkeeping. While the performance penalty is not dramatic, it is sufficient to influence startup time in non-trivial applications.
When executing java -jar from the command line, the JVM is usually started without any debugging agent attached. The runtime environment is therefore leaner and more representative of production conditions. The absence of instrumentation alone can account for a noticeable reduction in startup duration.
Spring Boot DevTools and Restart Classloaders
A particularly common source of discrepancy is the presence of spring-boot-devtools on the IDE classpath. DevTools is designed to improve developer productivity by enabling automatic restarts and class reloading. To achieve this, it creates a layered classloader arrangement that separates application classes from dependencies and monitors the filesystem for changes.
This restart mechanism introduces additional classloader complexity and file-watching infrastructure. While extremely useful during development, it is not free from a performance standpoint. If DevTools is present when running inside IntelliJ but excluded from the packaged artifact, then the two execution modes are not equivalent. The IDE run effectively includes additional runtime behavior that the fat jar does not.
In many cases, this single difference explains several seconds of startup variance.
JVM Ergonomics and Configuration Differences
Subtle variations in JVM configuration can also contribute to timing differences. IntelliJ may inject specific JVM options, alter heap sizing defaults, or enable particular runtime flags. The command-line invocation, unless explicitly configured, may rely on different ergonomics chosen by the JVM.
Heap size, garbage collector selection, tiered compilation thresholds, and class verification settings can all influence startup time. Spring Boot applications, which perform extensive reflection, annotation processing, and condition evaluation during initialization, are particularly sensitive to classloading and JIT behavior.
Ensuring that both execution paths use identical JVM arguments is essential for a scientifically valid comparison.
Filesystem Caching Effects
Operating system caching further complicates informal measurements. If the application is launched once from the IDE and then immediately launched again using java -jar, the second execution benefits from warmed filesystem caches. JAR contents and metadata may already reside in memory, reducing disk access latency.
Without controlling for caching effects—either by rebooting, clearing caches, or running multiple iterations and averaging results—observed differences may reflect environmental artifacts rather than structural advantages.
Spring Boot Startup Characteristics
It is important to remember that Spring Boot startup is classpath-intensive. The framework performs component scanning, auto-configuration condition evaluation, metadata resolution from META-INF resources, and reflection-based inspection of annotations.
These processes are highly sensitive to classloader behavior and I/O patterns. A consolidated archive can, under certain conditions, reduce the cumulative cost of classpath traversal.
From a systems perspective, fewer filesystem roots and more predictable access patterns can outweigh the negligible overhead of archive handling.
Conclusion: Leaner Runtime, Faster Startup
The faster startup of a Spring Boot application via java -jar is neither anomalous nor paradoxical. It typically reflects a cleaner runtime environment: fewer agents, no development tooling, simplified classpath topology, and production-oriented JVM ergonomics.
The fat jar is not slower because it is not being fully decompressed. On the contrary, its consolidated structure can streamline class loading. Meanwhile, the IDE environment often introduces layers of instrumentation and classloader indirection designed for developer convenience rather than performance parity.
For accurate benchmarking, one must eliminate debugging agents, disable DevTools, align JVM arguments, and control for filesystem caching. Only then can meaningful conclusions be drawn.
In short, the difference is not about packaging overhead. It is about execution context. And in many cases, the command-line invocation more closely resembles the optimized conditions under which the application is intended to run in production.