> Markdown version of [Vaadin Executor](https://vaadin.com/docs/latest/flow/advanced/service-executor). Section index: [llms.txt](https://vaadin.com/docs/latest/flow/llms.txt)

# Vaadin Executor

The Vaadin Executor provides a centralized mechanism for managing asynchronous tasks in Vaadin applications. It offers a configurable thread pool that can be used for executing background operations without blocking the UI thread.

This feature is particularly useful for performing time-consuming operations asynchronously, executing background tasks that should not block the UI, managing concurrent operations efficiently and integrating with framework-specific task execution mechanisms, like Spring `TaskExecutor` or CDI `ManagedExecutor`.

By default, Vaadin creates a thread pool executor with the following configuration:

- Core pool size: 8 threads

- Maximum pool size: Unbounded (Integer.MAX\_VALUE)

- Keep-alive time: 60 seconds for idle threads

- Custom thread factory that creates daemon threads

- Core threads are allowed to time out when idle

This default configuration is suitable for most applications but can be customized as needed.

## <a id="accessing-and-using-the-executor"></a>Accessing and Using the Executor

You can access the executor through the `VaadinService` instance:

```java
Executor executor = VaadinService.getCurrent().getExecutor();

// Execute a task asynchronously
executor.execute(() -> {
    // Your background task here
    myService.longRunningTask();
});

// Execute a task asynchronously using CompletableFuture
CompletableFuture.supplyAsync(myService::longRunningTask, executor)
    .thenAccept(this::handleResult);
```

Code that runs in the executor doesn’t hold the session lock. To update the user interface from it, use signals or the `UI.access()` method, as described in [Pushing UI Updates](https://vaadin.com/docs/latest/building-apps/server-push/updates.md). For guidance on running background jobs and starting tasks from the user interface, see [Background Jobs](https://vaadin.com/docs/latest/building-apps/business-logic/background-jobs.md) and [User Interface Threads](https://vaadin.com/docs/latest/building-apps/server-push/threads.md).

## <a id="configuring-a-custom-executor"></a>Configuring a Custom Executor

In standard Java applications, you can customize the executor by registering a [VaadinServiceInitListener](https://vaadin.com/docs/latest/flow/advanced/service-init-listener.md) and providing your own executor implementation:

`CustomExecutorServiceInitListener.java`

```java
package com.example;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import com.vaadin.flow.server.ServiceInitEvent;
import com.vaadin.flow.server.VaadinServiceInitListener;

public class CustomExecutorServiceInitListener implements VaadinServiceInitListener {
    @Override
    public void serviceInit(ServiceInitEvent event) {
        ThreadPoolExecutor customExecutor = new ThreadPoolExecutor(
            16, // Core pool size
            32, // Maximum pool size
            120, // Keep-alive time
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(),
            r -> {
                Thread thread = new Thread(r, "CustomVaadinExecutor-" + r.hashCode());
                thread.setDaemon(true);
                return thread;
            });

        // Allow core threads to time out
        customExecutor.allowCoreThreadTimeOut(true);

        // Set the custom executor
        event.setExecutor(customExecutor);
    }
}
```

Register your listener using Java’s `ServiceLoader` mechanism by creating a file at `META-INF/services/com.vaadin.flow.server.VaadinServiceInitListener`. The file should contain the fully qualified name of your implementation class: `com.example.CustomExecutorServiceInitListener`

When configuring a custom Thread Pool, consider the following best practices:

- **Core Pool Size**: Set based on the number of concurrent tasks your application typically handles. A good starting point is the number of CPU cores.

- **Maximum Pool Size**: Set to a reasonable upper limit to prevent resource exhaustion. Consider your server’s memory and CPU constraints.

- **Queue Capacity**: Use a bounded queue to prevent memory issues when task submission rate exceeds execution rate.

- Use descriptive thread names to make debugging easier.

- Make threads daemon threads (`Thread.setDaemon(true)`) to prevent them from blocking JVM shutdown.

- Allow core threads to time out if your application has periods of inactivity

For framework integrations, consult the specific documentation pages for [Spring](https://vaadin.com/docs/latest/flow/integrations/spring/configuration.md#configure-custom-vaadin-executor), [CDI](https://vaadin.com/docs/latest/flow/integrations/cdi/service-beans.md#configure-custom-vaadin-executor) and [Quarkus](https://vaadin.com/docs/latest/flow/integrations/quarkus.md#configure-custom-vaadin-executor).

`2EF7B593-E426-479E-89D7-E62667D316C2`
