diff --git a/packages/database/prefix/prefix.go b/packages/database/prefix/prefix.go
index 005c6dfa31761c7edcd72199e3ff0d13f0d28691..ddfbad3bdfd918c73f48fdd7ba33b87b55acab9a 100644
--- a/packages/database/prefix/prefix.go
+++ b/packages/database/prefix/prefix.go
@@ -7,5 +7,5 @@ const (
 	DBPrefixTransactionMetadata
 	DBPrefixAddressTransactions
 	DBPrefixAutoPeering
-	DBPrefixDatabaseVersion
+	DBPrefixHealth
 )
diff --git a/packages/shutdown/order.go b/packages/shutdown/order.go
index 1efadc17b29c7e5d8e93efe729b7b7c88b28298e..0a85e6204f54e1627fdfdbac20a3cfb3dbaf1676 100644
--- a/packages/shutdown/order.go
+++ b/packages/shutdown/order.go
@@ -16,5 +16,4 @@ const (
 	PrioritySynchronization
 	PriorityBootstrap
 	PrioritySpammer
-	PriorityBadgerGarbageCollection
 )
diff --git a/plugins/database/health.go b/plugins/database/health.go
new file mode 100644
index 0000000000000000000000000000000000000000..af6a4770c9261245a2535a7f9f25798be046f2df
--- /dev/null
+++ b/plugins/database/health.go
@@ -0,0 +1,42 @@
+package database
+
+import (
+	"errors"
+	"fmt"
+
+	"github.com/iotaledger/goshimmer/packages/database/prefix"
+	"github.com/iotaledger/hive.go/kvstore"
+)
+
+var (
+	healthStore kvstore.KVStore
+	healthKey   = []byte("db_health")
+)
+
+func configureHealthStore(store kvstore.KVStore) {
+	healthStore = store.WithRealm([]byte{prefix.DBPrefixHealth})
+}
+
+// MarkDatabaseUnhealthy marks the database as not healthy, meaning
+// that it wasn't shutdown properly.
+func MarkDatabaseUnhealthy() {
+	if err := healthStore.Set(healthKey, []byte{}); err != nil {
+		panic(fmt.Errorf("failed to set database health state: %w", err))
+	}
+}
+
+// MarkDatabaseHealthy marks the database as healthy, respectively correctly closed.
+func MarkDatabaseHealthy() {
+	if err := healthStore.Delete(healthKey); err != nil && !errors.Is(err, kvstore.ErrKeyNotFound) {
+		panic(fmt.Errorf("failed to set database health state: %w", err))
+	}
+}
+
+// IsDatabaseUnhealthy tells whether the database is unhealthy, meaning not shutdown properly.
+func IsDatabaseUnhealthy() bool {
+	contains, err := healthStore.Has(healthKey)
+	if err != nil {
+		panic(fmt.Errorf("failed to set database health state: %w", err))
+	}
+	return contains
+}
diff --git a/plugins/database/plugin.go b/plugins/database/plugin.go
index 5035199e453da8dada28cf0a2ea490d9f29708b3..1886ddb2db1e35236952cf24282b55d17cbefce4 100644
--- a/plugins/database/plugin.go
+++ b/plugins/database/plugin.go
@@ -7,14 +7,12 @@ import (
 	"time"
 
 	"github.com/iotaledger/goshimmer/packages/database"
-	"github.com/iotaledger/goshimmer/packages/database/prefix"
 	"github.com/iotaledger/goshimmer/packages/shutdown"
 	"github.com/iotaledger/goshimmer/plugins/config"
 	"github.com/iotaledger/hive.go/daemon"
 	"github.com/iotaledger/hive.go/kvstore"
 	"github.com/iotaledger/hive.go/logger"
 	"github.com/iotaledger/hive.go/node"
-	"github.com/iotaledger/hive.go/timeutil"
 )
 
 // PluginName is the name of the database plugin.
@@ -22,7 +20,7 @@ const PluginName = "Database"
 
 var (
 	// Plugin is the plugin instance of the database plugin.
-	Plugin = node.NewPlugin(PluginName, node.Enabled, configure, run)
+	Plugin = node.NewPlugin(PluginName, node.Enabled, configure)
 	log    *logger.Logger
 
 	db        database.DB
@@ -52,7 +50,7 @@ func createStore() {
 		db, err = database.NewDB(dbDir)
 	}
 	if err != nil {
-		log.Fatal(err)
+		log.Fatal("Unable to open the database, please delete the database folder. Error: %s", err)
 	}
 
 	store = db.NewStore()
@@ -61,30 +59,38 @@ func createStore() {
 func configure(_ *node.Plugin) {
 	// assure that the store is initialized
 	store := Store()
+	configureHealthStore(store)
 
-	err := checkDatabaseVersion(store.WithRealm([]byte{prefix.DBPrefixDatabaseVersion}))
-	if errors.Is(err, ErrDBVersionIncompatible) {
-		log.Panicf("The database scheme was updated. Please delete the database folder.\n%s", err)
+	if err := checkDatabaseVersion(healthStore); err != nil {
+		if errors.Is(err, ErrDBVersionIncompatible) {
+			log.Fatalf("The database scheme was updated. Please delete the database folder. %s", err)
+		}
+		log.Fatalf("Failed to check database version: %s", err)
 	}
-	if err != nil {
-		log.Panicf("Failed to check database version: %s", err)
+
+	if IsDatabaseUnhealthy() {
+		log.Fatal("The database is marked as not properly shutdown/corrupted, please delete the database folder and restart.")
 	}
 
 	// we open the database in the configure, so we must also make sure it's closed here
-	err = daemon.BackgroundWorker(PluginName, closeDB, shutdown.PriorityDatabase)
-	if err != nil {
-		log.Panicf("Failed to start as daemon: %s", err)
+	if err := daemon.BackgroundWorker(PluginName, manageDBLifetime, shutdown.PriorityDatabase); err != nil {
+		log.Fatalf("Failed to start as daemon: %s", err)
 	}
-}
 
-func run(_ *node.Plugin) {
-	if err := daemon.BackgroundWorker(PluginName+"[GC]", runGC, shutdown.PriorityBadgerGarbageCollection); err != nil {
-		log.Panicf("Failed to start as daemon: %s", err)
-	}
+	// run GC up on startup
+	runDatabaseGC()
 }
 
-func closeDB(shutdownSignal <-chan struct{}) {
+// manageDBLifetime takes care of managing the lifetime of the database. It marks the database as dirty up on
+// startup and unmarks it up on shutdown. Up on shutdown it will run the db GC and then close the database.
+func manageDBLifetime(shutdownSignal <-chan struct{}) {
+	// we mark the database only as corrupted from within a background worker, which means
+	// that we only mark it as dirty, if the node actually started up properly (meaning no termination
+	// signal was received before all plugins loaded).
+	MarkDatabaseUnhealthy()
 	<-shutdownSignal
+	runDatabaseGC()
+	MarkDatabaseHealthy()
 	log.Infof("Syncing database to disk...")
 	if err := db.Close(); err != nil {
 		log.Errorf("Failed to flush the database: %s", err)
@@ -92,14 +98,15 @@ func closeDB(shutdownSignal <-chan struct{}) {
 	log.Infof("Syncing database to disk... done")
 }
 
-func runGC(shutdownSignal <-chan struct{}) {
+func runDatabaseGC() {
 	if !db.RequiresGC() {
 		return
 	}
-	// run the garbage collection with the given interval
-	timeutil.Ticker(func() {
-		if err := db.GC(); err != nil {
-			log.Warnf("Garbage collection failed: %s", err)
-		}
-	}, 5*time.Minute, shutdownSignal)
+	log.Info("Running database garbage collection...")
+	s := time.Now()
+	if err := db.GC(); err != nil {
+		log.Warnf("Database garbage collection failed: %s", err)
+		return
+	}
+	log.Infof("Database garbage collection done, took %v...", time.Since(s))
 }