diff --git a/src/main.cpp b/src/main.cpp
index 3f75304..76f98c0 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -16,6 +16,8 @@
 constexpr uint32_t WIDTH = 800;
 constexpr uint32_t HEIGHT = 600;
 
+constexpr int MAX_FRAMES_IN_FLIGHT = 2;
+
 constexpr std::array<const char*,1> REQUIRED_LAYERS {
     "VK_LAYER_KHRONOS_validation"
 };
@@ -77,9 +79,10 @@ private:
     vk::raii::Pipeline m_graphicsPipeline{ nullptr };
     vk::raii::CommandPool m_commandPool{ nullptr };
     std::vector<vk::raii::CommandBuffer> m_commandBuffers;
-    vk::raii::Semaphore m_imageAvailableSemaphore{ nullptr };
-    vk::raii::Semaphore m_renderFinishedSemaphore{ nullptr };
-    vk::raii::Fence m_inFlightFence{ nullptr };
+    std::vector<vk::raii::Semaphore> m_imageAvailableSemaphores;
+    std::vector<vk::raii::Semaphore> m_renderFinishedSemaphores;
+    std::vector<vk::raii::Fence> m_inFlightFences;
+    uint32_t m_currentFrame = 0;
     /////////////////////////////////////////////////////////////
 
     /////////////////////////////////////////////////////////////
@@ -105,7 +108,7 @@ private:
         createFramebuffers();
         createGraphicsPipeline();
         createCommandPool();
-        createCommandBuffer();
+        createCommandBuffers();
         createSyncObjects();
     }
 
@@ -549,11 +552,11 @@ private:
 
         m_commandPool = m_device.createCommandPool( poolInfo );
     }
-    void createCommandBuffer() {
+    void createCommandBuffers() {
         vk::CommandBufferAllocateInfo allocInfo;
         allocInfo.commandPool = m_commandPool;
         allocInfo.level = vk::CommandBufferLevel::ePrimary;
-        allocInfo.commandBufferCount = 1;
+        allocInfo.commandBufferCount = MAX_FRAMES_IN_FLIGHT;
 
         m_commandBuffers = m_device.allocateCommandBuffers(allocInfo);
     }
@@ -601,39 +604,43 @@ private:
         constexpr vk::FenceCreateInfo fenceInfo(
             vk::FenceCreateFlagBits::eSignaled  // flags
         );
-        m_imageAvailableSemaphore = m_device.createSemaphore( semaphoreInfo );
-        m_renderFinishedSemaphore = m_device.createSemaphore( semaphoreInfo );
-        m_inFlightFence = m_device.createFence( fenceInfo );
+
+        for(size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i){
+            m_imageAvailableSemaphores.emplace_back( m_device, semaphoreInfo );
+            m_renderFinishedSemaphores.emplace_back( m_device,  semaphoreInfo );
+            m_inFlightFences.emplace_back( m_device , fenceInfo );
+        }
     }
     void drawFrame() {
-        if(const auto res = m_device.waitForFences( *m_inFlightFence, true, std::numeric_limits<uint64_t>::max() );
+        if(const auto res = m_device.waitForFences( *m_inFlightFences[m_currentFrame], true, std::numeric_limits<uint64_t>::max() );
             res != vk::Result::eSuccess
         ) throw std::runtime_error{ "waitForFences in drawFrame was failed" };
 
-        m_device.resetFences( *m_inFlightFence );
+        m_device.resetFences( *m_inFlightFences[m_currentFrame] );
 
-        auto [nxtRes, imageIndex] = m_swapChain.acquireNextImage(std::numeric_limits<uint64_t>::max(), m_imageAvailableSemaphore);
+        auto [nxtRes, imageIndex] = m_swapChain.acquireNextImage(std::numeric_limits<uint64_t>::max(),  m_imageAvailableSemaphores[m_currentFrame]);
 
-        m_commandBuffers[0].reset();
-        recordCommandBuffer(m_commandBuffers[0], imageIndex);
+        m_commandBuffers[m_currentFrame].reset();
+        recordCommandBuffer(m_commandBuffers[m_currentFrame], imageIndex);
 
         vk::SubmitInfo submitInfo;
-        submitInfo.setWaitSemaphores( *m_imageAvailableSemaphore );
+        submitInfo.setWaitSemaphores( *m_imageAvailableSemaphores[m_currentFrame] );
         std::array<vk::PipelineStageFlags,1> waitStages = { vk::PipelineStageFlagBits::eColorAttachmentOutput };
         submitInfo.setWaitDstStageMask( waitStages );
-        submitInfo.setCommandBuffers( *m_commandBuffers[0] );
+        submitInfo.setCommandBuffers( *m_commandBuffers[m_currentFrame] );
 
-        submitInfo.setSignalSemaphores( *m_renderFinishedSemaphore );
-        m_graphicsQueue.submit(submitInfo, m_inFlightFence);
+        submitInfo.setSignalSemaphores( *m_renderFinishedSemaphores[m_currentFrame] );
+        m_graphicsQueue.submit(submitInfo, m_inFlightFences[m_currentFrame]);
 
         vk::PresentInfoKHR presentInfo;
-        presentInfo.setWaitSemaphores( *m_renderFinishedSemaphore );
+        presentInfo.setWaitSemaphores( *m_renderFinishedSemaphores[m_currentFrame] );
         presentInfo.setSwapchains( *m_swapChain );
         presentInfo.pImageIndices = &imageIndex;
         if (const auto res = m_presentQueue.presentKHR( presentInfo );
             res != vk::Result::eSuccess
         ) throw std::runtime_error{ "presentKHR in drawFrame was failed" };
 
+        m_currentFrame = (m_currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
     }
     /////////////////////////////////////////////////////////////
 };
