diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index 253b0c124ecd555cfd3c5da7fef5c1168230a0c7..ffd7f1f1af6ca869d86876870c2a8d468d464609 100644
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -55,6 +55,8 @@
 #define MATERIALS_GET_TIMEOUT                     (60.f * 20)
 #define MATERIALS_POST_MAX_ENTRIES                50
 #define MATERIALS_POST_TIMEOUT                    (60.f * 5)
+#define MATERIALS_PUT_THROTTLE_SECS               1.f
+#define MATERIALS_PUT_MAX_ENTRIES                 50
 
 /**
  * LLMaterialsResponder helper class
@@ -122,12 +124,25 @@ LLMaterialMgr::~LLMaterialMgr()
 	gIdleCallbacks.deleteFunction(&LLMaterialMgr::onIdle, NULL);
 }
 
-bool LLMaterialMgr::isGetPending(const LLUUID& region_id, const LLMaterialID& material_id)
+bool LLMaterialMgr::isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const
 {
 	get_pending_map_t::const_iterator itPending = mGetPending.find(pending_material_t(region_id, material_id));
 	return (mGetPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_POST_TIMEOUT);
 }
 
+void LLMaterialMgr::markGetPending(const LLUUID& region_id, const LLMaterialID& material_id)
+{
+	get_pending_map_t::iterator itPending = mGetPending.find(pending_material_t(region_id, material_id));
+	if (mGetPending.end() == itPending)
+	{
+		mGetPending.insert(std::pair<pending_material_t, F64>(pending_material_t(region_id, material_id), LLFrameTimer::getTotalSeconds()));
+	}
+	else
+	{
+		itPending->second = LLFrameTimer::getTotalSeconds();
+	}
+}
+
 const LLMaterialPtr LLMaterialMgr::get(const LLUUID& region_id, const LLMaterialID& material_id)
 {
 	LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL;
@@ -151,6 +166,7 @@ const LLMaterialPtr LLMaterialMgr::get(const LLUUID& region_id, const LLMaterial
 				itQueue = ret.first;
 			}
 			itQueue->second.insert(material_id);
+			markGetPending(region_id, material_id);
 		}
 		LL_DEBUGS("Materials") << " returning empty material " << LL_ENDL;
 		material = LLMaterialPtr();
@@ -179,6 +195,7 @@ boost::signals2::connection LLMaterialMgr::get(const LLUUID& region_id, const LL
 			itQueue = ret.first;
 		}
 		itQueue->second.insert(material_id);
+		markGetPending(region_id, material_id);
 	}
 
 	get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
@@ -190,7 +207,7 @@ boost::signals2::connection LLMaterialMgr::get(const LLUUID& region_id, const LL
 	return itCallback->second->connect(cb);;
 }
 
-bool LLMaterialMgr::isGetAllPending(const LLUUID& region_id)
+bool LLMaterialMgr::isGetAllPending(const LLUUID& region_id) const
 {
 	getall_pending_map_t::const_iterator itPending = mGetAllPending.find(region_id);
 	return (mGetAllPending.end() != itPending) && (LLFrameTimer::getTotalSeconds() < itPending->second + MATERIALS_GET_TIMEOUT);
@@ -456,9 +473,11 @@ void LLMaterialMgr::onIdle(void*)
 		instancep->processGetAllQueue();
 	}
 
-	if (!instancep->mPutQueue.empty())
+	static LLFrameTimer mPutTimer;
+	if ( (!instancep->mPutQueue.empty()) && (mPutTimer.hasExpired()) )
 	{
 		instancep->processPutQueue();
+		mPutTimer.resetWithExpiry(MATERIALS_PUT_THROTTLE_SECS);
 	}
 }
 
@@ -506,17 +525,16 @@ void LLMaterialMgr::processGetQueue()
 
 		material_queue_t& materials = itRegionQueue->second;
 		material_queue_t::iterator loopMaterial = materials.begin();
-		if (materials.end() == loopMaterial)
-		{
-			LL_DEBUGS("Material") << "Get queue for region empty, trying next region." << LL_ENDL;
-			continue;
-		}
 		while ( (materials.end() != loopMaterial) && (materialsData.size() <= MATERIALS_GET_MAX_ENTRIES) )
 		{
 			material_queue_t::iterator itMaterial = loopMaterial++;
 			materialsData.append((*itMaterial).asLLSD());
 			materials.erase(itMaterial);
-			mGetPending.insert(std::pair<pending_material_t, F64>(pending_material_t(region_id, *itMaterial), LLFrameTimer::getTotalSeconds()));
+			markGetPending(region_id, *itMaterial);
+		}
+		if (materials.empty())
+		{
+			mGetQueue.erase(itRegionQueue);
 		}
 		
 		std::string materialString = zip_llsd(materialsData);
@@ -580,6 +598,9 @@ void LLMaterialMgr::processGetAllQueue()
 
 void LLMaterialMgr::processPutQueue()
 {
+	typedef std::map<const LLViewerRegion*, LLSD> regionput_request_map;
+	regionput_request_map requests;
+
 	put_queue_t::iterator loopQueue = mPutQueue.begin();
 	while (mPutQueue.end() != loopQueue)
 	{
@@ -601,18 +622,11 @@ void LLMaterialMgr::processPutQueue()
 			continue;
 		}
 
-		std::string capURL = regionp->getCapability(MATERIALS_CAPABILITY_NAME);
-		if (capURL.empty())
-		{
-			LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
-				<< "' is not defined on region '" << regionp->getName() << "'" << LL_ENDL;
+		LLSD& facesData = requests[regionp];
 
-			mPutQueue.erase(itQueue);
-			continue;
-		}
-
-		LLSD facesData = LLSD::emptyArray();
-		for (facematerial_map_t::const_iterator itFace = itQueue->second.begin(); itFace != itQueue->second.end(); ++itFace)
+		facematerial_map_t& face_map = itQueue->second;
+		facematerial_map_t::iterator itFace = face_map.begin();
+		while ( (face_map.end() != itFace) && (facesData.size() < MATERIALS_GET_MAX_ENTRIES) )
 		{
 			LLSD faceData = LLSD::emptyMap();
 			faceData[MATERIALS_CAP_FACE_FIELD] = static_cast<LLSD::Integer>(itFace->first);
@@ -622,10 +636,26 @@ void LLMaterialMgr::processPutQueue()
 				faceData[MATERIALS_CAP_MATERIAL_FIELD] = itFace->second.asLLSD();
 			}
 			facesData.append(faceData);
+			face_map.erase(itFace++);
+		}
+		if (face_map.empty())
+		{
+			mPutQueue.erase(itQueue);
+		}
+	}
+
+	for (regionput_request_map::const_iterator itRequest = requests.begin(); itRequest != requests.end(); ++itRequest)
+	{
+		std::string capURL = itRequest->first->getCapability(MATERIALS_CAPABILITY_NAME);
+		if (capURL.empty())
+		{
+			LL_WARNS("Materials") << "Capability '" << MATERIALS_CAPABILITY_NAME
+				<< "' is not defined on region '" << itRequest->first->getName() << "'" << LL_ENDL;
+			continue;
 		}
 
 		LLSD materialsData = LLSD::emptyMap();
-		materialsData[MATERIALS_CAP_FULL_PER_FACE_FIELD] = facesData;
+		materialsData[MATERIALS_CAP_FULL_PER_FACE_FIELD] = itRequest->second;
 
 		std::string materialString = zip_llsd(materialsData);
 
@@ -640,7 +670,7 @@ void LLMaterialMgr::processPutQueue()
 			LLSD putData = LLSD::emptyMap();
 			putData[MATERIALS_CAP_ZIP_FIELD] = materialBinary;
 
-			LL_DEBUGS("Materials") << "put for " << facesData.size() << " faces; object " << object_id << LL_ENDL;
+			LL_DEBUGS("Materials") << "put for " << itRequest->second.size() << " faces" << LL_ENDL;
 			LLHTTPClient::ResponderPtr materialsResponder = new LLMaterialsResponder("PUT", capURL, boost::bind(&LLMaterialMgr::onPutResponse, this, _1, _2));
 			LLHTTPClient::put(capURL, putData, materialsResponder);
 		}
@@ -648,7 +678,6 @@ void LLMaterialMgr::processPutQueue()
 		{
 			LL_ERRS("debugMaterials") << "cannot zip LLSD binary content" << LL_ENDL;
 		}
-		mPutQueue.erase(itQueue);
 	}
 }
 
diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h
index 6f444309d3e3e1e900a57835deade3e12bbb0c03..39be5cab29158ba72c8ab61d77ca3551fac9b698 100644
--- a/indra/newview/llmaterialmgr.h
+++ b/indra/newview/llmaterialmgr.h
@@ -54,8 +54,9 @@ class LLMaterialMgr : public LLSingleton<LLMaterialMgr>
 
 protected:
 	void clearGetQueues(const LLUUID& region_id);
-	bool isGetPending(const LLUUID& region_id, const LLMaterialID& material_id);
-	bool isGetAllPending(const LLUUID& region_id);
+	bool isGetPending(const LLUUID& region_id, const LLMaterialID& material_id) const;
+	bool isGetAllPending(const LLUUID& region_id) const;
+	void markGetPending(const LLUUID& region_id, const LLMaterialID& material_id);
 	const LLMaterialPtr setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data);
 
 	static void onIdle(void*);
diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp
index 91e485d01b7b6e19827f8c746e3c29ddd5b5bfaf..97ca08f69497c6f9c885a047ecd2c6b36b582dda 100644
--- a/indra/newview/llviewerstatsrecorder.cpp
+++ b/indra/newview/llviewerstatsrecorder.cpp
@@ -216,7 +216,11 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )
 				<< "Texture Fetch bps\t"
 				<< "\n";
 
-			fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile );
+			size_t data_size = data_msg.str().size();
+			if ( data_size != fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ))
+			{
+				llwarns << "Unable to write complete column headings to " << STATS_FILE_NAME << llendl;
+			}
 		}
 		else
 		{
@@ -249,7 +253,12 @@ void LLViewerStatsRecorder::writeToLog( F32 interval )
 		<< "\t" << (mTextureFetchSize * 8 / delta_time)
 		<< "\n";
 
-	fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile );
+	size_t data_size = data_msg.str().size();
+	if ( data_size != fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile ))
+	{
+		llwarns << "Unable to write complete stats record to " << STATS_FILE_NAME << llendl;
+	}
+	fwrite(data_msg.str().c_str(), 1, data_size, mObjectCacheFile );
 	clearStats();
 }