diff --git a/include/upnp/upnp_context.h b/include/upnp/upnp_context.h
index 46254dc1b7bdd9cbd7d12fe7b1c9e3f6338209f6..57f6d826453f7925d6f463799c99f050ee2acd5d 100644
--- a/include/upnp/upnp_context.h
+++ b/include/upnp/upnp_context.h
@@ -138,6 +138,17 @@ public:
     // then the state of all pending mappings is set to FAILED.
     void setIgdDiscoveryTimeout(std::chrono::milliseconds timeout);
 
+    // Set limits on the number of "available" mappings that the UPnPContext
+    // can keep at any given time. An available mapping is one that has been
+    // opened, but isn't being used by any Controller. The context will attempt
+    // to close or open mappings as needed to keep the number of available
+    // mappings between `minCount` and `maxCount`.
+    void setAvailableMappingsLimits(PortType type, unsigned minCount, unsigned maxCount) {
+        unsigned index = (type == PortType::TCP) ? 0 : 1;
+        maxAvailableMappings_[index] = maxCount;
+        minAvailableMappings_[index] = (minCount <= maxCount) ? minCount : 0;
+    }
+
 private:
     // Initialization
     void init();
@@ -286,8 +297,8 @@ private:
 
     // Minimum and maximum limits on the number of available
     // mappings to keep in the list at any given time
-    static constexpr unsigned minAvailableMappings_[2] {4, 8};
-    static constexpr unsigned maxAvailableMappings_[2] {8, 12};
+    unsigned minAvailableMappings_[2] {4, 8};
+    unsigned maxAvailableMappings_[2] {8, 12};
     unsigned getMinAvailableMappings(PortType type) {
         unsigned index = (type == PortType::TCP) ? 0 : 1;
         return minAvailableMappings_[index];
diff --git a/tools/upnp/upnpctrl.cpp b/tools/upnp/upnpctrl.cpp
index 7c4febff98144065cabcb43f00a2830ba70ddc06..ba13de580a8596a6f42611f651c100e8d18b7d6a 100644
--- a/tools/upnp/upnpctrl.cpp
+++ b/tools/upnp/upnpctrl.cpp
@@ -62,6 +62,8 @@ main(int argc, char** argv)
     auto ioContext  = std::make_shared<asio::io_context>();
     std::shared_ptr<dht::log::Logger> logger = dht::log::getStdLogger();
     auto upnpContext = std::make_shared<dhtnet::upnp::UPnPContext>(ioContext, logger);
+    upnpContext->setAvailableMappingsLimits(dhtnet::upnp::PortType::TCP, 0, 0);
+    upnpContext->setAvailableMappingsLimits(dhtnet::upnp::PortType::UDP, 0, 0);
 
     auto ioContextRunner = std::make_shared<std::thread>([context = ioContext]() {
         try {