How Much Heap Does a Single SpringBoot HTTP Request Really Use?

This article measures the heap memory allocated by a single SpringBoot HTTP and RPC request using JMeter load testing and detailed GC logs, revealing that even tiny payloads can consume around 34 KB of heap, and discusses how request size, logging, and JVM settings affect memory usage and GC frequency.

Architect
Architect
Architect
How Much Heap Does a Single SpringBoot HTTP Request Really Use?

In real work we often need to perform full‑link load testing, tune GC parameters, and optimize JVM memory allocation. By knowing the heap size required for one RPC or HTTP request, we can precisely calculate the total heap needed for a given concurrency and estimate GC frequency.

Experiment Idea

Create a new SpringBoot 2.5.4 application.

Add a POST endpoint for JMeter to call.

Configure a JMeter test plan: each thread performs 2,000 HTTP calls, 10 threads total (20,000 calls).

Enable detailed GC logging in SpringBoot to record memory allocated in the young generation before and after GC.

After the 20,000 HTTP calls, trigger a manual GC and calculate the total young‑generation heap growth from the GC logs (objects are mainly allocated in the young generation).

SpringBoot HTTP Endpoint

@Slf4j
@RestController
public class TestController {

   private AtomicLong count = new AtomicLong(0);

   @ResponseBody
   @RequestMapping(value = "create", method = RequestMethod.POST)
   public String create(@RequestBody Order order) {
       //log.warn("Received order cnt{}:{}", count.getAndIncrement(), order);
       return "ok";
   }

   @ResponseBody
   @RequestMapping(value = "gc", method = RequestMethod.GET)
   public String gc() {
       System.gc();
       return "ok";
   }
}

JMeter Test Plan

3.1 Add Thread Group

Configure 10 threads, each looping 2,000 times.

3.2 Add HTTP Defaults

3.3 Add Request Header

Set Content-Type: application/json because the request body is JSON.

3.4 Add HTTP Request

Specify the URL and request body.

Experiment Execution

4.1 Start SpringBoot Application

Heap size 4 GB, young generation 2 GB. Set SurvivorRatio=8 (each survivor occupies 1/10 of the young generation). Configure GC log output:

-Xloggc:/Users/testUser/log/gc.log
java -server \
 -Xmx4g -Xms4g -XX:SurvivorRatio=8 -Xmn2g \
 -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1g -XX:MaxDirectMemorySize=1g \
 -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCCause -XX:+PrintGCDetails \
 -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution \
 -XX:+UnlockDiagnosticVMOptions -XX:ParGCCardsPerStrideChunk=32768 \
 -XX:+PrintCommandLineFlags -XX:+UseConcMarkSweepGC -XX:+UseParNewGC \
 -XX:ParallelCMSThreads=6 -XX:+CMSClassUnloadingEnabled \
 -XX:+UseCMSCompactAtFullCollection -XX:+CMSParallelInitialMarkEnabled \
 -XX:+CMSParallelRemarkEnabled -XX:+CMSScavengeBeforeRemark -XX:+PrintHeapAtGC \
 -XX:CMSFullGCsBeforeCompaction=1 -XX:CMSInitiatingOccupancyFraction=70 \
 -XX:+UseCMSInitiatingOccupancyOnly -XX:+PrintReferenceGC \
 -XX:+ParallelRefProcEnabled -XX:ReservedCodeCacheSize=256M \
 -Xloggc:/Users/testUser/log/gc.log \
 -jar target/activiti-0.0.1-SNAPSHOT.jar

4.2 Manual GC Before Test

Run curl http://localhost:8080/gc to clear existing objects.

curl http://localhost:8080/gc

4.3 Run JMeter Load Test

Execute the JMeter plan; each run triggers 20,000 HTTP calls.

4.4 GC Log Analysis

After GC, the Eden space usage drops to 0. The pre‑GC Eden size equals the total memory requested by the 20,000 HTTP calls.

Results

Even with a tiny request body (≈50 bytes), each HTTP call allocates about 34 KB of heap memory. This overhead comes from internal object creation within SpringBoot.

When the detail field is expanded to 1,200 characters, the average heap per call rises to ~36 KB, an increase of ~2 KB that roughly matches the payload size.

Adding a log statement inside the controller ( log.warn(...)) raises the average memory per request to 56 KB , an extra 20 KB caused by larger log messages.

Removing the detail field drops the memory usage back to ~35.7 KB, confirming that log size directly impacts heap consumption and can trigger more frequent GC, degrading performance.

Conclusion & Recommendations

For a simple SpringBoot endpoint, a single HTTP request consumes roughly 34 KB of heap, which is a lower bound; real‑world services with complex logic, multiple downstream calls, and extensive logging can easily reach 0.5 MB–1 MB per RPC request.

To keep memory usage and GC pauses under control, limit the size of individual log entries and avoid unnecessary object creation in request handling.

JMeterSpringBootMemoryOptimizationPerformanceTesting
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.