diff --git a/patches/server/0061-CPU-cores-estimation.patch b/patches/server/0060-CPU-cores-estimation.patch
similarity index 100%
rename from patches/server/0061-CPU-cores-estimation.patch
rename to patches/server/0060-CPU-cores-estimation.patch
diff --git a/patches/server/0062-Add-centralized-AsyncExecutor.patch b/patches/server/0061-Add-centralized-AsyncExecutor.patch
similarity index 77%
rename from patches/server/0062-Add-centralized-AsyncExecutor.patch
rename to patches/server/0061-Add-centralized-AsyncExecutor.patch
index f7b84f2..c5f5634 100644
--- a/patches/server/0062-Add-centralized-AsyncExecutor.patch
+++ b/patches/server/0061-Add-centralized-AsyncExecutor.patch
@@ -7,14 +7,16 @@ License: AGPL-3.0 (https://www.gnu.org/licenses/agpl-3.0.html)
diff --git a/src/main/java/org/galemc/gale/concurrent/AsyncExecutor.java b/src/main/java/org/galemc/gale/concurrent/AsyncExecutor.java
new file mode 100644
-index 0000000000000000000000000000000000000000..00b8d5e54b822c114583edd9b0ff6d59e76e15d7
+index 0000000000000000000000000000000000000000..de182b9473963b95085fa612f70884a56765ae43
--- /dev/null
+++ b/src/main/java/org/galemc/gale/concurrent/AsyncExecutor.java
-@@ -0,0 +1,92 @@
+@@ -0,0 +1,103 @@
+// Gale - centralized async execution
+
+package org.galemc.gale.concurrent;
+
++import com.google.common.util.concurrent.ThreadFactoryBuilder;
++import net.minecraft.Util;
+import org.galemc.gale.util.CPUCoresEstimation;
+
+import java.util.concurrent.BlockingQueue;
@@ -25,7 +27,8 @@ index 0000000000000000000000000000000000000000..00b8d5e54b822c114583edd9b0ff6d59
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
-+ * An executor for tasks that can run asynchronously.
++ * An executor for tasks that can run asynchronously. This executor uses a fixed thread pool, and as such
++ * is not appropriate for tasks that block.
+ *
+ * It can be paused when all CPU cores may be needed for something else.
+ *
@@ -41,7 +44,11 @@ index 0000000000000000000000000000000000000000..00b8d5e54b822c114583edd9b0ff6d59
+ *
+ * This value is at least 1.
+ */
-+ public static final int parallelism = Math.max(1, Integer.getInteger("gale.threads.async", CPUCoresEstimation.get() - 2));
++ public static final int parallelism;
++ static {
++ int parallelismByEnvironmentVariable = Integer.getInteger("gale.threads.async", -1);
++ parallelism = Math.max(1, parallelismByEnvironmentVariable > 0 ? parallelismByEnvironmentVariable : CPUCoresEstimation.get() - 2);
++ }
+
+ /**
+ * The queue of tasks in the {@link AsyncExecutor} singleton instance.
@@ -54,12 +61,16 @@ index 0000000000000000000000000000000000000000..00b8d5e54b822c114583edd9b0ff6d59
+ */
+ public static final AsyncExecutor instance = new AsyncExecutor();
+
-+ private static volatile boolean isPaused = true;
++ private static volatile boolean isPaused = false;
+ private static final ReentrantLock pauseLock = new ReentrantLock();
+ private static final Condition pauseCondition = pauseLock.newCondition();
+
+ private AsyncExecutor() {
-+ super(parallelism, parallelism, 0L, TimeUnit.MILLISECONDS, queue);
++ super(parallelism, parallelism, 0L, TimeUnit.MILLISECONDS, queue, new ThreadFactoryBuilder()
++ .setNameFormat("Async Executor Thread - %1$d")
++ .setPriority(Thread.NORM_PRIORITY - 1) // Deprioritize over main
++ .setUncaughtExceptionHandler(Util::onThreadException)
++ .build());
+ }
+
+ @Override
diff --git a/patches/server/0062-Remove-Paper-async-executor.patch b/patches/server/0062-Remove-Paper-async-executor.patch
new file mode 100644
index 0000000..a953e18
--- /dev/null
+++ b/patches/server/0062-Remove-Paper-async-executor.patch
@@ -0,0 +1,68 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: MartijnMuijsers
+Date: Tue, 29 Nov 2022 13:10:20 +0100
+Subject: [PATCH] Remove Paper async executor
+
+License: AGPL-3.0 (https://www.gnu.org/licenses/agpl-3.0.html)
+
+diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java
+index 1e812c4f5a8d54293084de29e8731e0b8ddcc0ae..06507695eb53067b0da9cb66e4d443f21cb6f070 100644
+--- a/src/main/java/io/papermc/paper/util/MCUtil.java
++++ b/src/main/java/io/papermc/paper/util/MCUtil.java
+@@ -34,6 +34,7 @@ import org.bukkit.Location;
+ import org.bukkit.block.BlockFace;
+ import org.bukkit.craftbukkit.CraftWorld;
+ import org.bukkit.craftbukkit.util.Waitable;
++import org.galemc.gale.concurrent.AsyncExecutor;
+ import org.spigotmc.AsyncCatcher;
+
+ import javax.annotation.Nonnull;
+@@ -45,6 +46,7 @@ import java.util.Queue;
+ import java.util.Set;
+ import java.util.concurrent.CompletableFuture;
+ import java.util.concurrent.ExecutionException;
++import java.util.concurrent.Executor;
+ import java.util.concurrent.LinkedBlockingQueue;
+ import java.util.concurrent.ThreadPoolExecutor;
+ import java.util.concurrent.TimeUnit;
+@@ -55,14 +57,7 @@ import java.util.function.Consumer;
+ import java.util.function.Supplier;
+
+ public final class MCUtil {
+- public static final ThreadPoolExecutor asyncExecutor = new ThreadPoolExecutor(
+- 0, 2, 60L, TimeUnit.SECONDS,
+- new LinkedBlockingQueue<>(),
+- new ThreadFactoryBuilder()
+- .setNameFormat("Paper Async Task Handler Thread - %1$d")
+- .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(MinecraftServer.LOGGER))
+- .build()
+- );
++ public static final Executor asyncExecutor = AsyncExecutor.instance; // Gale - centralized async execution - remove Paper async executor
+ public static final ThreadPoolExecutor cleanerExecutor = new ThreadPoolExecutor(
+ 1, 1, 0L, TimeUnit.SECONDS,
+ new LinkedBlockingQueue<>(),
+diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
+index a30024ab934b81cd76e282fab4bbf6052bdaaaaf..2534aa4fa9a023ed23b2d710fcffecd5f2fca6b9 100644
+--- a/src/main/java/net/minecraft/server/MinecraftServer.java
++++ b/src/main/java/net/minecraft/server/MinecraftServer.java
+@@ -148,6 +148,7 @@ import net.minecraft.world.level.storage.loot.PredicateManager;
+ import net.minecraft.world.phys.Vec2;
+ import net.minecraft.world.phys.Vec3;
+ import org.apache.commons.lang3.Validate;
++import org.galemc.gale.concurrent.AsyncExecutor;
+ import org.galemc.gale.concurrent.MinecraftServerBlockableEventLoop;
+ import org.galemc.gale.configuration.GaleConfigurations;
+ import org.galemc.gale.configuration.GaleGlobalConfiguration;
+@@ -980,8 +981,10 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
+ MinecraftServer.LOGGER.error("Failed to unlock level {}", this.storageSource.getLevelId(), ioexception1);
+ }
+ // Spigot start
+- io.papermc.paper.util.MCUtil.asyncExecutor.shutdown(); // Paper
+- try { io.papermc.paper.util.MCUtil.asyncExecutor.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS); // Paper
++ // Gale start - centralized async execution - remove Paper async executor
++ AsyncExecutor.instance.shutdown(); // Paper
++ try { AsyncExecutor.instance.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS); // Paper
++ // Gale end - centralized async execution - remove Paper async executor
+ } catch (java.lang.InterruptedException ignored) {} // Paper
+ if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) {
+ MinecraftServer.LOGGER.info("Saving usercache.json");
diff --git a/patches/server/0063-Remove-Paper-cleaner-executor.patch b/patches/server/0063-Remove-Paper-cleaner-executor.patch
new file mode 100644
index 0000000..8325142
--- /dev/null
+++ b/patches/server/0063-Remove-Paper-cleaner-executor.patch
@@ -0,0 +1,27 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: MartijnMuijsers
+Date: Tue, 29 Nov 2022 13:11:58 +0100
+Subject: [PATCH] Remove Paper cleaner executor
+
+License: AGPL-3.0 (https://www.gnu.org/licenses/agpl-3.0.html)
+
+diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java
+index 06507695eb53067b0da9cb66e4d443f21cb6f070..d9b1c85b4e36055b58c71748b005adf08c61f72f 100644
+--- a/src/main/java/io/papermc/paper/util/MCUtil.java
++++ b/src/main/java/io/papermc/paper/util/MCUtil.java
+@@ -58,14 +58,7 @@ import java.util.function.Supplier;
+
+ public final class MCUtil {
+ public static final Executor asyncExecutor = AsyncExecutor.instance; // Gale - centralized async execution - remove Paper async executor
+- public static final ThreadPoolExecutor cleanerExecutor = new ThreadPoolExecutor(
+- 1, 1, 0L, TimeUnit.SECONDS,
+- new LinkedBlockingQueue<>(),
+- new ThreadFactoryBuilder()
+- .setNameFormat("Paper Object Cleaner")
+- .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(MinecraftServer.LOGGER))
+- .build()
+- );
++ public static final Executor cleanerExecutor = AsyncExecutor.instance; // Gale - centralized async execution - remove Paper cleaner executor
+
+ public static final long INVALID_CHUNK_KEY = getCoordinateKey(Integer.MAX_VALUE, Integer.MAX_VALUE);
+
diff --git a/patches/server/0064-Remove-background-executor.patch b/patches/server/0064-Remove-background-executor.patch
new file mode 100644
index 0000000..e534173
--- /dev/null
+++ b/patches/server/0064-Remove-background-executor.patch
@@ -0,0 +1,78 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: MartijnMuijsers
+Date: Tue, 29 Nov 2022 14:21:44 +0100
+Subject: [PATCH] Remove background executor
+
+License: AGPL-3.0 (https://www.gnu.org/licenses/agpl-3.0.html)
+
+diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
+index 6b7943e8348b0a41ca69fb56ccfd5f1c1484eb07..e14245a77b40fca4bacf82295ad390339aba08a9 100644
+--- a/src/main/java/net/minecraft/Util.java
++++ b/src/main/java/net/minecraft/Util.java
+@@ -72,6 +72,7 @@ import net.minecraft.util.RandomSource;
+ import net.minecraft.util.TimeSource;
+ import net.minecraft.util.datafix.DataFixers;
+ import net.minecraft.world.level.block.state.properties.Property;
++import org.galemc.gale.concurrent.AsyncExecutor;
+ import org.slf4j.Logger;
+
+ public class Util {
+@@ -80,7 +81,7 @@ public class Util {
+ private static final String MAX_THREADS_SYSTEM_PROPERTY = "max.bg.threads";
+ private static final AtomicInteger WORKER_COUNT = new AtomicInteger(1);
+ private static final ExecutorService BOOTSTRAP_EXECUTOR = makeExecutor("Bootstrap", -2); // Paper - add -2 priority
+- private static final ExecutorService BACKGROUND_EXECUTOR = makeExecutor("Main", -1); // Paper - add -1 priority
++ private static final ExecutorService BACKGROUND_EXECUTOR = AsyncExecutor.instance; // Gale - centralized async execution - remove background executor
+ // Paper start - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread
+ public static final ExecutorService PROFILE_EXECUTOR = Executors.newFixedThreadPool(2, new java.util.concurrent.ThreadFactory() {
+
+@@ -219,7 +220,6 @@ public class Util {
+ }
+
+ public static void shutdownExecutors() {
+- shutdownExecutor(BACKGROUND_EXECUTOR);
+ shutdownExecutor(IO_POOL);
+ }
+
+diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
+index 2534aa4fa9a023ed23b2d710fcffecd5f2fca6b9..2537f2b35e2342c97892ac347d697d72f2d2d3d0 100644
+--- a/src/main/java/net/minecraft/server/MinecraftServer.java
++++ b/src/main/java/net/minecraft/server/MinecraftServer.java
+@@ -981,11 +981,6 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
+ MinecraftServer.LOGGER.error("Failed to unlock level {}", this.storageSource.getLevelId(), ioexception1);
+ }
+ // Spigot start
+- // Gale start - centralized async execution - remove Paper async executor
+- AsyncExecutor.instance.shutdown(); // Paper
+- try { AsyncExecutor.instance.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS); // Paper
+- // Gale end - centralized async execution - remove Paper async executor
+- } catch (java.lang.InterruptedException ignored) {} // Paper
+ if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) {
+ MinecraftServer.LOGGER.info("Saving usercache.json");
+ this.getProfileCache().save(false); // Paper
+@@ -995,6 +990,13 @@ public abstract class MinecraftServer extends MinecraftServerBlockableEventLoop
+ LOGGER.info("Flushing Chunk IO");
+ io.papermc.paper.chunk.system.io.RegionFileIOThread.close(true); // Paper // Paper - rewrite chunk system
+ LOGGER.info("Closing Thread Pool");
++ // Gale start - centralized async execution - remove Paper async executor, remove background executor
++ AsyncExecutor.instance.shutdown(); // Paper
++ try {
++ AsyncExecutor.instance.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS); // Paper
++ // Gale end - centralized async execution - remove Paper async executor
++ } catch (java.lang.InterruptedException ignored) {} // Paper
++ // Gale start - centralized async execution - remove background executor
+ Util.shutdownExecutors(); // Paper
+ LOGGER.info("Closing Server");
+ try {
+diff --git a/src/main/java/org/galemc/gale/concurrent/AsyncExecutor.java b/src/main/java/org/galemc/gale/concurrent/AsyncExecutor.java
+index de182b9473963b95085fa612f70884a56765ae43..fff4549d86e672dc7b9959ac5dd51fd04d4d62c3 100644
+--- a/src/main/java/org/galemc/gale/concurrent/AsyncExecutor.java
++++ b/src/main/java/org/galemc/gale/concurrent/AsyncExecutor.java
+@@ -34,6 +34,7 @@ public final class AsyncExecutor extends ThreadPoolExecutor {
+ public static final int parallelism;
+ static {
+ int parallelismByEnvironmentVariable = Integer.getInteger("gale.threads.async", -1);
++ parallelismByEnvironmentVariable = Math.max(parallelismByEnvironmentVariable, Integer.getInteger("Paper.WorkerThreadCount", -1)); // Gale - centralized async execution - remove background executor
+ parallelism = Math.max(1, parallelismByEnvironmentVariable > 0 ? parallelismByEnvironmentVariable : CPUCoresEstimation.get() - 2);
+ }
+
diff --git a/patches/server/0060-Remove-bootstrap-executor.patch b/patches/server/0065-Remove-bootstrap-executor.patch
similarity index 81%
rename from patches/server/0060-Remove-bootstrap-executor.patch
rename to patches/server/0065-Remove-bootstrap-executor.patch
index 84c034c..00f1052 100644
--- a/patches/server/0060-Remove-bootstrap-executor.patch
+++ b/patches/server/0065-Remove-bootstrap-executor.patch
@@ -12,16 +12,16 @@ As part of: Patina (https://github.com/PatinaMC/Patina)
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
-index 6b7943e8348b0a41ca69fb56ccfd5f1c1484eb07..259c138f4502efa92140674fb4fb7d6256e3e228 100644
+index e14245a77b40fca4bacf82295ad390339aba08a9..d84c721ed64cf927ccc9884235b22414298ce3ed 100644
--- a/src/main/java/net/minecraft/Util.java
+++ b/src/main/java/net/minecraft/Util.java
-@@ -79,8 +79,8 @@ public class Util {
+@@ -80,8 +80,8 @@ public class Util {
private static final int DEFAULT_MAX_THREADS = 255;
private static final String MAX_THREADS_SYSTEM_PROPERTY = "max.bg.threads";
private static final AtomicInteger WORKER_COUNT = new AtomicInteger(1);
- private static final ExecutorService BOOTSTRAP_EXECUTOR = makeExecutor("Bootstrap", -2); // Paper - add -2 priority
- private static final ExecutorService BACKGROUND_EXECUTOR = makeExecutor("Main", -1); // Paper - add -1 priority
-+ private static final ExecutorService BOOTSTRAP_EXECUTOR = BACKGROUND_EXECUTOR/*makeExecutor("Bootstrap", -2)*/; // Paper - add -2 priority // Gale - Patina - remove bootstrap executor
+ private static final ExecutorService BACKGROUND_EXECUTOR = AsyncExecutor.instance; // Gale - centralized async execution - remove background executor
++ private static final ExecutorService BOOTSTRAP_EXECUTOR = BACKGROUND_EXECUTOR; // Gale - Patina - remove bootstrap executor
// Paper start - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread
public static final ExecutorService PROFILE_EXECUTOR = Executors.newFixedThreadPool(2, new java.util.concurrent.ThreadFactory() {