Ktor 3.0.0 Help

Choosing an engine

To run a Ktor server application, you need to create and configure a server first. Server configuration includes different settings:

  • an engine for processing network requests;

  • host and port values used to access a server;

  • SSL settings;

  • ... and so on.

Supported engines

The table below lists engines supported by Ktor, along with the supported platforms:

Engine

Platforms

HTTP/2

Netty

JVM

Jetty

JVM

Tomcat

JVM

CIO (Coroutine-based I/O)

JVM, Native, GraalVM

✖️

ServletApplicationEngine

JVM

Add dependencies

Before using the desired engine, you need to add the corresponding dependency to your build script:

  • ktor-server-netty

  • ktor-server-jetty

  • ktor-server-tomcat

  • ktor-server-cio

Below are examples of adding a dependency for Netty:

implementation("io.ktor:ktor-server-netty:$ktor_version")
implementation "io.ktor:ktor-server-netty:$ktor_version"
<dependency> <groupId>io.ktor</groupId> <artifactId>ktor-server-netty-jvm</artifactId> <version>${ktor_version}</version> </dependency>

Choose how to create a server

A Ktor server application can be created and run in two ways: using the embeddedServer to quickly pass server parameters in code, or using EngineMain to load the configuration from the external application.conf or application.yaml file.

embeddedServer

The embeddedServer function accepts an engine factory used to create an engine of a specific type. In the example below, we pass the Netty factory to run a server with the Netty engine and listen on the 8080 port:

package com.example import io.ktor.server.application.* import io.ktor.server.response.* import io.ktor.server.routing.* import io.ktor.server.engine.* import io.ktor.server.netty.* fun main() { embeddedServer(Netty, port = 8080) { routing { get("/") { call.respondText("Hello, world!") } } }.start(wait = true) }

EngineMain

EngineMain represents an engine for running a server. You can use the following engines:

  • io.ktor.server.netty.EngineMain

  • io.ktor.server.jetty.EngineMain

  • io.ktor.server.tomcat.EngineMain

  • io.ktor.server.cio.EngineMain

The EngineMain.main function is used to start a server with the selected engine and loads the application module specified in the external configuration file. In the example below, we start a server from the application's main function:

package com.example import io.ktor.server.application.* import io.ktor.server.response.* import io.ktor.server.routing.* fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args) fun Application.module() { routing { get("/") { call.respondText("Hello, world!") } } }
ktor { deployment { port = 8080 } application { modules = [ com.example.ApplicationKt.module ] } }
ktor: deployment: port: 8080 application: modules: - com.example.ApplicationKt.module

If you need to start a server using a build system task, you need to configure the required EngineMain as the main class:

application { mainClass.set("io.ktor.server.netty.EngineMain") }
mainClassName = "io.ktor.server.netty.EngineMain"
<properties> <main.class>io.ktor.server.netty.EngineMain</main.class> </properties>

Configure an engine

In this section, we'll take a look at how to specify various engine-specific options.

In code

The embeddedServer function allows you to pass engine-specific options using the configure optional parameter. This parameter includes options common for all engines and exposed by the ApplicationEngine.Configuration class.

import io.ktor.server.engine.* import io.ktor.server.netty.* fun main() { embeddedServer(Netty, port = 8080, configure = { connectionGroupSize = 2 workerGroupSize = 5 callGroupSize = 10 shutdownGracePeriod = 2000 shutdownTimeout = 3000 }) { // ... }.start(wait = true) }

In addition to these options, you can configure additional engine-specific properties.

Netty

Netty-specific options are exposed by the NettyApplicationEngine.Configuration class.

import io.ktor.server.engine.* import io.ktor.server.netty.* fun main() { embeddedServer(Netty, configure = { requestQueueLimit = 16 shareWorkGroup = false configureBootstrap = { // ... } responseWriteTimeoutSeconds = 10 }) { // ... }.start(true) }

Jetty

Jetty-specific options are exposed by the JettyApplicationEngineBase.Configuration class.

You can configure the Jetty server inside the configureServer block, which provides access to a Server instance.

Use the idleTimeout property to specify the duration of time a connection can be idle before it gets closed.

import io.ktor.server.engine.* import io.ktor.server.jetty.* fun main() { embeddedServer(Jetty, configure = { configureServer = { // this: Server -> // ... } idleTimeout = 30.seconds }) { // ... }.start(true) }

CIO

CIO-specific options are exposed by the CIOApplicationEngine.Configuration class.

import io.ktor.server.engine.* import io.ktor.server.cio.* fun main() { embeddedServer(CIO, configure = { connectionIdleTimeoutSeconds = 45 }) { // ... }.start(true) }

Tomcat

If you use Tomcat as the engine, you can configure it using the configureTomcat property, which provides access to a Tomcat instance.

import io.ktor.server.engine.* import io.ktor.server.tomcat.* fun main() { embeddedServer(Tomcat, configure = { configureTomcat = { // this: Tomcat -> // ... } }) { // ... }.start(true) }

In a configuration file

If you use EngineMain, you can specify options common for all engines in a configuration file within the ktor.deployment group.

ktor { deployment { connectionGroupSize = 2 workerGroupSize = 5 callGroupSize = 10 shutdownGracePeriod = 2000 shutdownTimeout = 3000 } }
ktor: deployment: connectionGroupSize: 2 workerGroupSize: 5 callGroupSize: 10 shutdownGracePeriod: 2000 shutdownTimeout: 3000

Netty

You can also configure Netty-specific options in a configuration file within the ktor.deployment group:

ktor { deployment { maxInitialLineLength = 2048 maxHeaderSize = 1024 maxChunkSize = 42 } }
ktor: deployment: maxInitialLineLength: 2048 maxHeaderSize: 1024 maxChunkSize: 42
Last modified: 11 October 2023