skip to content

Embedded Servers

Boot embeds the server instead of deploying to one: choosing Tomcat, Jetty, Undertow or Netty, tuning it through properties, customizing it programmatically, and terminating TLS. Interviewers ask because thread and connection settings are where load problems start.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

explore

questions

21

What is the default embedded server in a Spring Boot servlet web application, and how does it get there?

level: juniorimportance: must knowfreq 70%

answer

  1. starter-web -> starter-tomcat transitive
  2. TomcatServletWebServerFactory auto-config
  3. embedded = inside JVM, fat JAR
  4. default port 8080
  5. servlet stack default only

basics

~10 s

Embedded Apache Tomcat. When you add spring-boot-starter-web, it transitively pulls in spring-boot-starter-tomcat, so Spring Boot auto-configures and starts an embedded Tomcat on port 8080 by default.

solid answer

~40 s

For a servlet-stack web app (spring-boot-starter-web), the default is embedded Apache Tomcat. The web starter depends on spring-boot-starter-tomcat, which puts Tomcat on the classpath; ServletWebServerFactoryAutoConfiguration then detects it and creates a TomcatServletWebServerFactory, so the app runs a self-contained Tomcat inside the JVM — no external server or WAR deployment needed. It listens on port 8080 unless server.port says otherwise. "Embedded" means the servlet container is a library bundled in your fat JAR and started programmatically in main(), rather than you deploying a WAR into a standalone Tomcat/JBoss. You can override the default by excluding spring-boot-starter-tomcat and adding the Jetty or Undertow starter instead.

code

xml · 8 lines
xml
<!-- Adding this one starter gives you embedded Tomcat by default -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring-boot-starter-web transitively includes spring-boot-starter-tomcat.
     ServletWebServerFactoryAutoConfiguration then builds a
     TomcatServletWebServerFactory and starts Tomcat on port 8080. -->

go deeper

for a junior

Know it's embedded Tomcat on 8080, pulled in by spring-boot-starter-web.

for a middle

Explain the transitive dependency chain and that auto-config builds the factory.

for a senior

Name TomcatServletWebServerFactory / ServletWebServerFactoryAutoConfiguration and the classpath conditions.

for a principal

Frame it as a classpath-driven convention and contrast with reactive/Netty and WebApplicationType inference.

## What an embedded server is **Embedded server** means the HTTP/servlet container runs *inside* your application's JVM process, started from your `main()` method, rather than you packaging a WAR and deploying it into a separately installed application server. Spring Boot's signature move is the "fat JAR" (a.k.a. executable/über JAR): one runnable `.jar` that contains your code, all dependencies, *and* the web server. ## How Tomcat becomes the default 1. When you add the starter `org.springframework.boot:spring-boot-starter-web`, Maven/Gradle transitively pulls in `spring-boot-starter-tomcat`, which brings Tomcat's `tomcat-embed-core` jar onto the classpath. 2. At startup, Spring Boot auto-configuration — specifically `ServletWebServerFactoryAutoConfiguration` and its nested `EmbeddedTomcat` configuration — sees the Tomcat classes on the classpath (via `@ConditionalOnClass`) and no other `ServletWebServerFactory` bean defined, so it creates a `TomcatServletWebServerFactory` bean. 3. That factory builds and starts the embedded Tomcat when the `ServletWebServerApplicationContext` refreshes. Default port is **8080** (change with `server.port`). ## Why Tomcat specifically It is the most battle-tested, widely deployed servlet container; Spring Boot picks it as the safe default. It implements the Jakarta Servlet API (formerly javax.servlet), so it works with the blocking, thread-per-request servlet programming model — Spring MVC (`@Controller`, `DispatcherServlet`). ## Key gotcha — SERVLET vs REACTIVE - The Tomcat default applies to the *servlet* stack (Spring MVC). - If instead you use `spring-boot-starter-webflux` (reactive stack), the default is **Netty**, not Tomcat. The choice is driven by the `WebApplicationType` Spring Boot infers from the classpath. ## When to keep the default Almost always for MVC apps. Only swap it out for a specific reason (async performance, footprint, ops standardization). **Terms defined:** - *Servlet container* = software implementing the Servlet spec (Tomcat/Jetty/Undertow). - *Auto-configuration* = Boot's conditional beans that configure the app based on what's on the classpath. - *Starter* = a curated dependency bundle.

  • What class actually creates the embedded Tomcat, and what condition triggers it?
    ServletWebServerFactoryAutoConfiguration (nested EmbeddedTomcat config) creates a TomcatServletWebServerFactory bean, gated by @ConditionalOnClass on Tomcat classes and no user-defined ServletWebServerFactory bean present.
  • Is Tomcat still the default if you use spring-boot-starter-webflux?
    No. WebFlux is the reactive stack; its default embedded server is Netty (Reactor Netty), not Tomcat.

saying these in an interview costs you the question

  • Thinking you must install and deploy a WAR into an external Tomcat — Boot embeds it
  • Saying the default is Jetty or Netty for a plain MVC app
  • Believing the server is configured by XML rather than auto-configuration

context

open as a page

How do you enable HTTPS/TLS on Spring Boot's embedded web server?

level: juniorimportance: must knowfreq 55%

basics

~10 s

Provide a keystore file and set server.ssl.* properties: server.ssl.key-store (path), server.ssl.key-store-password, server.ssl.key-store-type, and server.ssl.key-alias. Spring Boot configures the embedded server's connector to serve HTTPS on server.port.

open as a page

How do you change the port and base URL path of a Spring Boot app, and what are the defaults?

level: juniorimportance: must knowfreq 78%

basics

~10 s

Set server.port (default 8080) to change the listening port, and server.servlet.context-path (default /) to prefix every URL. Both go in application.properties/application.yml.

open as a page

How do you switch a Spring Boot servlet app from Tomcat to Jetty or Undertow?

level: middleimportance: must knowfreq 60%

basics

~10 s

Exclude spring-boot-starter-tomcat from spring-boot-starter-web, then add spring-boot-starter-jetty (or spring-boot-starter-undertow). Boot's auto-configuration detects the new server on the classpath and uses it instead.

open as a page

Explain `server.tomcat.threads.max` and `server.tomcat.accept-count`. How do they interact under load?

level: middleimportance: must knowfreq 70%

basics

~10 s

threads.max (default 200) is the max worker threads that process requests. accept-count (default 100) is the OS backlog queue of connections waiting when all threads are busy; beyond it, new connections are refused.

open as a page

How does Spring Boot actually apply WebServerFactoryCustomizer beans, and how does ordering interact with property-based configuration?

level: seniorimportance: must knowfreq 27%

basics

~20 s

A WebServerFactoryCustomizerBeanPostProcessor collects all matching customizer beans, sorts them by Ordered/@Order, and calls customize() on the factory during its initialization. Boot's own property-binding customizer has order 0; unordered custom ones run after it, so their setters override properties.

open as a page

What is WebServerFactoryCustomizer in Spring Boot, and when would you use it instead of application.properties?

level: juniorimportance: should knowfreq 38%

basics

~20 s

It's a bean whose customize(factory) method lets you configure the embedded web server (port, context path, error pages, compression) in Java code. Use it when a setting isn't exposed as a server.* property or must be computed at runtime.

open as a page

Using ConfigurableServletWebServerFactory, how do you programmatically set custom error pages and enable response compression?

level: middleimportance: should knowfreq 30%

basics

~10 s

In a WebServerFactoryCustomizer, call factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/404")) for error pages, and build a Compression object (setEnabled(true), mime types, min size) and pass it to factory.setCompression(compression).

open as a page

How do you restrict TLS protocol versions and cipher suites on the embedded server?

level: middleimportance: should knowfreq 35%

basics

~10 s

Use server.ssl.enabled-protocols to whitelist versions (e.g. TLSv1.3, TLSv1.2) and server.ssl.ciphers to whitelist cipher suites. server.ssl.protocol sets the base SSLContext protocol (default TLS).

open as a page

What is WebApplicationType, how does Spring Boot infer it, and how does it govern which server (if any) starts?

level: seniorimportance: should knowfreq 40%

basics

~20 s

WebApplicationType is an enum (SERVLET, REACTIVE, NONE) that tells Spring Boot which kind of application context and web server to create. Boot infers it from the classpath: servlet classes -> SERVLET (Tomcat), only reactive/WebFlux -> REACTIVE (Netty), no web classes -> NONE (no server).

open as a page

For a Spring WebFlux (reactive) application, which embedded server runs by default and why is it different from the servlet stack?

level: seniorimportance: should knowfreq 50%

basics

~20 s

Reactor Netty. WebFlux is a non-blocking, reactive stack that doesn't use the Servlet API, so it can't run on a servlet container's thread-per-request model. Netty's event-loop model fits reactive back-pressure; spring-boot-starter-webflux includes it by default.

open as a page

What are Spring Boot SSL bundles (spring.ssl.bundle) and why use them for the embedded server?

level: seniorimportance: should knowfreq 30%

basics

~10 s

SSL bundles (Spring Boot 3.1+) are named, reusable sets of TLS material and options defined under spring.ssl.bundle.jks.* or .pem.*. The connector references one via server.ssl.bundle=<name>, so the same config is shared and centrally managed.

open as a page

How do you enable hot-reloadable TLS certificates on the embedded server without restarting the app?

level: seniorimportance: should knowfreq 20%

basics

~10 s

Use an SSL bundle and set reload-on-update: true on it (e.g. spring.ssl.bundle.pem.web.reload-on-update). Spring Boot watches the cert/keystore files and rebuilds the embedded connector's SSLContext in place when they change — no restart.

open as a page

What does `server.tomcat.connection-timeout` control, and how does it help defend against slow clients?

level: seniorimportance: should knowfreq 40%

basics

~10 s

server.tomcat.connection-timeout (default 20s) is how long Tomcat waits after accepting a connection for the client to send the request line/headers. If the client is too slow, Tomcat closes the connection, freeing resources.

open as a page

What is `server.tomcat.max-connections` and how does it differ from `threads.max` and `accept-count`?

level: seniorimportance: should knowfreq 52%

basics

~10 s

max-connections (default 8192) caps how many connections Tomcat will accept and hold at once. threads.max (200) caps how many run concurrently; accept-count (100) is the OS backlog once max-connections is reached.

open as a page

How do you configure mutual TLS (client certificate authentication) on the embedded server, and how does it relate to SSL bundles?

level: principalimportance: should knowfreq 22%

basics

~10 s

Set server.ssl.client-auth to NEED (mandatory) or WANT (optional), and supply a truststore of accepted client-CA certificates via server.ssl.trust-store (or a bundle's truststore). The server then requests and validates the client's certificate during the handshake.

open as a page

When and why would you change `server.max-http-request-header-size`, and what are the tradeoffs?

level: principalimportance: should knowfreq 34%

basics

~10 s

server.max-http-request-header-size (default 8KB) caps the total size of incoming HTTP request headers. Raise it when large headers (big JWTs, many cookies) cause 400/431 errors; keep it bounded to avoid memory-abuse attacks.

open as a page

What is the difference between key-store-password and key-password, and PKCS12 vs JKS keystores?

level: middleimportance: nice to knowfreq 22%

basics

~10 s

key-store-password opens the keystore file; key-password unlocks the individual private-key entry inside it. PKCS12 is the modern cross-platform format (Java's default); JKS is the older Java-only format.

open as a page

How would you add a second Tomcat connector (e.g. a plain-HTTP management port alongside HTTPS) using a customizer?

level: seniorimportance: nice to knowfreq 20%

basics

~10 s

Write a WebServerFactoryCustomizer<TomcatServletWebServerFactory>, build a Tomcat Connector (new Connector(...), set its port/protocol), and call factory.addAdditionalTomcatConnectors(connector). The factory's own connector stays the primary; extras are added on top.

open as a page

How does Spring Boot decide which WebServerFactoryCustomizer beans apply to a given factory, and what does the WebServerFactory type hierarchy mean for servlet vs reactive apps?

level: principalimportance: nice to knowfreq 16%

basics

~20 s

Boot reads the customizer's generic type parameter T (via ResolvableType) and applies it only if the factory is assignable to T. Broad types like WebServerFactory match everything; specific types like ReactiveWebServerFactory or TomcatServletWebServerFactory match only their branch.

open as a page

As an architect, how would you decide among Tomcat, Jetty, Undertow, and Netty for a Spring Boot service?

level: principalimportance: nice to knowfreq 28%

basics

~20 s

First decide the programming model: blocking MVC -> a servlet container (Tomcat/Jetty/Undertow); non-blocking WebFlux -> Netty. Among servlet containers, keep Tomcat unless you have a measured reason (footprint, throughput, WebSockets, ops standardization) to pick Undertow or Jetty.

open as a page