diff --git a/indra/llmessage/lltemplatemessagebuilder.h b/indra/llmessage/lltemplatemessagebuilder.h
index 855ea871448ccc2cda079ad5b9a6a23e3bfdaadb..1026594153c4e0766898ddff1897631e47f63681 100644
--- a/indra/llmessage/lltemplatemessagebuilder.h
+++ b/indra/llmessage/lltemplatemessagebuilder.h
@@ -41,7 +41,7 @@ class LLTemplateMessageBuilder final : public LLMessageBuilder
 {
 public:
 	
-	typedef std::map<const char* , LLMessageTemplate*> message_template_name_map_t;
+	typedef boost::unordered_flat_map<const char* , LLMessageTemplate*> message_template_name_map_t;
 
 	LLTemplateMessageBuilder(const message_template_name_map_t&);
 	virtual ~LLTemplateMessageBuilder();
diff --git a/indra/llmessage/lltemplatemessagereader.h b/indra/llmessage/lltemplatemessagereader.h
index 5b4c532bf5789dab2a1ccc927dee078451131575..c0fbc45620907de0eda70c37db0d005991eb70eb 100644
--- a/indra/llmessage/lltemplatemessagereader.h
+++ b/indra/llmessage/lltemplatemessagereader.h
@@ -36,7 +36,7 @@ class LLTemplateMessageReader : public LLMessageReader
 {
 public:
 
-	typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t;
+	typedef boost::unordered_flat_map<U32, LLMessageTemplate*> message_template_number_map_t;
 
 	LLTemplateMessageReader(message_template_number_map_t&);
     ~LLTemplateMessageReader() override;
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index 04e526bc18e32ea4fc345720141625a5677e357f..b6b51c2c37de86e5405e059cf5580ed7b9d0404a 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -323,7 +323,7 @@ void LLMessageSystem::loadTemplateFile(const std::string& filename, bool failure
 LLMessageSystem::~LLMessageSystem()
 {
 	mMessageTemplates.clear(); // don't delete templates.
-	for_each(mMessageNumbers.begin(), mMessageNumbers.end(), DeletePairedPointer());
+	std::for_each(mMessageNumbers.begin(), mMessageNumbers.end(), DeletePairedPointer());
 	mMessageNumbers.clear();
 	
 	if (!mbError)
@@ -1573,7 +1573,7 @@ void LLMessageSystem::disableCircuit(const LLHost &host)
 		}
 
 		U64 ip_port = 0;
-		std::map<U32, U64>::iterator iter = gMessageSystem->mCircuitCodeToIPPort.find(code);
+		auto iter = gMessageSystem->mCircuitCodeToIPPort.find(code);
 		if (iter != gMessageSystem->mCircuitCodeToIPPort.end())
 		{
 			ip_port = iter->second;
diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h
index a4fda4e2527456ba149f20420c221a4755247ad9..d243db79409cb854ff2745cc9efcc23e9f405c3d 100644
--- a/indra/llmessage/message.h
+++ b/indra/llmessage/message.h
@@ -57,6 +57,7 @@
 
 #include "llstoredmessage.h"
 
+#include <boost/unordered/unordered_flat_map.hpp>
 #include <boost/signals2/connection.hpp>
 #include <boost/function.hpp>
 #include "llpounceable.h"
@@ -303,8 +304,8 @@ class LLMessageSystem : public LLMessageSenderInterface
 
 	F32                         mMessageFileVersionNumber;
 
-	typedef std::map<const char *, LLMessageTemplate*> message_template_name_map_t;
-	typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t;
+	typedef boost::unordered_flat_map<const char *, LLMessageTemplate*> message_template_name_map_t;
+	typedef boost::unordered_flat_map<U32, LLMessageTemplate*> message_template_number_map_t;
 
 	message_template_name_map_t		mMessageTemplates;
 	message_template_number_map_t	mMessageNumbers;
@@ -354,8 +355,8 @@ class LLMessageSystem : public LLMessageSenderInterface
 	F64Seconds			mCircuitPrintTime;	    // used to print circuit debug info every couple minutes
 	F32Seconds			mCircuitPrintFreq;	    
 
-	std::map<U64, U32>	mIPPortToCircuitCode;
-	std::map<U32, U64>	mCircuitCodeToIPPort;
+	boost::unordered_flat_map<U64, U32>	mIPPortToCircuitCode;
+	boost::unordered_flat_map<U32, U64>	mCircuitCodeToIPPort;
 	U32					mOurCircuitCode;
 	S32					mSendPacketFailureCount;
 	S32					mUnackedListDepth;
@@ -841,7 +842,7 @@ class LLMessageSystem : public LLMessageSenderInterface
 	
 	// The mCircuitCodes is a map from circuit codes to session
 	// ids. This allows us to verify sessions on connect.
-	typedef std::map<U32, LLUUID> code_session_map_t;
+	typedef boost::unordered_flat_map<U32, LLUUID> code_session_map_t;
 	code_session_map_t mCircuitCodes;
 
 	// Viewers need to track a process session in order to make sure
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 1d364610179bd84feef1fd2170108bb86d174f4b..0c25756019bf7e3e32567983c2f0cdcf5c5069de 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -215,7 +215,7 @@ class LLDrawable
 	friend class LLDrawPool;
 	friend class LLSpatialBridge;
 	
-	typedef std::unordered_set<LLPointer<LLDrawable> > drawable_set_t;
+	typedef boost::unordered_set<LLPointer<LLDrawable> > drawable_set_t;
     typedef std::set<LLPointer<LLDrawable> > ordered_drawable_set_t;
 	typedef std::vector<LLPointer<LLDrawable> > drawable_vector_t;
 	typedef std::list<LLPointer<LLDrawable> > drawable_list_t;
diff --git a/indra/newview/lleasymessagesender.cpp b/indra/newview/lleasymessagesender.cpp
index 681d3a8a1448e33ed63a6e6c41cb23d0ff53008d..c7ab8968f8bc4f233ff23a6df2eb4ecffe519fca 100644
--- a/indra/newview/lleasymessagesender.cpp
+++ b/indra/newview/lleasymessagesender.cpp
@@ -163,7 +163,7 @@ bool LLEasyMessageSender::sendLLUDPMessage(const LLHost& region_host, const std:
 	//Make sure everything's kosher with the message we built
 
 	//check if the message type is one that we know about
-	std::map<const char *, LLMessageTemplate*>::iterator template_iter=
+	auto template_iter=
 		gMessageSystem->mMessageTemplates.find( LLMessageStringTable::getInstance()->getString(message.c_str()) );
 	if (template_iter == gMessageSystem->mMessageTemplates.end())
 	{
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 9b2f08c88f4b5a97a1ed28e2ef1587571e814681..fe61b91a7fa67eb1596f5888241cdd36e12a868b 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -3546,6 +3546,7 @@ void LLMeshRepository::unregisterMesh(LLVOVolume* vobj, const LLUUID& mesh_id)
 		auto it = lod.find(mesh_id);
 		if(it != lod.end())
 		{
+			vobj->decMeshCache();
 			it->second.erase(vobj);
 			if (it->second.empty())
 			{
@@ -3560,6 +3561,7 @@ void LLMeshRepository::unregisterSkin(LLVOVolume* vobj, const LLUUID& mesh_id)
 	auto it = mLoadingSkins.find(mesh_id);
 	if (it != mLoadingSkins.end())
 	{
+		vobj->decSkinCache();
 		it->second.erase(vobj);
 		if(it->second.empty())
 		{
@@ -3589,11 +3591,13 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
 			auto& obj_set = iter->second;
 			auto it = obj_set.find(vobj);
 			if (it == obj_set.end()) {
+				vobj->incMeshCache();
 				obj_set.insert(vobj);
 			}
 		}
 		else
 		{
+			vobj->incMeshCache();
 			LLMutexLock lock(mMeshMutex);
 			//first request for this mesh
 			mLoadingMeshes[detail][mesh_id].insert(vobj);
@@ -3942,6 +3946,7 @@ void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo* info)
 		{
 			if (vobj)
 			{
+				vobj->decSkinCache();
 				vobj->notifySkinInfoLoaded(info);
 			}
 		}
@@ -3958,6 +3963,7 @@ void LLMeshRepository::notifySkinInfoUnavailable(const LLUUID& mesh_id)
 		{
 			if (vobj)
 			{
+				vobj->decSkinCache();
 				vobj->notifySkinInfoUnavailable();
 			}
 		}
@@ -4040,6 +4046,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
 		{
 			if (vobj)
 			{
+				vobj->decMeshCache();
 				vobj->notifyMeshLoaded();
 			}
 		}
@@ -4070,6 +4077,8 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params,
 		{
 			if (vobj)
 			{
+				vobj->decMeshCache();
+
 				LLVolume* obj_volume = vobj->getVolume();
 
 				if (obj_volume && 
@@ -4111,11 +4120,14 @@ LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOVolume*
 				auto& obj_set = iter->second;
 				auto it = obj_set.find(requesting_obj);
 				if (it == obj_set.end()) {
+					requesting_obj->incSkinCache();
 					obj_set.insert(requesting_obj);
 				}
 			}
 			else
 			{
+				requesting_obj->incSkinCache();
+
 				LLMutexLock lock(mMeshMutex);
 				//first request for this mesh
 				mLoadingSkins[mesh_id].insert(requesting_obj);
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index d9df459fdc937c49a27c0ca713d918f888de9b85..25a4f1f2afe7d4f87149023ec9ac549ec75acc30 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -1384,16 +1384,25 @@ void LLViewerObjectList::clearDebugText()
 void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
 {
 	LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
-
-	bool new_dead_object = true;
-	if (mDeadObjects.find(objectp->mID) != mDeadObjects.end())
-	{
-		LL_INFOS() << "Object " << objectp->mID << " already on dead list!" << LL_ENDL;	
-		new_dead_object = false;
-	}
-	else
-	{
-		mDeadObjects.insert(objectp->mID);
+	// <FS:Beq> FIRE-30694 DeadObject Spam - handle new_dead_object properly and closer to source
+	// bool new_dead_object = true;
+	//if (mDeadObjects.find(objectp->mID) != mDeadObjects.end())
+	//{
+	//// <FS:Beq> FIRE-30694 DeadObject Spam
+	//// LL_INFOS() << "Object " << objectp->mID << " already on dead list!" << LL_ENDL;	
+	//// 	new_dead_object = false;
+	//	LL_DEBUGS() << "Object " << objectp->mID << " already on dead list!" << LL_ENDL;	
+	//// </FS:Beq>
+	//}
+	//// <FS:Beq> detect but still delete dupes
+	//// else
+	{
+	// <FS:Beq> FIRE-30694 DeadObject Spam
+	// 	mDeadObjects.insert(objectp->mID);
+		mDeadObjects.insert( objectp->mID );
+		mNumDeadObjects++;
+		llassert( mNumDeadObjects == mDeadObjects.size() );
+	// </FS:Beq>
 	}
 
 	// Cleanup any references we have to this object
@@ -1428,11 +1437,6 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
 	}
 
 	// Don't clean up mObject references, these will be cleaned up more efficiently later!
-	
-	if(new_dead_object)
-	{
-		mNumDeadObjects++;
-	}
 }
 
 BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)
@@ -1527,7 +1531,11 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)
     LL_PROFILE_ZONE_SCOPED;
 
 	S32 num_removed = 0;
+	S32 num_divergent = 0;
 	LLViewerObject *objectp;
+
+	static const F64 max_time = 0.01; // Let's try 10ms per frame
+	LLTimer timer;
 	
 	vobj_list_t::reverse_iterator target = mObjects.rbegin();
 
@@ -1543,12 +1551,24 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)
 
 		if (objectp->isDead())
 		{
+			// mDeadObjects.erase(objectp->mID); // <FS:Ansariel> Use timer for cleaning up dead objects
+            auto delete_me = mDeadObjects.find(objectp->mID);
+            if( delete_me != mDeadObjects.end() )
+            {
+                mDeadObjects.erase( delete_me );
+            }
+            else
+            {
+				LL_WARNS() << "Attempt to delete object " << objectp->mID << " but object not in dead list" << LL_ENDL;
+				num_divergent++; // this is the number we are adrift in the count
+            }
 			LLPointer<LLViewerObject>::swap(*iter, *target);
 			*target = nullptr;
 			++target;
 			num_removed++;
 
-			if (num_removed == mNumDeadObjects || iter->isNull())
+			//if (num_removed == mNumDeadObjects || iter->isNull())
+			if (num_removed == mNumDeadObjects || iter->isNull() || (use_timer && timer.getElapsedTimeF64() > max_time))
 			{
 				// We've cleaned up all of the dead objects or caught up to the dead tail
 				break;
@@ -1560,15 +1580,25 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)
 		}
 	}
 
-	llassert(num_removed == mNumDeadObjects);
+	// <FS:Ansariel> Use timer for cleaning up dead objects
+	//llassert(num_removed == mNumDeadObjects);
 
 	//erase as a block
-	mObjects.erase(mObjects.begin()+(mObjects.size()-mNumDeadObjects), mObjects.end());
+	//mObjects.erase(mObjects.begin()+(mObjects.size()-mNumDeadObjects), mObjects.end());
 
 	// We've cleaned the global object list, now let's do some paranoia testing on objects
 	// before blowing away the dead list.
-	mDeadObjects.clear();
-	mNumDeadObjects = 0;
+	//mDeadObjects.clear();
+	//mNumDeadObjects = 0;
+	mObjects.erase(mObjects.begin()+(mObjects.size()-num_removed), mObjects.end());
+	mNumDeadObjects -= num_removed;
+
+	// TODO(Beq) If this still happens, we ought to realign at this point. Do a full sweep and reset.
+	if ( mNumDeadObjects != mDeadObjects.size() )
+	{
+		LL_WARNS_ONCE() << "Num dead objects (" << mNumDeadObjects << ") != dead object list size (" << mDeadObjects.size() << "),  deadlist discrepancy (" << num_divergent << ")" << LL_ENDL;
+	}
+	// </FS:Ansariel>
 }
 
 void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp)
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index bd814362b1ba6ef9d3bf9907ad61ac3b5d46d8b4..db4eaa456ad1b42a8d7ed1001f49c2ac581b05c0 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -209,7 +209,7 @@ class LLViewerObjectList
 	vobj_list_t mMapObjects;
 
 
-	using uuid_hash_set_t = boost::unordered_set<LLUUID>;
+	using uuid_hash_set_t = boost::unordered_multiset<LLUUID>;
     uuid_hash_set_t   mDeadObjects;
 
 	boost::unordered_flat_map<LLUUID, LLPointer<LLViewerObject> > mUUIDObjectMap;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index b699e6a3bf7793e55fb19311fa6ca75c780308aa..126ffa0b45a10b2bdeec9ca480f0c245a93e3857 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -10748,6 +10748,10 @@ void LLVOAvatar::updateRiggingInfo()
 
     static std::vector<LLVOVolume*> volumes;
 	volumes.clear();
+	if (volumes.capacity() < mLastAssocVolSize)
+	{
+		volumes.reserve(mLastAssocVolSize);
+	}
 	getAssociatedVolumes(volumes);
     mLastAssocVolSize = volumes.size();
 
@@ -11273,9 +11277,6 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
 		F32 max_attachment_complexity = max_complexity_setting;
 		max_attachment_complexity = llmax(max_attachment_complexity, DEFAULT_MAX_ATTACHMENT_COMPLEXITY);
 
-		// Diagnostic list of all textures on our avatar
-        static std::unordered_set<const LLViewerTexture*> all_textures;
-
 		std::map<LLUUID, U32> item_complexity;
 		std::map<LLUUID, U32> temp_item_complexity;
 		U32 body_parts_complexity;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index c8b98a19dd81a0f7e14b5dbe68b2dc3bb74415eb..13505a5493bfb74a09f2626ae03bd9b78d0b77d3 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -258,8 +258,13 @@ LLVOVolume::~LLVOVolume()
 
 	mSkinInfo = nullptr;
 
+	if (mFetchingMesh > 0)
 	{
 		gMeshRepo.unregisterMesh(this, getVolume()->getParams().getSculptID());
+	}
+
+	if(mFetchingSkinInfo > 0)
+	{
 		gMeshRepo.unregisterSkin(this, getVolume()->getParams().getSculptID());
 	}
 
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 2337c6abc0f6798e132a577abfaead7a69d97d3b..d17a7a95a589350d74d78beaf338a948f0d0f6eb 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -450,6 +450,11 @@ class LLVOVolume final : public LLViewerObject
     F32 mLODDistance;
     F32 mLODAdjustedDistance;
     F32 mLODRadius;
+
+	void incMeshCache() { mFetchingMesh++; }
+	void incSkinCache() { mFetchingSkinInfo++; }
+	void decMeshCache() { mFetchingMesh--; }
+	void decSkinCache() { mFetchingSkinInfo--; }
 private:
 	friend class LLDrawable;
 	friend class LLFace;
@@ -485,6 +490,8 @@ class LLVOVolume final : public LLViewerObject
 
 	LLPointer<LLRiggedVolume> mRiggedVolume;
 
+	S32 mFetchingMesh = 0;
+	S32 mFetchingSkinInfo = 0;
 	bool mSkinInfoUnavaliable;
 	LLConstPointer<LLMeshSkinInfo> mSkinInfo;
 	// statics
diff --git a/indra/newview/skins/default/xui/en/floater_adjust_environment.xml b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml
index f1fd696ec6740988a6bc5964e2019615d0d10532..40c24b478d90ace3fe210d2177c453416146fc62 100644
--- a/indra/newview/skins/default/xui/en/floater_adjust_environment.xml
+++ b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml
@@ -12,7 +12,7 @@
          can_resize="false">
   <string name="hdr_string">HDR Scale:</string>
   <string name="brightness_string">Brightness:</string>
-  <string name="hdr_tooltip">Intensity of lightning effects such as realistically bright skies and dynamic exposure. 1.0 is the default, 0 is off, values between 0 and 1 are mixing Ambient with HDR.</string>
+  <string name="hdr_tooltip">Intensity of lighting effects such as realistically bright skies and dynamic exposure. 1.0 is the default, 0 is off, values between 0 and 1 are mixing Ambient with HDR.</string>
     <layout_stack name="outer_stack"
                   width="845"
                   height="275"
diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
index 75d50b698a10c5715cbcfd17948caedd44f7d93c..41c48f8ca2991532b052a4bd59a578542383264e 100644
--- a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
+++ b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
@@ -9,7 +9,7 @@
         top="0">
   <string name="hdr_string">HDR Scale:</string>
   <string name="brightness_string">Brightness:</string>
-  <string name="hdr_tooltip">Intensity of lightning effects such as realistically bright skies and dynamic exposure. 1.0 is the default, 0 is off, values between 0 and 1 are mixing Ambient with HDR.</string>
+  <string name="hdr_tooltip">Intensity of lighting effects such as realistically bright skies and dynamic exposure. 1.0 is the default, 0 is off, values between 0 and 1 are mixing Ambient with HDR.</string>
     <layout_stack
             name="main_ls"
             follows="all"