diff --git a/include/proxy-wasm/v8.h b/include/proxy-wasm/v8.h
index 73c91b95..5531f52c 100644
--- a/include/proxy-wasm/v8.h
+++ b/include/proxy-wasm/v8.h
@@ -21,6 +21,7 @@
 
 namespace proxy_wasm {
 
+bool initV8Engine();
 std::unique_ptr<WasmVm> createV8Vm();
 
 } // namespace proxy_wasm
diff --git a/include/proxy-wasm/wamr.h b/include/proxy-wasm/wamr.h
index 98ff72e3..32a05e94 100644
--- a/include/proxy-wasm/wamr.h
+++ b/include/proxy-wasm/wamr.h
@@ -21,6 +21,7 @@
 
 namespace proxy_wasm {
 
+bool initWamrEngine();
 std::unique_ptr<WasmVm> createWamrVm();
 
 } // namespace proxy_wasm
diff --git a/include/proxy-wasm/wasmtime.h b/include/proxy-wasm/wasmtime.h
index e3fe4b48..11c4ae7a 100644
--- a/include/proxy-wasm/wasmtime.h
+++ b/include/proxy-wasm/wasmtime.h
@@ -18,6 +18,7 @@
 
 namespace proxy_wasm {
 
+bool initWasmtimeEngine();
 std::unique_ptr<WasmVm> createWasmtimeVm();
 
 } // namespace proxy_wasm
diff --git a/src/v8/v8.cc b/src/v8/v8.cc
index 2d8660bc..755f2e96 100644
--- a/src/v8/v8.cc
+++ b/src/v8/v8.cc
@@ -747,6 +747,8 @@ std::string V8::getFailMessage(std::string_view function_name, wasm::own<wasm::T
 
 } // namespace v8
 
+bool initV8Engine() { return v8::engine() != nullptr; }
+
 std::unique_ptr<WasmVm> createV8Vm() { return std::make_unique<v8::V8>(); }
 
 } // namespace proxy_wasm
diff --git a/src/wamr/wamr.cc b/src/wamr/wamr.cc
index e193358c..de7b506d 100644
--- a/src/wamr/wamr.cc
+++ b/src/wamr/wamr.cc
@@ -644,6 +644,8 @@ void Wamr::getModuleFunctionImpl(std::string_view function_name,
 
 } // namespace wamr
 
+bool initWamrEngine() { return wamr::engine() != nullptr; }
+
 std::unique_ptr<WasmVm> createWamrVm() { return std::make_unique<wamr::Wamr>(); }
 
 } // namespace proxy_wasm
diff --git a/src/wasmtime/wasmtime.cc b/src/wasmtime/wasmtime.cc
index 040dea07..cc9ea8d6 100644
--- a/src/wasmtime/wasmtime.cc
+++ b/src/wasmtime/wasmtime.cc
@@ -694,6 +694,8 @@ void Wasmtime::getModuleFunctionImpl(std::string_view function_name,
 
 } // namespace wasmtime
 
+bool initWasmtimeEngine() { return wasmtime::engine() != nullptr; }
+
 std::unique_ptr<WasmVm> createWasmtimeVm() { return std::make_unique<wasmtime::Wasmtime>(); }
 
 } // namespace proxy_wasm
diff --git a/test/wasm_vm_test.cc b/test/wasm_vm_test.cc
index 642ea636..92c0ea6d 100644
--- a/test/wasm_vm_test.cc
+++ b/test/wasm_vm_test.cc
@@ -30,6 +30,46 @@ INSTANTIATE_TEST_SUITE_P(WasmEngines, TestVm, testing::ValuesIn(getWasmEngines()
                            return info.param;
                          });
 
+TEST_P(TestVm, Init) {
+  std::chrono::time_point<std::chrono::steady_clock> time2;
+
+  auto time1 = std::chrono::steady_clock::now();
+  if (engine_ == "v8") {
+#if defined(PROXY_WASM_HOST_ENGINE_V8)
+    EXPECT_TRUE(proxy_wasm::initV8Engine());
+    time2 = std::chrono::steady_clock::now();
+    EXPECT_TRUE(proxy_wasm::initV8Engine());
+#endif
+  } else if (engine_ == "wamr") {
+#if defined(PROXY_WASM_HOST_ENGINE_WAMR)
+    EXPECT_TRUE(proxy_wasm::initWamrEngine());
+    time2 = std::chrono::steady_clock::now();
+    EXPECT_TRUE(proxy_wasm::initWamrEngine());
+#endif
+  } else if (engine_ == "wasmtime") {
+#if defined(PROXY_WASM_HOST_ENGINE_WASMTIME)
+    EXPECT_TRUE(proxy_wasm::initWasmtimeEngine());
+    time2 = std::chrono::steady_clock::now();
+    EXPECT_TRUE(proxy_wasm::initWasmtimeEngine());
+#endif
+  } else {
+    return;
+  }
+  auto time3 = std::chrono::steady_clock::now();
+
+  auto cold = std::chrono::duration_cast<std::chrono::nanoseconds>(time2 - time1).count();
+  auto warm = std::chrono::duration_cast<std::chrono::nanoseconds>(time3 - time2).count();
+
+  std::cout << "\"cold\" engine time: " << cold << "ns" << std::endl;
+  std::cout << "\"warm\" engine time: " << warm << "ns" << std::endl;
+
+  // Verify that getting a "warm" engine takes less than 10us.
+  EXPECT_LE(warm, 10000);
+
+  // Verify that getting a "warm" engine takes at least 50x less time than getting a "cold" one.
+  EXPECT_LE(warm * 50, cold);
+}
+
 TEST_P(TestVm, Basic) {
   if (engine_ == "wamr" || engine_ == "wasmedge") {
     EXPECT_EQ(vm_->cloneable(), proxy_wasm::Cloneable::NotCloneable);