diff --git a/perf/memtx.cc b/perf/memtx.cc
index 360a9b12efc07fd2e2c85e1c382c05eb274289c6..1128a663a18ea4cb16f54a8743f5f8cacb1df044 100644
--- a/perf/memtx.cc
+++ b/perf/memtx.cc
@@ -188,7 +188,7 @@ class Memtx final {
 		::user_cache_free();
 		::space_cache_destroy();
 
-		memtx->base.vtab->shutdown(&memtx->base);
+		memtx->base.vtab->free(&memtx->base);
 		::tuple_free();
 		::txn_event_trigger_free();
 
diff --git a/src/box/blackhole.c b/src/box/blackhole.c
index 83e1d8bb96d6106f2d86e436a651823dea629f9a..8056504284c2fdf9be3df9fdd5b784059656f28b 100644
--- a/src/box/blackhole.c
+++ b/src/box/blackhole.c
@@ -132,7 +132,7 @@ static const struct space_vtab blackhole_space_vtab = {
 };
 
 static void
-blackhole_engine_shutdown(struct engine *engine)
+blackhole_engine_free(struct engine *engine)
 {
 	free(engine);
 }
@@ -173,7 +173,8 @@ blackhole_engine_create_space(struct engine *engine, struct space_def *def,
 }
 
 static const struct engine_vtab blackhole_engine_vtab = {
-	/* .shutdown = */ blackhole_engine_shutdown,
+	/* .free = */ blackhole_engine_free,
+	/* .shutdown = */ generic_engine_shutdown,
 	/* .create_space = */ blackhole_engine_create_space,
 	/* .create_read_view = */ generic_engine_create_read_view,
 	/* .prepare_join = */ generic_engine_prepare_join,
diff --git a/src/box/box.cc b/src/box/box.cc
index 5de28463f41054a99af2791b61ae57ddb876ca08..4985f5a472eabfffecb2b51b9feb2cbaf765f3ee 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -5913,7 +5913,7 @@ box_storage_free(void)
 	iproto_free();
 	replication_free();
 	gc_free();
-	engine_shutdown();
+	engine_free();
 	/* schema_free(); */
 	wal_free();
 	flightrec_free();
@@ -5980,6 +5980,7 @@ box_storage_shutdown()
 	fiber_shutdown();
 	replication_shutdown();
 	gc_shutdown();
+	engine_shutdown();
 }
 
 void
diff --git a/src/box/engine.c b/src/box/engine.c
index 239e4e26013dab2bc889a8879eeb81ada5caf8fa..1348d428a1fc379887f62fe09b5842146cba8793 100644
--- a/src/box/engine.c
+++ b/src/box/engine.c
@@ -77,6 +77,15 @@ engine_shutdown(void)
 	}
 }
 
+void
+engine_free(void)
+{
+	struct engine *engine, *tmp;
+	rlist_foreach_entry_safe(engine, &engines, link, tmp) {
+		engine->vtab->free(engine);
+	}
+}
+
 void
 engine_switch_to_ro(void)
 {
@@ -467,4 +476,10 @@ generic_engine_check_space_def(struct space_def *def)
 	return 0;
 }
 
+void
+generic_engine_shutdown(struct engine *engine)
+{
+	(void)engine;
+}
+
 /* }}} */
diff --git a/src/box/engine.h b/src/box/engine.h
index 81d221778b5c4241d0d95f3c51283a1aa4a58eb5..870f4d4cef195bcfdfb8bc5ab070e5e8d428bf73 100644
--- a/src/box/engine.h
+++ b/src/box/engine.h
@@ -93,6 +93,11 @@ engine_backup_cb(const char *path, void *arg);
 
 struct engine_vtab {
 	/** Destroy an engine instance. */
+	void (*free)(struct engine *);
+	/**
+	 * Shutdown an engine instance. Shutdown stops all internal
+	 * fibers/threads. It may yield.
+	 */
 	void (*shutdown)(struct engine *);
 	/** Allocate a new space instance. */
 	struct space *(*create_space)(struct engine *engine,
@@ -396,11 +401,18 @@ engine_read_view_delete(struct engine_read_view *rv)
 }
 
 /**
- * Shutdown all engine factories.
+ * Shutdown all engines. Shutdown stops all internal fibers/threads.
+ * It may yield.
  */
 void
 engine_shutdown(void);
 
+/**
+ * Free all engines.
+ */
+void
+engine_free(void);
+
 /**
  * Called before switching the instance to read-only mode.
  */
@@ -504,6 +516,7 @@ int generic_engine_backup(struct engine *, const struct vclock *,
 void generic_engine_memory_stat(struct engine *, struct engine_memory_stat *);
 void generic_engine_reset_stat(struct engine *);
 int generic_engine_check_space_def(struct space_def *);
+void generic_engine_shutdown(struct engine *engine);
 
 #if defined(__cplusplus)
 } /* extern "C" */
diff --git a/src/box/memtx_engine.cc b/src/box/memtx_engine.cc
index 61b86ae0564bece11c4054da35b71cce10a1fd48..ad2781e8fe9f206e3b9b7c6f43843315be6bc806 100644
--- a/src/box/memtx_engine.cc
+++ b/src/box/memtx_engine.cc
@@ -192,7 +192,7 @@ memtx_build_secondary_keys(struct space *space, void *param)
 }
 
 static void
-memtx_engine_shutdown(struct engine *engine)
+memtx_engine_free(struct engine *engine)
 {
 	struct memtx_engine *memtx = (struct memtx_engine *)engine;
 	mempool_destroy(&memtx->iterator_pool);
@@ -1370,7 +1370,8 @@ memtx_engine_memory_stat(struct engine *engine, struct engine_memory_stat *stat)
 }
 
 static const struct engine_vtab memtx_engine_vtab = {
-	/* .shutdown = */ memtx_engine_shutdown,
+	/* .free = */ memtx_engine_free,
+	/* .shutdown = */ generic_engine_shutdown,
 	/* .create_space = */ memtx_engine_create_space,
 	/* .create_read_view = */ memtx_engine_create_read_view,
 	/* .prepare_join = */ memtx_engine_prepare_join,
diff --git a/src/box/service_engine.c b/src/box/service_engine.c
index af48c36dba9e5ff21a0f97f89121b049d193d3f8..c60c8f1ddb7207359a718305d812643966b19624 100644
--- a/src/box/service_engine.c
+++ b/src/box/service_engine.c
@@ -37,7 +37,7 @@
 extern const struct space_vtab session_settings_space_vtab;
 
 static void
-service_engine_shutdown(struct engine *engine)
+service_engine_free(struct engine *engine)
 {
 	free(engine);
 }
@@ -88,7 +88,8 @@ service_engine_create_space(struct engine *engine, struct space_def *def,
 }
 
 static const struct engine_vtab service_engine_vtab = {
-	/* .shutdown = */ service_engine_shutdown,
+	/* .free = */ service_engine_free,
+	/* .shutdown = */ generic_engine_shutdown,
 	/* .create_space = */ service_engine_create_space,
 	/* .create_read_view = */ generic_engine_create_read_view,
 	/* .prepare_join = */ generic_engine_prepare_join,
diff --git a/src/box/sysview.c b/src/box/sysview.c
index dfd20c96c78e45125dbfb457c17923c813dea28a..35cf947c6c0edb4f01fbd16c27bd5b6587a0dd57 100644
--- a/src/box/sysview.c
+++ b/src/box/sysview.c
@@ -510,7 +510,7 @@ static const struct space_vtab sysview_space_vtab = {
 };
 
 static void
-sysview_engine_shutdown(struct engine *engine)
+sysview_engine_free(struct engine *engine)
 {
 	struct sysview_engine *sysview = (struct sysview_engine *)engine;
 	if (mempool_is_initialized(&sysview->iterator_pool))
@@ -557,7 +557,8 @@ sysview_engine_create_space(struct engine *engine, struct space_def *def,
 }
 
 static const struct engine_vtab sysview_engine_vtab = {
-	/* .shutdown = */ sysview_engine_shutdown,
+	/* .free = */ sysview_engine_free,
+	/* .shutdown = */ generic_engine_shutdown,
 	/* .create_space = */ sysview_engine_create_space,
 	/* .create_read_view = */ generic_engine_create_read_view,
 	/* .prepare_join = */ generic_engine_prepare_join,
diff --git a/src/box/vinyl.c b/src/box/vinyl.c
index 95c8d5df55948731311cbceba35f8234bdc383ed..8e35269954f49d4e5d8c01ed07a6df6c7a8ba0c0 100644
--- a/src/box/vinyl.c
+++ b/src/box/vinyl.c
@@ -2720,7 +2720,7 @@ vinyl_engine_new(const char *dir, size_t memory,
 }
 
 static void
-vinyl_engine_shutdown(struct engine *engine)
+vinyl_engine_free(struct engine *engine)
 {
 	struct vy_env *env = vy_env(engine);
 	vy_env_delete(env);
@@ -4585,7 +4585,8 @@ static TRIGGER(on_replace_vinyl_deferred_delete, vy_deferred_delete_on_replace);
 /* }}} Deferred DELETE handling */
 
 static const struct engine_vtab vinyl_engine_vtab = {
-	/* .shutdown = */ vinyl_engine_shutdown,
+	/* .free = */ vinyl_engine_free,
+	/* .shutdown = */ generic_engine_shutdown,
 	/* .create_space = */ vinyl_engine_create_space,
 	/* .create_read_view = */ generic_engine_create_read_view,
 	/* .prepare_join = */ vinyl_engine_prepare_join,