Optimizing Performance

1. Enabling HTTP/2 Support

Example: Enable HTTP/2 with TLS

server:
  http2.enabled: true
  ssl.enabled: true     # HTTP/2 requires TLS in browsers
  port: 8443

2. Configuring GZip Compression (server.compression)

Example: Enable GZip compression

server:
  compression:
    enabled: true
    mime-types: application/json,application/xml,text/html,text/css,text/plain
    min-response-size: 1024

3. Using Connection Pooling

Pool Tuning Property
HikariCP (default) spring.datasource.hikari.maximum-pool-size
Hikari idle ...minimum-idle
Hikari leak detection ...leak-detection-threshold
Apache HttpClient PoolingHttpClientConnectionManager
Reactor Netty ConnectionProvider.builder("X").maxConnections(N)

4. Optimizing JPA Queries (N+1 problem)

Warning: N+1 happens when iterating an entity collection triggers a SELECT per associated entity. Use JOIN FETCH, @EntityGraph, or batch fetching.

Example: JOIN FETCH to avoid N+1

@Query("SELECT o FROM Order o JOIN FETCH o.items WHERE o.userId = :uid")
List<Order> findOrdersWithItems(@Param("uid") Long uid);

5. Using Lazy vs Eager Fetching Strategies

Strategy When
LAZY (default for collections, ToMany) Most cases
EAGER (default for ToOne) Always-needed associations only
JOIN FETCH per query Override LAZY at call site

6. Implementing Database Indexing

Example: Composite index on JPA entity

@Entity
@Table(name = "orders", indexes = {
  @Index(name = "idx_orders_user_status", columnList = "user_id, status"),
  @Index(name = "idx_orders_created", columnList = "created_at")
})
public class Order { /* … */ }

7. Using Query Result Caching

Example: Cache service method with Spring Cache

@Cacheable(value = "users", key = "#id")
public UserDto get(Long id) { return repo.findById(id).map(UserDto::from).orElseThrow(); }
// Hibernate L2: spring.jpa.properties.hibernate.cache.use_second_level_cache=true

8. Configuring JVM Memory Settings (-Xmx, -Xms)

Flag Use
-Xms Initial heap (set = -Xmx for prod)
-Xmx Max heap
-XX:MaxMetaspaceSize Metaspace cap
-XX:+UseG1GC G1 GC (default in JDK 17+)
-XX:+UseZGC Low-pause for large heaps
-XX:MaxRAMPercentage=75.0 Container-aware sizing

9. Profiling Application Performance

Tool Use
JFR (Java Flight Recorder) Built-in low-overhead profiling
async-profiler Flame graphs (CPU, allocation)
VisualVM / JProfiler / YourKit Sampling/instrumentation
Spring Boot Actuator /heapdump, /threaddump Snapshots

10. Using @EntityGraph for Fetch Optimization

Example: EntityGraph for eager fetch

@EntityGraph(attributePaths = {"items", "customer"})
@Query("SELECT o FROM Order o WHERE o.id = :id")
Optional<Order> findFullOrder(@Param("id") Long id);

11. Implementing API Response Pagination

Example: Paginated API response

@GetMapping("/orders")
public Page<OrderDto> list(@PageableDefault(size = 50, sort = "createdAt,desc") Pageable p) {
  return repo.findAll(p).map(OrderDto::from);
}

12. Using Async and Non-Blocking Operations

Approach When
@Async + virtual threads Fire-and-forget tasks
WebFlux / Reactor End-to-end non-blocking
Virtual threads (JDK 21) spring.threads.virtual.enabled=true

13. Optimizing Spring Boot Startup Time

Technique Effect
spring.main.lazy-initialization=true Lazy bean creation
AOT compilation (spring-boot:process-aot) Pre-process configs
GraalVM Native Image Sub-second startup
CDS (Class Data Sharing) -XX:ArchiveClassesAtExit
Trim dependencies Fewer auto-configs to evaluate
Actuator /startup Identify slow beans