Backend Development 17 min read

Boost SpringBoot Performance: Monitoring, Profiling, and Optimization Techniques

This guide walks through practical SpringBoot performance improvements, covering metric exposure with Prometheus, flame‑graph profiling via async‑profiler, distributed tracing with SkyWalking, HTTP and Tomcat tuning, and layer‑specific optimizations for controllers, services, and data access.

macrozheng
macrozheng
macrozheng
Boost SpringBoot Performance: Monitoring, Profiling, and Optimization Techniques

1. Monitoring First

Before optimizing a

SpringBoot

service, expose its metrics. Use

Prometheus

as a time‑series database and add the Actuator and Micrometer Prometheus dependencies:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
  <groupId>io.micrometer</groupId>
  <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
  <groupId>io.micrometer</groupId>
  <artifactId>micrometer-core</artifactId>
</dependency>

Enable the endpoints in

application.properties

:

management.endpoint.metrics.enabled=true
management.endpoints.web.exposure.include=*
management.endpoint.prometheus.enabled=true
management.metrics.export.prometheus.enabled=true

After starting, metrics are available at

http://localhost:8080/actuator/prometheus

.

2. Java Flame Graphs

Use

async-profiler

to generate flame graphs. Extract the archive, then run the application with the javaagent:

java -agentpath:/root/build/libasyncProfiler.so=start,svg,file=profile.svg -jar spring-petclinic-2.3.1.BUILD-SNAPSHOT.jar

After stopping the process,

profile.svg

contains a visual hotspot analysis.

3. SkyWalking

Instrument the service with the SkyWalking JavaAgent to collect tracing data. Install the agent, then start the service with:

java -javaagent:/opt/skywalking-agent/skywalking-agent.jar -Dskywalking.agent.service_name=the-demo-name -jar /opt/test-service/spring-boot-demo.jar --spring.profiles.active=dev

Open the SkyWalking UI to locate high‑QPS, slow‑response endpoints for targeted tuning.

4. General Optimization Ideas

A typical request passes DNS, Nginx reverse proxy, and SpringBoot’s embedded Tomcat (MVC) before reaching the database.

5. HTTP Optimizations

Use a CDN for large static assets.

Set appropriate

Cache-Control

and

Expires

headers.

Limit the number of distinct domains per page (ideally ≤4).

Enable gzip compression in Nginx.

Compress JavaScript, CSS, and HTML files.

Enable keep‑alive connections for both client‑Nginx and Nginx‑backend.

location ~* ^.+\.(ico|gif|jpg|jpeg|png)$ {
    # cache 1 year
    add_header Cache-Control: no-cache, max-age=31536000;
}

gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_types text/plain application/javascript text/css;

6. Tomcat Tuning

Adjust thread pool, connection limits, and timeouts via a custom

WebServerFactoryCustomizer

:

@SpringBootApplication(proxyBeanMethods = false)
public class App implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
    @Override
    public void customize(ConfigurableServletWebServerFactory factory) {
        TomcatServletWebServerFactory f = (TomcatServletWebServerFactory) factory;
        f.setProtocol("org.apache.coyote.http11.Http11Nio2Protocol");
        f.addConnectorCustomizers(c -> {
            Http11NioProtocol p = (Http11NioProtocol) c.getProtocolHandler();
            p.setMaxConnections(200);
            p.setMaxThreads(200);
            p.setSelectorTimeout(3000);
            p.setSessionTimeout(3000);
            p.setConnectionTimeout(3000);
        });
    }
}

Switching from Tomcat to Undertow reduces footprint:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

7. Layer‑Specific Optimizations

Controller Layer

Return lightweight DTOs and consider asynchronous servlets to avoid large JSON payloads that increase memory usage.

Service Layer

Keep services stateless, apply appropriate design patterns, and handle distributed transactions carefully; use flexible (BASE) transactions or compensation mechanisms when strict ACID is too costly.

DAO Layer

Leverage caching, avoid eager loading of large associations, and be mindful of sharding‑induced query overhead.

End

We reviewed common SpringBoot performance‑boosting strategies, introduced three profiling tools (Prometheus, flame graphs, SkyWalking), and outlined optimizations at HTTP, container, and code‑level layers. Applying these techniques can significantly improve latency and throughput for Java backend services.

backendJavaMonitoringPerformancespringboot
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login 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.