diff --git a/tool/net/help.txt b/tool/net/help.txt
index 84db6da0c..00b66b52d 100644
--- a/tool/net/help.txt
+++ b/tool/net/help.txt
@@ -499,7 +499,7 @@ SPECIAL PATHS
           this path is a hidden file so that it can't be unintentionally run
           by the network client.
 
-  /.reload.lua
+  /.reload.lua (deprecated; use OnServerReload instead)
           This script is run from the main process when SIGHUP is received.
           This only applies to redbean when running in daemon mode. Any
           changes that are made to the Lua interpreter state will be
@@ -612,6 +612,12 @@ HOOKS
           to modify socket configuration to set `SO_REUSEPORT`, for example.
           If it returns `true`, redbean will not listen to that ip/port.
 
+  OnServerReload(reindex:bool)
+          If this function is defined it'll be called from the main process
+          on each server reload triggered by SIGHUP (for deamonized) and
+          SIGUSR1 (for all) redbean instances. reindex indicates if redbean
+          assets have been re-indexed following the signal.
+
   OnServerStart()
           If this function is defined it'll be called from the main process
           right before the main event loop starts.
diff --git a/tool/net/redbean.c b/tool/net/redbean.c
index 250457875..eb902e877 100644
--- a/tool/net/redbean.c
+++ b/tool/net/redbean.c
@@ -5560,11 +5560,20 @@ static void LuaInit(void) {
 #endif
 }
 
-static void LuaReload(void) {
+static void LuaOnServerReload(bool reindex) {
 #ifndef STATIC
   if (!LuaRunAsset("/.reload.lua", false)) {
     DEBUGF("(srvr) no /.reload.lua defined");
   }
+
+  lua_State *L = GL;
+  lua_getglobal(L, "OnServerReload");
+  lua_pushboolean(L, reindex);
+  if (LuaCallWithTrace(L, 1, 0, NULL) != LUA_OK) {
+    LogLuaError("OnServerReload", lua_tostring(L, -1));
+    lua_pop(L, 1);  // pop error
+  }
+  AssertLuaStackIsAt(L, 0);
 #endif
 }
 
@@ -5754,8 +5763,8 @@ static void HandleFrag(size_t got) {
 
 static void HandleReload(void) {
   LockInc(&shared->c.reloads);
-  Reindex();
-  LuaReload();
+  LuaOnServerReload(Reindex());
+  invalidated = false;
 }
 
 static void HandleHeartbeat(void) {
@@ -6506,7 +6515,6 @@ static void HandleMessages(void) {
       }
       if (invalidated) {
         HandleReload();
-        invalidated = false;
       }
     }
     if (cpm.msgsize == amtread) {
@@ -6537,7 +6545,6 @@ static void HandleMessages(void) {
     CollectGarbage();
     if (invalidated) {
       HandleReload();
-      invalidated = false;
     }
   }
 }
@@ -7135,7 +7142,6 @@ int EventLoop(int ms) {
       lua_repl_lock();
       HandleReload();
       lua_repl_unlock();
-      invalidated = false;
     } else if (meltdown) {
       lua_repl_lock();
       EnterMeltdownMode();