Configuring server timeouts
There are several ways to override the default timeouts at server-side.
Using ServerBuilder
import com.linecorp.armeria.server.Server;
import com.linecorp.armeria.server.ServerBuilder;
import java.time.Duration;
ServerBuilder sb = Server.builder();
Server server = sb.http(port)
.annotatedService(new HelloService())
.requestTimeout(Duration.ofSeconds(5))
.build();
Using VirtualHostBuilder
You can set the timeouts for each virtual host.
import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.server.Server;
import com.linecorp.armeria.server.ServerBuilder;
import java.time.Duration;
import static com.linecorp.armeria.common.HttpStatus.OK;
ServerBuilder sb = Server.builder();
Server server = sb.http(port)
.defaultVirtualHost()
.service("/hello1", (ctx, req) -> HttpResponse.of(OK))
.requestTimeout(Duration.ofSeconds(5))
.and()
.virtualHost("*.foo.com")
.service("/hello2", (ctx, req) -> HttpResponse.of(OK))
.requestTimeout(Duration.ofSeconds(10))
.and()
.withVirtualHost(builder -> {
builder.hostnamePattern("*.bar.com")
.service("/hello3", (ctx, req) -> HttpResponse.of(OK))
.requestTimeout(Duration.ofSeconds(15));
})
.build();
Using ServiceBindingBuilder
You can set the timeouts for each route.
import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.server.Server;
import com.linecorp.armeria.server.ServerBuilder;
import java.time.Duration;
import static com.linecorp.armeria.common.HttpStatus.OK;
ServerBuilder sb = Server.builder();
Server server = sb.http(port)
.route()
.get("/hello1")
.requestTimeout(Duration.ofSeconds(5))
.build((ctx, req) -> HttpResponse.of(OK))
.withRoute(builder -> {
builder.get("/hello2")
.requestTimeout(Duration.ofSeconds(10))
.build((ctx, req) -> HttpResponse.of(OK));
})
.build();
Using ServiceRequestContext
You can use the context to set the timeouts for a request.
import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.server.Server;
import com.linecorp.armeria.server.ServerBuilder;
import java.time.Duration;
import static com.linecorp.armeria.common.HttpStatus.OK;
ServerBuilder sb = Server.builder();
Server server = sb.http(port)
.service("/hello", (ctx, req) -> {
ctx.setRequestTimeout(Duration.ofSeconds(5));
return HttpResponse.of(OK);
})
.build();
Using @RequestTimeout Annotation
You can use the @RequestTimeout annotation for annotated services and gRPC services.
import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.server.ServiceRequestContext;
import com.linecorp.armeria.server.annotation.Get;
import com.linecorp.armeria.server.annotation.decorator.RequestTimeout;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import static com.linecorp.armeria.common.HttpStatus.OK;
@RequestTimeout(value = 10, unit = TimeUnit.SECONDS)
public class HelloService {
@Get("/hello")
@RequestTimeout(5000)
public HttpResponse getHello() {
return HttpResponse.of(OK);
}
}
Handling timeouts for streaming requests
For long-running streaming requests (e.g., gRPC server streaming, bidirectional streaming, or
GraphQL subscriptions), the default request timeout applies to the entire duration of the stream—from
receiving the first message until responseObserver.onCompleted() is called. This means that if your
stream is expected to last longer than the configured request timeout, you must manually extend the
timeout as messages are sent.
You can extend the timeout dynamically using ServiceRequestContext with
EXTEND:
import com.linecorp.armeria.common.util.TimeoutMode;
import com.linecorp.armeria.server.ServiceRequestContext;
import java.time.Duration;
import io.grpc.stub.StreamObserver;
public class MyStreamingService extends MyServiceGrpc.MyServiceImplBase {
@Override
public void streamingOutputCall(Request request,
StreamObserver<Response> responseObserver) {
ServiceRequestContext ctx = ServiceRequestContext.current();
for (int i = 0; i < 100; i++) {
// Simulate processing time
Thread.sleep(500);
// Send a response
responseObserver.onNext(Response.newBuilder().build());
// Extend the timeout with each message sent
ctx.setRequestTimeout(TimeoutMode.EXTEND, Duration.ofSeconds(5));
}
responseObserver.onCompleted();
}
}
You can also extend the timeout reactively when streaming with reactive publishers:
import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.common.util.TimeoutMode;
import com.linecorp.armeria.server.ServiceRequestContext;
import java.time.Duration;
import reactor.core.publisher.Flux;
// Extend timeout with each emitted item
ServerBuilder sb = Server.builder();
sb.service("/streaming", (ctx, req) -> {
Flux<String> publisher =
Flux.interval(Duration.ofMillis(200))
.doOnNext(i -> ctx.setRequestTimeout(TimeoutMode.EXTEND, Duration.ofMillis(500)));
return HttpResponse.of(publisher.take(100).map(i -> "data: " + i + "\n"));
});
Alternatively, for streams with unpredictable duration (e.g., infinite streams or proxy services), you can disable the timeout entirely:
// Disable request timeout for infinite streaming
ServerBuilder sb = Server.builder();
sb.requestTimeoutMillis(0)
.service("/infinite-stream", myStreamingService);
See Timeout control for more details on using
TimeoutMode to dynamically adjust timeouts.
Understanding timeout and cancellation origins
Timeouts and cancellations can originate from either the client or server side, and understanding this is crucial for debugging issues. For detailed information about how timeouts and cancellations propagate between clients and servers, see Understanding timeout and cancellation origins.
Global Configuration
You may globally configure the default timeout with system properties or a custom FlagsProvider.
Using FlagsProvider
You can override the request timeout specified by JVM system properties by implementing your own FlagsProvider and loading it via Java SPI.
package com.example.providers;
// Add the following text file to your classpath or JAR file:
//
// $ cat META-INF/services/com.linecorp.armeria.common.FlagsProvider
// com.example.providers.MyFlagsProvider
//
public class MyFlagsProvider implements FlagsProvider {
@Override
public int priority() {
// The provider with higher value will be evaluated first.
return 100;
}
@Override
public Long defaultRequestTimeoutMillis() {
return 1000L;
}
}
Using JVM system properties
You can override the default server timeouts by specifying the following JVM system properties if you do not prefer setting it programmatically.
-Dcom.linecorp.armeria.defaultRequestTimeoutMillis=<long>
Represents the amount of time from receiving a request to sending the corresponding response completely. Default: 10000.
The JVM system properties have effect only when you did not specify them programmatically.
See Flags for the complete list of JVM system properties in Armeria.