diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index c58540914e1a4aad0f32a302cec8acc50c92b2b4..1fc70cd6d6438888396b837192ee2ffc961d9e16 100644
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -39,6 +39,11 @@
 // Globals
 LLLandmarkList gLandmarkList;
 
+// number is mostly arbitrary, but it should be below DEFAULT_QUEUE_SIZE pool size,
+// which is 4096, to not overfill the pool if user has more than 4K of landmarks,
+// and low number helps with not flooding server with requests
+const S32 MAX_SIMULTANEOUS_REQUESTS = 512;
+
 
 ////////////////////////////////////////////////////////////////////////////
 // LLLandmarkList
@@ -69,6 +74,11 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
 		{
 			return NULL;
 		}
+	    if ( mWaitList.find(asset_uuid) != mWaitList.end() )
+		{
+            // Landmark is sheduled for download, but not requested yet
+			return NULL;
+		}
 		
 		landmark_requested_list_t::iterator iter = mRequestedList.find(asset_uuid);
 		if (iter != mRequestedList.end())
@@ -86,6 +96,13 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
 			mLoadedCallbackMap.insert(vt);
 		}
 
+        if (mRequestedList.size() > MAX_SIMULTANEOUS_REQUESTS)
+        {
+            // Postpone download till queu is emptier
+            mWaitList.insert(asset_uuid);
+            return NULL;
+        }
+
 		gAssetStorage->getAssetData(asset_uuid,
 									LLAssetType::AT_LANDMARK,
 									LLLandmarkList::processGetAssetReply,
@@ -155,8 +172,22 @@ void LLLandmarkList::processGetAssetReply(
 		}
 
 		gLandmarkList.mBadList.insert(uuid);
+        gLandmarkList.mRequestedList.erase(uuid); //mBadList effectively blocks any load, so no point keeping id in requests
+        // todo: this should clean mLoadedCallbackMap!
 	}
 
+    if (!gLandmarkList.mWaitList.empty())
+    {
+        // start new download from wait list
+        landmark_uuid_list_t::iterator iter = gLandmarkList.mWaitList.begin();
+        LLUUID asset_uuid = *iter;
+        gLandmarkList.mWaitList.erase(iter);
+        gAssetStorage->getAssetData(asset_uuid,
+            LLAssetType::AT_LANDMARK,
+            LLLandmarkList::processGetAssetReply,
+            NULL);
+        gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds;
+    }
 }
 
 BOOL LLLandmarkList::isAssetInLoadedCallbackMap(const LLUUID& asset_uuid)
diff --git a/indra/newview/lllandmarklist.h b/indra/newview/lllandmarklist.h
index 3356f866ce453aa83c8ebaef1e783e84fd7a8d0a..2e7bd2561013d67165f4a783c5322bd09a81db61 100644
--- a/indra/newview/lllandmarklist.h
+++ b/indra/newview/lllandmarklist.h
@@ -70,9 +70,10 @@ class LLLandmarkList
 	typedef std::map<LLUUID, LLLandmark*> landmark_list_t;
 	landmark_list_t mList;
 
-	typedef std::set<LLUUID> landmark_bad_list_t;
-	landmark_bad_list_t mBadList;
-	
+	typedef std::set<LLUUID> landmark_uuid_list_t;
+	landmark_uuid_list_t mBadList;
+	landmark_uuid_list_t mWaitList;
+
 	typedef std::map<LLUUID,F32> landmark_requested_list_t;
 	landmark_requested_list_t mRequestedList;