diff --git a/include/vector.h b/include/vector.h
index 4b8f73e..401a026 100644
--- a/include/vector.h
+++ b/include/vector.h
@@ -91,35 +91,35 @@ public:
         }
     }
 
-    // Cold path: only taken on growth
     UFV_COLD void reserve_grow(size_type minNeeded) {
         size_type oldSize = size();
+        size_type oldCap = capacity();
+        size_type newCap = std::bit_ceil(minNeeded);
+    
         if constexpr (POD_PATH) {
-            size_type newCap = capacity() ? capacity() * 2 : 1;
-            while (newCap < minNeeded) newCap <<= 1;
+            if (newCap == oldCap) return;
             void* blk = _b
-                       ? std::realloc(_b, newCap * sizeof(T))
-                       : std::malloc (newCap * sizeof(T));
+                      ? std::realloc(_b, newCap * sizeof(T))
+                      : std::malloc (newCap * sizeof(T));
             if (!blk) throw std::bad_alloc();
             _b   = static_cast<T*>(blk);
             _e   = _b + oldSize;
             _cap = _b + newCap;
         } else {
-            size_type newCap = capacity() ? capacity() * 2 : 1;
-            while (newCap < minNeeded) newCap <<= 1;
             T* newB = alloc_traits::allocate(_alloc, newCap);
             if constexpr (std::is_nothrow_move_constructible_v<T>) {
                 std::uninitialized_move(_b, _e, newB);
             } else {
                 std::uninitialized_copy(_b, _e, newB);
             }
-            clear();
-            if (_b) alloc_traits::deallocate(_alloc, _b, capacity());
+            std::destroy(_b, _e); // only if not using clear()
+            if (_b) alloc_traits::deallocate(_alloc, _b, oldCap);
             _b   = newB;
             _e   = newB + oldSize;
             _cap = newB + newCap;
         }
     }
+    
 
     UFV_ALWAYS_INLINE void reserve(size_type n) {
         if (n > capacity()) reserve_grow(n);