Home/Learn/Spring Boot/Embedded Servers

Embedded Servers

Beginner
Core & Setup

Spring Boot embeds Tomcat, Jetty, or Undertow directly in the fat JAR, removing the need to deploy WARs to external containers.

Overview

Spring Boot packages an embedded servlet or reactive server (Tomcat, Jetty, Undertow, or Reactor Netty) inside the executable JAR. The application starts with java -jar — no external container required. This simplifies deployment to containers and cloud environments. Tomcat is the default for spring-boot-starter-web; Reactor Netty is the default for spring-boot-starter-webflux. Server configuration (port, SSL, connection pool, timeouts) is controlled via application.properties without any XML.

Server Configuration

Control port, context path, SSL, connection limits, and timeouts via spring.server.* properties. Override defaults for production tuning without changing application code.

Properties — embedded server configuration
# application.properties — embedded server config

# Port and context path
server.port=8080
server.servlet.context-path=/api

# SSL (enable HTTPS)
server.ssl.enabled=true
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-type=PKCS12
server.ssl.key-store-password=${SSL_KEYSTORE_PASSWORD}

# Tomcat-specific tuning
server.tomcat.max-threads=200          # max worker threads
server.tomcat.min-spare-threads=20     # min idle threads
server.tomcat.accept-count=100         # queue length when all threads busy
server.tomcat.connection-timeout=20000 # ms before idle connection dropped

# Undertow-specific
server.undertow.threads.io=4           # IO threads (= CPU cores typically)
server.undertow.threads.worker=32      # worker threads

# HTTP/2 support (requires SSL)
server.http2.enabled=true

# Compression
server.compression.enabled=true
server.compression.mime-types=text/html,text/plain,application/json
server.compression.min-response-size=1024

Programmatic Server Customisation

Implement WebServerFactoryCustomizer<T> to configure the embedded server programmatically when properties are insufficient — e.g. setting custom connectors, error pages, or access log patterns.

Java — WebServerFactoryCustomizer
// Tomcat programmatic customisation
@Component
public class TomcatCustomizer
        implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        factory.addConnectorCustomizers(connector -> {
            connector.setProperty("relaxedQueryChars", "|{}[]");
            connector.setProperty("maxPostSize", String.valueOf(10 * 1024 * 1024)); // 10 MB
        });

        // Access log valve
        AccessLogValve valve = new AccessLogValve();
        valve.setPattern("%h %t "%r" %s %b %D ms");
        valve.setDirectory("/var/log/app");
        factory.addContextValves(valve);
    }
}

// Undertow customisation
@Component
public class UndertowCustomizer
        implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {

    @Override
    public void customize(UndertowServletWebServerFactory factory) {
        factory.addDeploymentInfoCustomizers(info ->
            info.setDefaultEncoding("UTF-8"));
    }
}

Graceful Shutdown

Enable graceful shutdown so in-flight requests complete before the server stops. Configure a timeout after which remaining requests are forcibly terminated. Works with all embedded servers.

Properties — graceful shutdown with Kubernetes
# Enable graceful shutdown (Spring Boot 2.3+)
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=30s
# The server stops accepting new connections immediately on SIGTERM
# Existing requests have 30 seconds to complete before forcible shutdown

# Kubernetes deployment — pair with preStop hook:
# lifecycle:
#   preStop:
#     exec:
#       command: ["sleep", "5"]
# This gives 5 seconds for load balancer to deregister the pod
# before the JVM starts shutting down

// Health check integration — mark DOWN before shutdown
@Bean
public AvailabilityChangeEventPublisher availabilityPublisher(
        ApplicationContext context) {
    return new AvailabilityChangeEventPublisher(context);
}
// Spring automatically publishes ReadinessState.REFUSING_TRAFFIC
// when graceful shutdown starts — signals readiness probe to fail

Key Points to Remember

  • 1Embedded servers (Tomcat/Jetty/Undertow/Netty) are packaged in the JAR — no WAR deployment needed.
  • 2java -jar app.jar is all that's required to start — simplifies cloud/container deployment.
  • 3server.port, server.ssl.*, and server.tomcat.* cover most tuning needs via properties.
  • 4WebServerFactoryCustomizer<T> allows programmatic server configuration beyond properties.
  • 5server.shutdown=graceful lets in-flight requests complete before shutdown.
  • 6HTTP/2 is supported but requires SSL — enable with server.http2.enabled=true.

Interview Questions

Sign in to ask Aria
1

What is an embedded server and why does Spring Boot use one?

EasyTCS
2

How do you change the default port of a Spring Boot application?

EasyInfosys
3

How would you configure SSL/TLS on an embedded Tomcat server?

MediumAmazon
4

What is graceful shutdown and why is it important for Kubernetes deployments?

HardNetflix
5

How do you tune the thread pool size of the embedded Tomcat server?

MediumWipro

Ask Aria about Embedded Servers

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…