diff --git a/include/vkcv/DescriptorConfig.hpp b/include/vkcv/DescriptorConfig.hpp
index 71b14ba86d63cf8206afd5a258edb189923ac087..c3d9ec51c3214952781d42660806f945a3e8ac7e 100644
--- a/include/vkcv/DescriptorConfig.hpp
+++ b/include/vkcv/DescriptorConfig.hpp
@@ -65,10 +65,12 @@ namespace vkcv
             ShaderStages shaderStages
         ) noexcept;
         
-        uint32_t bindingID;
-        DescriptorType descriptorType;
-        uint32_t descriptorCount;
-        ShaderStages shaderStages;
+        uint32_t        bindingID;
+        DescriptorType  descriptorType;
+        uint32_t        descriptorCount;
+        ShaderStages    shaderStages;
+
+        bool DescriptorBinding::operator ==(const DescriptorBinding &other) const;
     };
     
     typedef std::unordered_map<uint32_t, DescriptorBinding> DescriptorBindings;
diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp
index 15c1734924274acbe3aa42ac1429abeab2c71c11..a7c2d8ea147ed6e137ac7b729dfe3874afa6df19 100644
--- a/projects/first_mesh/src/main.cpp
+++ b/projects/first_mesh/src/main.cpp
@@ -106,9 +106,15 @@ int main(int argc, const char** argv) {
 	
 	const vkcv::VertexLayout firstMeshLayout (bindings);
 
+
 	// since we only use one descriptor set (namely, desc set 0), directly address it
+	// recreate copies of the bindings and the handles (to check whether they are properly reused instead of actually recreated)
 	std::unordered_map<uint32_t, vkcv::DescriptorBinding> set0Bindings = firstMeshProgram.getReflectedDescriptors().at(0);
+    auto set0BindingsExplicitCopy = set0Bindings;
+
 	vkcv::DescriptorSetLayoutHandle setLayoutHandle = core.createDescriptorSetLayout(set0Bindings);
+	vkcv::DescriptorSetLayoutHandle setLayoutHandleCopy = core.createDescriptorSetLayout(set0BindingsExplicitCopy);
+
 	vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(setLayoutHandle);
 
 	const vkcv::PipelineConfig firstMeshPipelineConfig {
diff --git a/src/vkcv/DescriptorConfig.cpp b/src/vkcv/DescriptorConfig.cpp
index a9a127fe608472682c1cbc8d32ca466fba860c72..91a9c24dc1819b69223b6befa9b6d64409698c35 100644
--- a/src/vkcv/DescriptorConfig.cpp
+++ b/src/vkcv/DescriptorConfig.cpp
@@ -1,15 +1,23 @@
 #include "vkcv/DescriptorConfig.hpp"
 
-namespace vkcv {
+namespace vkcv
+{
 	DescriptorBinding::DescriptorBinding(
 		uint32_t bindingID,
 		DescriptorType descriptorType,
 		uint32_t descriptorCount,
-		ShaderStages shaderStages) noexcept
-		:
+		ShaderStages shaderStages) noexcept:
 		bindingID(bindingID),
 		descriptorType(descriptorType),
 		descriptorCount(descriptorCount),
-		shaderStages(shaderStages) {}
-	
+		shaderStages(shaderStages)
+		{}
+
+    bool DescriptorBinding::operator==(const DescriptorBinding &other) const
+    {
+	    return (this->bindingID == other.bindingID) &&
+	           (this->descriptorType == other.descriptorType) &&
+	           (this->descriptorCount == other.descriptorCount) &&
+	           (this->shaderStages == other.shaderStages);
+    }
 }
diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp
index a1c2dd543a51ad72b5632c6b2be68247b4d4f69a..78c9c0a75e40ff7c4dc7b542c61ca4bedfef5d69 100644
--- a/src/vkcv/DescriptorManager.cpp
+++ b/src/vkcv/DescriptorManager.cpp
@@ -44,6 +44,17 @@ namespace vkcv
 
     DescriptorSetLayoutHandle DescriptorManager::createDescriptorSetLayout(const DescriptorBindings &setBindingsMap)
     {
+        for (auto i = 0; i < m_DescriptorSetLayouts.size(); i++)
+        {
+            if(m_DescriptorSetLayouts[i].descriptorBindings.size() != setBindingsMap.size())
+                continue;
+
+            if (m_DescriptorSetLayouts[i].descriptorBindings == setBindingsMap)
+            {
+                return DescriptorSetLayoutHandle(i, [&](uint64_t id) { destroyDescriptorSetLayoutById(id); });
+            }
+        }
+        
         //create the descriptor set's layout by iterating over its bindings
         std::vector<vk::DescriptorSetLayoutBinding> bindingsVector = {};
         for (auto bindingElem : setBindingsMap)
diff --git a/src/vkcv/ShaderProgram.cpp b/src/vkcv/ShaderProgram.cpp
index 363981f4fdcbcdee98bbf286db0811c7b37fae94..a1634c230907ffa741101710613aff73e1fb7b06 100644
--- a/src/vkcv/ShaderProgram.cpp
+++ b/src/vkcv/ShaderProgram.cpp
@@ -155,7 +155,14 @@ namespace vkcv {
                     base_type.vecsize,
                     shaderStage);
 
-            m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding));
+            auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding));
+            if(!insertionResult.second)
+            {
+                vkcv_log(LogLevel::WARNING,
+                         "Attempting to overwrite already existing binding %u at set ID %u.",
+                         bindingID,
+                         setID);
+            }
         }
 
         for (uint32_t i = 0; i < resources.storage_buffers.size(); i++)
@@ -171,7 +178,14 @@ namespace vkcv {
                     base_type.vecsize,
                     shaderStage);
 
-            m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding));
+            auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding));
+            if(!insertionResult.second)
+            {
+                vkcv_log(LogLevel::WARNING,
+                         "Attempting to overwrite already existing binding %u at set ID %u.",
+                         bindingID,
+                         setID);
+            }
         }
 
         for (uint32_t i = 0; i < resources.separate_samplers.size(); i++) {
@@ -186,7 +200,14 @@ namespace vkcv {
                     base_type.vecsize,
                     shaderStage);
 
-            m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding));
+            auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding));
+            if(!insertionResult.second)
+            {
+                vkcv_log(LogLevel::WARNING,
+                         "Attempting to overwrite already existing binding %u at set ID %u.",
+                         bindingID,
+                         setID);
+            }
         }
 
         for (uint32_t i = 0; i < resources.separate_images.size(); i++) {
@@ -201,7 +222,14 @@ namespace vkcv {
                     base_type.vecsize,
                     shaderStage);
 
-            m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding));
+            auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding));
+            if(!insertionResult.second)
+            {
+                vkcv_log(LogLevel::WARNING,
+                         "Attempting to overwrite already existing binding %u at set ID %u.",
+                         bindingID,
+                         setID);
+            }
         }
 
         for (uint32_t i = 0; i < resources.storage_images.size(); i++) {
@@ -216,7 +244,14 @@ namespace vkcv {
                     base_type.vecsize,
                     shaderStage);
 
-            m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding));
+            auto insertionResult = m_DescriptorSets[setID].insert(std::make_pair(bindingID, binding));
+            if(!insertionResult.second)
+            {
+                vkcv_log(LogLevel::WARNING,
+                         "Attempting to overwrite already existing binding %u at set ID %u.",
+                         bindingID,
+                         setID);
+            }
         }
 
         //reflect push constants