diff --git a/documentation/en/user/source/production/index.rst b/documentation/en/user/source/production/index.rst
index 8d396d662..d2c4e358a 100644
--- a/documentation/en/user/source/production/index.rst
+++ b/documentation/en/user/source/production/index.rst
@@ -102,6 +102,33 @@ Resource Allocation
Also see https://github.com/GeoWebCache/geowebcache/wiki/Estimating-the-number-of-tiles-and-size-on-disk for table that can be used to estimate how much storage you need and how long seeding will take
+Seeder thread pool configuration
+++++++++++++++++++++++++++++++
+
+The number of concurrent seed tasks that GeoWebCache can execute is controlled by an internal
+thread pool. You can configure its sizes using environment variables (values shown are
+defaults used when variables are not set):
+
+- ``GWC_SEEDER_CORE_POOL_SIZE``: core pool size, defaults to ``16``
+- ``GWC_SEEDER_MAX_POOL_SIZE``: maximum pool size, defaults to ``32``
+
+Example (Linux/macOS):
+
+.. code-block:: bash
+
+ export GWC_SEEDER_CORE_POOL_SIZE=8
+ export GWC_SEEDER_MAX_POOL_SIZE=16
+ # start your servlet container / GeoWebCache here
+
+On Windows (PowerShell):
+
+.. code-block:: powershell
+
+ $Env:GWC_SEEDER_CORE_POOL_SIZE = "8"
+ $Env:GWC_SEEDER_MAX_POOL_SIZE = "16"
+ # start your servlet container / GeoWebCache here
+
+These settings control the pool used to run seed tasks.
Clustering
----------
diff --git a/geowebcache/core/src/test/java/org/geowebcache/seed/SeederThreadPoolExecutorConfigurationTest.java b/geowebcache/core/src/test/java/org/geowebcache/seed/SeederThreadPoolExecutorConfigurationTest.java
new file mode 100644
index 000000000..8e9fb98b9
--- /dev/null
+++ b/geowebcache/core/src/test/java/org/geowebcache/seed/SeederThreadPoolExecutorConfigurationTest.java
@@ -0,0 +1,152 @@
+/**
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General
+ * Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ *
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ *
You should have received a copy of the GNU Lesser General Public License along with this program. If not, see
+ * .
+ */
+package org.geowebcache.seed;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.EnvironmentVariables;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+/**
+ * Test class to verify that the SeederThreadPoolExecutor configuration properly reads environment variables for core
+ * pool size and maximum pool size.
+ */
+public class SeederThreadPoolExecutorConfigurationTest {
+
+ /** Allows to set environment variables for each individual test */
+ @Rule
+ public final EnvironmentVariables environmentVariables = new EnvironmentVariables();
+
+ private ApplicationContext applicationContext;
+
+ @After
+ public void tearDown() {
+ if (applicationContext != null) {
+ ((ClassPathXmlApplicationContext) applicationContext).close();
+ }
+ }
+
+ /** Test that default values are used when environment variables are not set. */
+ @Test
+ public void testDefaultValuesWhenEnvironmentVariablesNotSet() {
+ // Clear any existing environment variables
+ environmentVariables.clear("GWC_SEEDER_CORE_POOL_SIZE");
+ environmentVariables.clear("GWC_SEEDER_MAX_POOL_SIZE");
+
+ // Load the Spring context with test configuration
+ applicationContext = new ClassPathXmlApplicationContext("seeder-thread-pool-test-context.xml");
+
+ // Get the seeder thread pool executor bean
+ SeederThreadPoolExecutor executor =
+ applicationContext.getBean("gwcSeederThreadPoolExec", SeederThreadPoolExecutor.class);
+
+ // Verify default values are used
+ assertEquals("Core pool size should default to 16", 16, executor.getCorePoolSize());
+ assertEquals("Maximum pool size should default to 32", 32, executor.getMaximumPoolSize());
+
+ // Clean up
+ executor.shutdown();
+ }
+
+ /** Test that custom environment variable values are properly loaded. */
+ @Test
+ public void testCustomEnvironmentVariableValues() {
+ // Set custom environment variables
+ environmentVariables.set("GWC_SEEDER_CORE_POOL_SIZE", "8");
+ environmentVariables.set("GWC_SEEDER_MAX_POOL_SIZE", "16");
+
+ // Load the Spring context with test configuration
+ applicationContext = new ClassPathXmlApplicationContext("seeder-thread-pool-test-context.xml");
+
+ // Get the seeder thread pool executor bean
+ SeederThreadPoolExecutor executor =
+ applicationContext.getBean("gwcSeederThreadPoolExec", SeederThreadPoolExecutor.class);
+
+ // Verify custom values are used
+ assertEquals("Core pool size should be set to 8", 8, executor.getCorePoolSize());
+ assertEquals("Maximum pool size should be set to 16", 16, executor.getMaximumPoolSize());
+
+ // Clean up
+ executor.shutdown();
+ }
+
+ /** Test that only one environment variable is set (partial configuration). */
+ @Test
+ public void testPartialEnvironmentVariableConfiguration() {
+ // Set only core pool size environment variable
+ environmentVariables.set("GWC_SEEDER_CORE_POOL_SIZE", "12");
+ environmentVariables.clear("GWC_SEEDER_MAX_POOL_SIZE");
+
+ // Load the Spring context with test configuration
+ applicationContext = new ClassPathXmlApplicationContext("seeder-thread-pool-test-context.xml");
+
+ // Get the seeder thread pool executor bean
+ SeederThreadPoolExecutor executor =
+ applicationContext.getBean("gwcSeederThreadPoolExec", SeederThreadPoolExecutor.class);
+
+ // Verify mixed configuration
+ assertEquals("Core pool size should be set to 12", 12, executor.getCorePoolSize());
+ assertEquals("Maximum pool size should default to 32", 32, executor.getMaximumPoolSize());
+
+ // Clean up
+ executor.shutdown();
+ }
+
+ /** Test that invalid environment variable values fall back to defaults. */
+ @Test
+ public void testInvalidEnvironmentVariableValues() {
+ // Set invalid environment variables
+ environmentVariables.set("GWC_SEEDER_CORE_POOL_SIZE", "invalid");
+ environmentVariables.set("GWC_SEEDER_MAX_POOL_SIZE", "not_a_number");
+
+ // Load the Spring context with test configuration
+ applicationContext = new ClassPathXmlApplicationContext("seeder-thread-pool-test-context.xml");
+
+ // Get the seeder thread pool executor bean
+ SeederThreadPoolExecutor executor =
+ applicationContext.getBean("gwcSeederThreadPoolExec", SeederThreadPoolExecutor.class);
+
+ // Verify default values are used when invalid values are provided
+ assertEquals("Core pool size should default to 16 when invalid value provided", 16, executor.getCorePoolSize());
+ assertEquals(
+ "Maximum pool size should default to 32 when invalid value provided",
+ 32,
+ executor.getMaximumPoolSize());
+
+ // Clean up
+ executor.shutdown();
+ }
+
+ /** Test that the SeederThreadPoolExecutor can be created with various configurations. */
+ @Test
+ public void testSeederThreadPoolExecutorCreation() {
+ // Test with different pool sizes
+ SeederThreadPoolExecutor executor1 = new SeederThreadPoolExecutor(4, 8);
+ assertEquals("Core pool size should be 4", 4, executor1.getCorePoolSize());
+ assertEquals("Maximum pool size should be 8", 8, executor1.getMaximumPoolSize());
+ executor1.shutdown();
+
+ SeederThreadPoolExecutor executor2 = new SeederThreadPoolExecutor(1, 1);
+ assertEquals("Core pool size should be 1", 1, executor2.getCorePoolSize());
+ assertEquals("Maximum pool size should be 1", 1, executor2.getMaximumPoolSize());
+ executor2.shutdown();
+
+ SeederThreadPoolExecutor executor3 = new SeederThreadPoolExecutor(64, 128);
+ assertEquals("Core pool size should be 64", 64, executor3.getCorePoolSize());
+ assertEquals("Maximum pool size should be 128", 128, executor3.getMaximumPoolSize());
+ executor3.shutdown();
+ }
+}
diff --git a/geowebcache/core/src/test/resources/seeder-thread-pool-test-context.xml b/geowebcache/core/src/test/resources/seeder-thread-pool-test-context.xml
new file mode 100644
index 000000000..f226d12e5
--- /dev/null
+++ b/geowebcache/core/src/test/resources/seeder-thread-pool-test-context.xml
@@ -0,0 +1,21 @@
+
+
+
+
+ Test configuration for SeederThreadPoolExecutor with environment variables
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/geowebcache/web/src/main/webapp/WEB-INF/geowebcache-core-context.xml b/geowebcache/web/src/main/webapp/WEB-INF/geowebcache-core-context.xml
index d1845c40f..107fc34f2 100644
--- a/geowebcache/web/src/main/webapp/WEB-INF/geowebcache-core-context.xml
+++ b/geowebcache/web/src/main/webapp/WEB-INF/geowebcache-core-context.xml
@@ -183,8 +183,8 @@
-
-
+
+