diff --git a/config/Sources.cmake b/config/Sources.cmake
index 0d0a37876813861c605466566eced727a70f6488..6f7dc118ce3a96b1d25d91c39385c52aa2883876 100644
--- a/config/Sources.cmake
+++ b/config/Sources.cmake
@@ -20,7 +20,9 @@ set(vkcv_sources
 		${vkcv_source}/vkcv/Window.cpp
 
 		${vkcv_include}/vkcv/Buffer.hpp
-		${vkcv_source}/vkcv/Buffer.cpp
+		
+		${vkcv_include}/vkcv/BufferManager.hpp
+		${vkcv_source}/vkcv/BufferManager.cpp
 
 		${vkcv_include}/vkcv/SwapChain.hpp
 		${vkcv_source}/vkcv/SwapChain.cpp
diff --git a/include/vkcv/Buffer.hpp b/include/vkcv/Buffer.hpp
index 6647cbf2e2686edf615ace45e1c63c002f0fd457..f2ebb96a783aaa615e0808be2849b7ba5a288ff5 100644
--- a/include/vkcv/Buffer.hpp
+++ b/include/vkcv/Buffer.hpp
@@ -1,163 +1,59 @@
 #pragma once
 /**
- * @authors Lars Hoerttrich
- * @file include/vkcv/Buffer.hpp
+ * @authors Lars Hoerttrich, Tobias Frisch
+ * @file vkcv/Buffer.hpp
  * @brief template buffer class, template for type security, implemented here because template classes can't be written in .cpp
  */
-#include "vkcv/Handles.hpp"
-#include <vulkan/vulkan.hpp>
-#include "vkcv/Context.hpp"
-
-
+#include "BufferManager.hpp"
 
 namespace vkcv {
-	//Enum of buffertypes
-	enum BufferType { VERTEX, UNIFORM, STORAGE };
-
-	//Functions outsourced to Buffer.cpp file:
-	void outsourcedDestructor(vk::Device device, vk::DeviceMemory bufferMemory, vk::Buffer buffer);
-	vk::Buffer outsourcedCreateBuffer(vk::Device device, BufferType type, size_t size);
-	vk::DeviceMemory outsourcedAllocateMemory(vk::Device device, vk::PhysicalDevice physicalDevice, vk::MemoryRequirements memoryRequirements);
 
 	template<typename T>
 	class Buffer {
 	public:
-		//future bufferHandle struct
-		struct Handle {
-			uint64_t id;
-
-		};
-
 		// explicit destruction of default constructor
 		Buffer<T>() = delete;
-		// is never called directly
-		~Buffer<T>() noexcept {
-			outsourcedDestructor(m_Device, m_BufferMemory, m_Buffer);
-		}
 
-		Buffer<T>(const Buffer<T>& other) = delete; // copy-ctor
-		Buffer<T>(Buffer<T>&& other) noexcept :
-		        m_Buffer(other.m_Buffer),
-				m_BufferMemory(other.m_BufferMemory),
-				m_Device(other.m_Device),
-		        m_Type(other.m_Type),
-		        m_Size(other.m_Size),
-		        m_DataP(other.m_DataP)
-		{
-			other.m_Buffer = nullptr;
-			other.m_BufferMemory = nullptr;
-			other.m_Device = nullptr;
-			other.m_Type = vkcv::VERTEX; //set to 0
-			other.m_Size = 0;
-			other.m_DataP = nullptr;
-		} // move-ctor
-
-		Buffer<T>& operator=(const Buffer<T>& other) = delete; // copy assignment
-		Buffer<T>& operator=(Buffer<T>&& other) noexcept {
-			m_Buffer = other.m_Buffer;
-			m_BufferMemory = other.m_BufferMemory;
-			m_Device = other.m_Device;
-			m_Type = other.m_Type;
-			m_Size = other.m_Size;
-			m_DataP = other.m_DataP;
-
-			other.m_Buffer = nullptr;
-			other.m_BufferMemory = nullptr;
-			other.m_Device = nullptr;
-			other.m_Type = vkcv::VERTEX; //set to 0
-			other.m_Size = 0;
-			other.m_DataP = nullptr;
-
-		}// move assignment
-
-		BufferType getType() { return m_Type; };
-		size_t getSize() { return m_Size; };
-		
-		/**
-		 * Maps this buffers Memory, fills this buffer with @p data of type T and count @p count
-		 * unmaps afterwards.
-		 * @p data Pointer to data
-		 * @p count Amount of data of type T
-		 */
-		 // TODO: we will probably need staging-buffer here later (possible add in BufferManager later?)
-		void fill(T* data, size_t count) {
-			const vk::MemoryRequirements requirements = m_Device.getBufferMemoryRequirements(m_Buffer);
-			
-			// TODO: check if mapped already
-			m_DataP = static_cast<uint8_t*>(m_Device.mapMemory(m_BufferMemory, 0, requirements.size));
-			memcpy(m_DataP, data, sizeof(T) * count);
-			m_Device.unmapMemory(m_BufferMemory);
+		BufferType getType() {
+			return m_type;
 		};
 		
-		T* map() {
-			const vk::MemoryRequirements requirements = m_Device.getBufferMemoryRequirements(m_Buffer);
-			
-			m_DataP = static_cast<uint8_t*>(m_Device.mapMemory(m_BufferMemory, 0, requirements.size));
-			// TODO: make sure to unmap before deallocation
-			
-			return reinterpret_cast<T*>(m_DataP);
-		};
+		size_t getCount() {
+			return m_count;
+		}
 		
-		void unmap() {
-			m_Device.unmapMemory(m_BufferMemory);
-			// TODO: mark m_DataP as invalid?
-		};
+		size_t getSize() {
+			return m_count * sizeof(T);
+		}
 		
-		/**
-		 * * Create function of #Buffer requires a @p device, a @p physicalDevice, a @p buffer type and a @p size.		 *
-		 * @param device Vulkan-Device
-		 * @param physicalDevice Vulkan-PhysicalDevice
-		 * @param type Enum type of possible vkcv::BufferType
-		 * @param Size size of data
-		 */
-		static Buffer<T> create(vk::Device device, vk::PhysicalDevice physicalDevice, BufferType type, size_t size) {
-			vk::Buffer buffer = nullptr;
-			
+		void fill(T* data, size_t count = SIZE_MAX, size_t offset = 0) {
+			 m_manager->fillBuffer(m_handle_id, data, count * sizeof(T), offset * sizeof(T));
+		}
+		
+		T* map(size_t offset = 0, size_t count = SIZE_MAX) {
+			return reinterpret_cast<T*>(m_manager->mapBuffer(m_handle_id, offset * sizeof(T), count * sizeof(T)));
+		}
 
-			buffer = outsourcedCreateBuffer(device, type, sizeof(T) * size);
-			
-			if (!buffer) {
-				//TODO: potential issue
-			}
-			
-			//get requirements for allocation
-			const vk::MemoryRequirements requirements = device.getBufferMemoryRequirements(buffer);
-			
-			vk::DeviceMemory memory= outsourcedAllocateMemory(device, physicalDevice, requirements);
-			
-			if (!memory) {
-				//TODO: other potential issue
-			}
-			
-			device.bindBufferMemory(buffer, memory, 0);
-			
-			return Buffer<T>(buffer, memory, device, type, size);
+		void unmap() {
+			m_manager->unmapBuffer(m_handle_id);
+		}
+		
+		static Buffer<T> create(BufferManager* manager, BufferType type, size_t count) {
+			return Buffer<T>(manager, manager->createBuffer(type, count * sizeof(T)), type, count);
 		}
 
 	private:
-		vk::Buffer m_Buffer;
-		vk::DeviceMemory m_BufferMemory;
-		vk::Device m_Device;
-		BufferType m_Type;
-		size_t m_Size=0;
-		uint8_t* m_DataP;
-
-		/**
-		 * * Constructor of #Buffer requires a @p buffer, a @p memory, @p device, @ requirement, a @p buffer type and a @p size.
-		 * @param buffer Vulkan-Buffer
-		 * @param memory Vulkan-DeviceMemory
-		 * @param device Vulkan-Device
-		 * @param requirement Vulkan-MemoryRequirements
-		 * @param type Enum type of possible vkcv::BufferType
-		 * @param Size size of data
-		 */
-		Buffer<T>(vk::Buffer buffer, vk::DeviceMemory memory, vk::Device device, BufferType type, size_t size) :
-				m_Buffer(buffer),
-				m_BufferMemory(memory),
-				m_Device(device),
-				m_Type(type),
-				m_Size(size),
-				m_DataP(nullptr)
-		{}	
+		BufferManager* m_manager;
+		uint64_t m_handle_id;
+		BufferType m_type;
+		size_t m_count;
+		
+		Buffer<T>(BufferManager* manager, uint64_t id, BufferType type, size_t count) :
+				m_manager(manager),
+				m_handle_id(id),
+				m_type(type),
+				m_count(count)
+		{}
+		
 	};
 }
diff --git a/include/vkcv/BufferManager.hpp b/include/vkcv/BufferManager.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1bafaf6ba5ea4ab079e9514451759d1950fd8443
--- /dev/null
+++ b/include/vkcv/BufferManager.hpp
@@ -0,0 +1,89 @@
+#pragma once
+
+#include <vector>
+#include <vulkan/vulkan.hpp>
+
+namespace vkcv
+{
+	enum BufferType { VERTEX, UNIFORM, STORAGE };
+	
+	class BufferManager
+	{
+		friend class Core;
+	private:
+		
+		struct Buffer
+		{
+			vk::Buffer m_handle;
+			vk::DeviceMemory m_memory;
+			void* m_mapped = nullptr;
+		};
+		
+		vk::PhysicalDevice m_physicalDevice;
+		vk::Device m_device;
+		
+		std::vector<Buffer> m_buffers;
+		
+		BufferManager(vk::Device device, vk::PhysicalDevice physicalDevice) noexcept;
+		
+	public:
+		BufferManager() = delete;
+		~BufferManager() noexcept;
+		
+		BufferManager(BufferManager&& other) = delete;
+		BufferManager(const BufferManager& other) = delete;
+		
+		BufferManager& operator=(BufferManager&& other) = delete;
+		BufferManager& operator=(const BufferManager& other) = delete;
+		
+		/**
+		 * Creates and allocates a new buffer and returns its
+		 * unique buffer handle id.
+		 *
+		 * @param type Type of buffer
+		 * @param size Size of buffer in bytes
+		 * @return New buffer handle id
+		 */
+		uint64_t createBuffer(BufferType type, size_t size);
+		
+		/**
+		 * Fills a buffer represented by a given buffer
+		 * handle id with custom data.
+		 *
+		 * @param id Buffer handle id
+		 * @param data Pointer to data
+		 * @param size Size of data in bytes
+		 * @param offset Offset to fill in data in bytes
+		 */
+		void fillBuffer(uint64_t id, void* data, size_t size, size_t offset);
+		
+		/**
+		 * Maps memory to a buffer represented by a given
+		 * buffer handle id and returns it.
+		 *
+		 * @param id Buffer handle id
+		 * @param offset Offset of mapping in bytes
+		 * @param size Size of mapping in bytes
+		 * @return Pointer to mapped memory
+		 */
+		void* mapBuffer(uint64_t id, size_t offset, size_t size);
+		
+		/**
+		 * Unmaps memory from a buffer represented by a given
+		 * buffer handle id.
+		 *
+		 * @param id Buffer handle id
+		 */
+		void unmapBuffer(uint64_t id);
+	
+		/**
+		 * Destroys and deallocates buffer represented by a given
+		 * buffer handle id.
+		 *
+		 * @param id Buffer handle id
+		 */
+		void destroyBuffer(uint64_t id);
+		
+	};
+	
+}
diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index 45e555151584e60f4edd29058e5a59e076f9fafc..67bc1b3903ebcb2b49729dbe736043b58de77b1b 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -23,6 +23,7 @@ namespace vkcv
     // forward declarations
     class PassManager;
     class PipelineManager;
+    class BufferManager;
 
     class Core final
     {
@@ -49,6 +50,7 @@ namespace vkcv
 
         std::unique_ptr<PassManager> m_PassManager;
         std::unique_ptr<PipelineManager> m_PipelineManager;
+        std::unique_ptr<BufferManager> m_BufferManager;
 		CommandResources m_CommandResources;
 		SyncResources m_SyncResources;
 		uint32_t m_currentSwapchainImageIndex;
@@ -138,13 +140,13 @@ namespace vkcv
 
         /**
             * Creates a #Buffer with data-type T and @p bufferType 
-            * @param bufferType Type of Buffer created
-            * @param size Amount of Data of type T
+            * @param type Type of Buffer created
+            * @param count Count of elements of type T
             * return Buffer-Object
             */
         template<typename T>
-        Buffer<T> createBuffer(vkcv::BufferType bufferType,size_t size) {
-        	return Buffer<T>::create(m_Context.getDevice(), m_Context.getPhysicalDevice(), bufferType, size);
+        Buffer<T> createBuffer(vkcv::BufferType type, size_t count) {
+        	return Buffer<T>::create(m_BufferManager.get(), type, count);
         }
 
 		/**
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index 3c3f91de9ac1c4490859559db2bca5bdd089ecfa..469015fe2f61e35fc95a741d4fe9fe51dc3f4bd9 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -37,8 +37,9 @@ int main(int argc, const char** argv) {
 	
 	vec3* m = buffer.map();
 	m[0] = { 0, 0, 0 };
-	m[0] = { 0, 0, 0 };
-	m[0] = { 0, 0, 0 };
+	m[1] = { 0, 0, 0 };
+	m[2] = { 0, 0, 0 };
+	buffer.unmap();
 
 	std::cout << "Physical device: " << physicalDevice.getProperties().deviceName << std::endl;
 
diff --git a/src/vkcv/Buffer.cpp b/src/vkcv/Buffer.cpp
deleted file mode 100644
index 956f680064b30ac5e22ce41c622e2cb96ccecd46..0000000000000000000000000000000000000000
--- a/src/vkcv/Buffer.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * @authors Lars Hoerttrich
- * @file src/vkcv/Buffer.cpp
- * @brief Implementation of template buffer class, template for type security
- */
-#include"vkcv/Buffer.hpp"
-
-namespace vkcv {
-
-	/**
-	 * @brief searches memory type index for buffer allocation, inspired by vulkan tutorial and "https://github.com/KhronosGroup/Vulkan-Hpp/blob/master/samples/utils/utils.hpp"
-	 * @param physicalMemoryProperties Memory Properties of physical device
-	 * @param typeBits
-	 * @param requirements Property flags that are required
-	 * @return memory type index for Buffer
-	 */
-	uint32_t searchMemoryType(vk::PhysicalDeviceMemoryProperties const& physicalMemoryProperties, uint32_t typeBits, vk::MemoryPropertyFlags requirements) {
-		uint32_t memoryTypeIndex = uint32_t(0);
-		for (uint32_t i = 0; i < physicalMemoryProperties.memoryTypeCount; i++)
-		{
-			if ((typeBits & 1) &&
-				((physicalMemoryProperties.memoryTypes[i].propertyFlags & requirements) == requirements))
-			{
-				memoryTypeIndex = i;
-				break;
-			}
-			typeBits >>= 1;
-		}
-		return memoryTypeIndex;
-	}
-
-	void outsourcedDestructor(vk::Device device, vk::DeviceMemory bufferMemory, vk::Buffer buffer)
-	{
-		if (device) {
-			device.freeMemory(bufferMemory);
-			device.destroyBuffer(buffer);
-		}
-	}
-
-	vk::Buffer outsourcedCreateBuffer(vk::Device device, BufferType type, size_t size)
-	{
-		switch (type) {
-		case VERTEX: {
-			//create vertex buffer
-			return device.createBuffer(vk::BufferCreateInfo(vk::BufferCreateFlags(), size, vk::BufferUsageFlagBits::eVertexBuffer));
-		}
-		default: {
-			// TODO: maybe an issue
-		}
-		}
-
-		return vk::Buffer(); //should never be reached
-	}
-
-	vk::DeviceMemory outsourcedAllocateMemory(vk::Device device, vk::PhysicalDevice physicalDevice, vk::MemoryRequirements memoryRequirements)
-	{
-		//find Memory Type
-		uint32_t memoryType = searchMemoryType(physicalDevice.getMemoryProperties(), memoryRequirements.memoryTypeBits, vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
-		return device.allocateMemory(vk::MemoryAllocateInfo(memoryRequirements.size, memoryType));
-	}
-}
\ No newline at end of file
diff --git a/src/vkcv/BufferManager.cpp b/src/vkcv/BufferManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a07ed463125c751593117e12874fb1312e1b03f0
--- /dev/null
+++ b/src/vkcv/BufferManager.cpp
@@ -0,0 +1,159 @@
+/**
+ * @author Tobias Frisch
+ * @file vkcv/BufferManager.cpp
+ */
+
+#include "vkcv/BufferManager.hpp"
+
+namespace vkcv {
+	
+	BufferManager::BufferManager(vk::Device device, vk::PhysicalDevice physicalDevice) noexcept :
+		m_device(device), m_physicalDevice(physicalDevice)
+	{}
+	
+	BufferManager::~BufferManager() noexcept {
+		for (size_t id = 0; id < m_buffers.size(); id++) {
+			destroyBuffer(id);
+		}
+	}
+	
+	/**
+	 * @brief searches memory type index for buffer allocation, inspired by vulkan tutorial and "https://github.com/KhronosGroup/Vulkan-Hpp/blob/master/samples/utils/utils.hpp"
+	 * @param physicalMemoryProperties Memory Properties of physical device
+	 * @param typeBits
+	 * @param requirements Property flags that are required
+	 * @return memory type index for Buffer
+	 */
+	uint32_t searchMemoryType(const vk::PhysicalDeviceMemoryProperties& physicalMemoryProperties, uint32_t typeBits, vk::MemoryPropertyFlags requirements) {
+		uint32_t memoryTypeIndex = 0;
+		
+		for (uint32_t i = 0; i < physicalMemoryProperties.memoryTypeCount; i++)
+		{
+			if ((typeBits & 1) &&
+				((physicalMemoryProperties.memoryTypes[i].propertyFlags & requirements) == requirements))
+			{
+				memoryTypeIndex = i;
+				break;
+			}
+			
+			typeBits >>= 1;
+		}
+		
+		return memoryTypeIndex;
+	}
+	
+	uint64_t BufferManager::createBuffer(BufferType type, size_t size) {
+		vk::BufferCreateFlags createFlags;
+		vk::BufferUsageFlags usageFlags;
+		
+		switch (type) {
+			case VERTEX:
+				usageFlags = vk::BufferUsageFlagBits::eVertexBuffer;
+				break;
+			case UNIFORM:
+				usageFlags = vk::BufferUsageFlagBits::eUniformBuffer;
+				break;
+			case STORAGE:
+				usageFlags = vk::BufferUsageFlagBits::eStorageBuffer;
+				break;
+			default:
+				// TODO: maybe an issue
+				break;
+		}
+		
+		vk::Buffer buffer = m_device.createBuffer(
+				vk::BufferCreateInfo(createFlags, size, usageFlags)
+		);
+		
+		const vk::MemoryRequirements requirements = m_device.getBufferMemoryRequirements(buffer);
+		
+		const uint32_t memoryType = searchMemoryType(
+				m_physicalDevice.getMemoryProperties(),
+				requirements.memoryTypeBits,
+				vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent
+		);
+		
+		vk::DeviceMemory memory = m_device.allocateMemory(vk::MemoryAllocateInfo(requirements.size, memoryType));
+		
+		const uint64_t id = m_buffers.size();
+		m_buffers.push_back({ buffer, memory, nullptr });
+		return id;
+	}
+	
+	void BufferManager::fillBuffer(uint64_t id, void *data, size_t size, size_t offset) {
+		if (id >= m_buffers.size()) {
+			return;
+		}
+		
+		auto& buffer = m_buffers[id];
+		
+		if (buffer.m_mapped) {
+			return;
+		}
+		
+		const vk::MemoryRequirements requirements = m_device.getBufferMemoryRequirements(buffer.m_handle);
+		
+		if (offset > requirements.size) {
+			return;
+		}
+		
+		const size_t mapped_size = std::min(size, requirements.size - offset);
+		void* mapped = m_device.mapMemory(buffer.m_memory, offset, mapped_size);
+		memcpy(mapped, data, mapped_size);
+		m_device.unmapMemory(buffer.m_memory);
+	}
+	
+	void* BufferManager::mapBuffer(uint64_t id, size_t offset, size_t size) {
+		if (id >= m_buffers.size()) {
+			return nullptr;
+		}
+		
+		auto& buffer = m_buffers[id];
+		
+		if (buffer.m_mapped) {
+			return nullptr;
+		}
+		
+		const vk::MemoryRequirements requirements = m_device.getBufferMemoryRequirements(buffer.m_handle);
+		
+		if (offset > requirements.size) {
+			return nullptr;
+		}
+		
+		const size_t mapped_size = std::min(size, requirements.size - offset);
+		buffer.m_mapped = m_device.mapMemory(buffer.m_memory, offset, mapped_size);
+		return buffer.m_mapped;
+	}
+	
+	void BufferManager::unmapBuffer(uint64_t id) {
+		if (id >= m_buffers.size()) {
+			return;
+		}
+		
+		auto& buffer = m_buffers[id];
+		
+		if (buffer.m_mapped == nullptr) {
+			return;
+		}
+		
+		m_device.unmapMemory(buffer.m_memory);
+		buffer.m_mapped = nullptr;
+	}
+	
+	void BufferManager::destroyBuffer(uint64_t id) {
+		if (id >= m_buffers.size()) {
+			return;
+		}
+		
+		auto& buffer = m_buffers[id];
+		
+		if (buffer.m_memory) {
+			m_device.freeMemory(buffer.m_memory);
+		}
+		
+		if (buffer.m_handle) {
+			m_device.destroyBuffer(buffer.m_handle);
+		}
+	}
+
+}
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index 41c2ac6f821a4dbd122b65fd06c3585d1fccd79d..4ddc96f34865b26990d32be6a0b7e7f06d84d6fe 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -9,6 +9,7 @@
 #include "vkcv/Core.hpp"
 #include "PassManager.hpp"
 #include "PipelineManager.hpp"
+#include "vkcv/BufferManager.hpp"
 #include "Surface.hpp"
 #include "ImageLayoutTransitions.hpp"
 #include "Framebuffer.hpp"
@@ -86,6 +87,7 @@ namespace vkcv
             m_swapchainImageViews(imageViews),
             m_PassManager{std::make_unique<PassManager>(m_Context.m_Device)},
             m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)},
+			m_BufferManager{std::unique_ptr<BufferManager>(new BufferManager(m_Context.m_Device, m_Context.m_PhysicalDevice))},
             m_CommandResources(commandResources),
             m_SyncResources(syncResources)
 	{}