diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp
index dbaaddb575..50cec4ee6a 100644
--- a/src/company_cmd.cpp
+++ b/src/company_cmd.cpp
@@ -203,16 +203,34 @@ static bool IsValidCompanyManagerFace(CompanyManagerFace cmf)
 	return true;
 }
 
+static CompanyMask _dirty_company_finances{}; ///< Bitmask of compamy finances that should be marked dirty.
+
 /**
- * Refresh all windows owned by a company.
+ * Mark all finance windows owned by a company as needing a refresh.
+ * The actual refresh is deferred until the end of the gameloop to reduce duplicated work.
  * @param company Company that changed, and needs its windows refreshed.
  */
 void InvalidateCompanyWindows(const Company *company)
 {
 	CompanyID cid = company->index;
+	_dirty_company_finances.Set(cid);
+}
 
-	if (cid == _local_company) SetWindowWidgetDirty(WC_STATUS_BAR, 0, WID_S_RIGHT);
-	SetWindowDirty(WC_FINANCES, cid);
+/**
+ * Refresh all company finance windows previously marked dirty.
+ */
+void InvalidateCompanyWindows()
+{
+	for (CompanyID cid : _dirty_company_finances) {
+		if (cid == _local_company) SetWindowWidgetDirty(WC_STATUS_BAR, 0, WID_S_RIGHT);
+		Window *w = FindWindowById(WC_FINANCES, cid);
+		if (w != nullptr) {
+			w->SetWidgetDirty(WID_CF_EXPS_PRICE3);
+			w->SetWidgetDirty(WID_CF_OWN_VALUE);
+			w->SetWidgetDirty(WID_CF_BALANCE_VALUE);
+		}
+	}
+	_dirty_company_finances = {};
 }
 
 /**
diff --git a/src/company_gui.h b/src/company_gui.h
index f6149b05fb..0e951eb5c7 100644
--- a/src/company_gui.h
+++ b/src/company_gui.h
@@ -23,6 +23,7 @@ void ShowCompanyFinances(CompanyID company);
 void ShowCompany(CompanyID company);
 
 void InvalidateCompanyWindows(const Company *c);
+void InvalidateCompanyWindows();
 void CloseCompanyWindows(CompanyID company);
 void DirtyCompanyInfrastructureWindows(CompanyID company);
 
diff --git a/src/openttd.cpp b/src/openttd.cpp
index d095f23b01..617c9cafc4 100644
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -27,6 +27,7 @@
 #include "saveload/saveload.h"
 #include "company_cmd.h"
 #include "company_func.h"
+#include "company_gui.h"
 #include "command_func.h"
 #include "news_func.h"
 #include "fios.h"
@@ -1229,6 +1230,7 @@ void StateGameLoop()
 
 		CallWindowGameTickEvent();
 		NewsLoop();
+		InvalidateCompanyWindows();
 	} else {
 		if (_debug_desync_level > 2 && TimerGameEconomy::date_fract == 0 && (TimerGameEconomy::date.base() & 0x1F) == 0) {
 			/* Save the desync savegame if needed. */
@@ -1265,6 +1267,7 @@ void StateGameLoop()
 
 		CallWindowGameTickEvent();
 		NewsLoop();
+		InvalidateCompanyWindows();
 		cur_company.Restore();
 	}