diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index 9ebcbdd8cea3a31b4c1df95cd45f16f7d0dfd938..6cf6f4f84f73c1e1310e3027d6f2ddcaf19859ac 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -297,63 +297,80 @@ namespace LLTrace
 		}
 
 		template <typename T>
-		typename T::value_t getPeriodMin(const TraceType<T>& stat) const
+		typename T::value_t getPeriodMin(const TraceType<T>& stat, U32 num_periods = S32_MAX) const
 		{
+			size_t total_periods = mRecordingPeriods.size();
+			num_periods = llmin(num_periods, total_periods);
+
 			typename T::value_t min_val = (std::numeric_limits<typename T::value_t>::max)();
-			U32 num_periods = mRecordingPeriods.size();
-			for (S32 i = 0; i < num_periods; i++)
+			for (S32 i = 1; i <= num_periods; i++)
 			{
-				min_val = llmin(min_val, mRecordingPeriods[(mCurPeriod + i) % num_periods].getSum(stat));
+				S32 index = (mCurPeriod + total_periods - i) % total_periods;
+				min_val = llmin(min_val, mRecordingPeriods[index].getSum(stat));
 			}
 			return min_val;
 		}
 
 		template <typename T>
-		F64 getPeriodMinPerSec(const TraceType<T>& stat) const
+		F64 getPeriodMinPerSec(const TraceType<T>& stat, U32 num_periods = S32_MAX) const
 		{
+			size_t total_periods = mRecordingPeriods.size();
+			num_periods = llmin(num_periods, total_periods);
+
 			F64 min_val = (std::numeric_limits<F64>::max)();
-			U32 num_periods = mRecordingPeriods.size();
-			for (S32 i = 0; i < num_periods; i++)
+			for (S32 i = 1; i <= num_periods; i++)
 			{
-				min_val = llmin(min_val, mRecordingPeriods[(mCurPeriod + i) % num_periods].getPerSec(stat));
+				S32 index = (mCurPeriod + total_periods - i) % total_periods;
+				min_val = llmin(min_val, mRecordingPeriods[index].getPerSec(stat));
 			}
 			return min_val;
 		}
 
 		template <typename T>
-		typename T::value_t getPeriodMax(const TraceType<T>& stat) const
+		typename T::value_t getPeriodMax(const TraceType<T>& stat, U32 num_periods = S32_MAX) const
 		{
+			size_t total_periods = mRecordingPeriods.size();
+			num_periods = llmin(num_periods, total_periods);
+
 			typename T::value_t max_val = (std::numeric_limits<typename T::value_t>::min)();
-			U32 num_periods = mRecordingPeriods.size();
-			for (S32 i = 0; i < num_periods; i++)
+			for (S32 i = 1; i <= num_periods; i++)
 			{
-				max_val = llmax(max_val, mRecordingPeriods[(mCurPeriod + i) % num_periods].getSum(stat));
+				S32 index = (mCurPeriod + total_periods - i) % total_periods;
+				max_val = llmax(max_val, mRecordingPeriods[index].getSum(stat));
 			}
 			return max_val;
 		}
 
 		template <typename T>
-		F64 getPeriodMaxPerSec(const TraceType<T>& stat) const
+		F64 getPeriodMaxPerSec(const TraceType<T>& stat, U32 num_periods = S32_MAX) const
 		{
+			size_t total_periods = mRecordingPeriods.size();
+			num_periods = llmin(num_periods, total_periods);
+
 			F64 max_val = (std::numeric_limits<F64>::min)();
-			U32 num_periods = mRecordingPeriods.size();
-			for (S32 i = 1; i < num_periods; i++)
+			for (S32 i = 1; i <= num_periods; i++)
 			{
-				max_val = llmax(max_val, mRecordingPeriods[(mCurPeriod + i) % num_periods].getPerSec(stat));
+				S32 index = (mCurPeriod + total_periods - i) % total_periods;
+				max_val = llmax(max_val, mRecordingPeriods[index].getPerSec(stat));
 			}
 			return max_val;
 		}
 
 		template <typename T>
-		typename T::value_t getPeriodMean(const TraceType<T>& stat) const
+		typename T::value_t getPeriodMean(const TraceType<T>& stat, U32 num_periods = S32_MAX) const
 		{
+			size_t total_periods = mRecordingPeriods.size();
+			num_periods = llmin(num_periods, total_periods);
+
 			typename T::value_t mean = 0.0;
-			U32 num_periods = mRecordingPeriods.size();
-			for (S32 i = 0; i < num_periods; i++)
+			if (num_periods <= 0) { return mean; }
+
+			for (S32 i = 1; i <= num_periods; i++)
 			{
-				if (mRecordingPeriods[(mCurPeriod + i) % num_periods].getDuration() > 0.f)
+				S32 index = (mCurPeriod + total_periods - i) % total_periods;
+				if (mRecordingPeriods[index].getDuration() > 0.f)
 				{
-					mean += mRecordingPeriods[(mCurPeriod + i) % num_periods].getSum(stat);
+					mean += mRecordingPeriods[index].getSum(stat);
 				}
 			}
 			mean /= num_periods;
@@ -361,15 +378,20 @@ namespace LLTrace
 		}
 
 		template <typename T>
-		typename T::value_t getPeriodMeanPerSec(const TraceType<T>& stat) const
+		typename T::value_t getPeriodMeanPerSec(const TraceType<T>& stat, U32 num_periods = S32_MAX) const
 		{
+			size_t total_periods = mRecordingPeriods.size();
+			num_periods = llmin(num_periods, total_periods);
+
 			typename T::value_t mean = 0.0;
-			U32 num_periods = mRecordingPeriods.size();
-			for (S32 i = 0; i < num_periods; i++)
+			if (num_periods <= 0) { return mean; }
+
+			for (S32 i = 1; i <= num_periods; i++)
 			{
-				if (mRecordingPeriods[i].getDuration() > 0.f)
+				S32 index = (mCurPeriod + total_periods - i) % total_periods;
+				if (mRecordingPeriods[index].getDuration() > 0.f)
 				{
-					mean += mRecordingPeriods[(mCurPeriod + i) % num_periods].getPerSec(stat);
+					mean += mRecordingPeriods[index].getPerSec(stat);
 				}
 			}
 			mean /= num_periods;
diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp
index 46eea368e51ad367e9bb38578e28dcb059b037ba..70ba59b13027fad2e8ec818ba1134bd59ec0782f 100644
--- a/indra/llui/llstatbar.cpp
+++ b/indra/llui/llstatbar.cpp
@@ -112,16 +112,16 @@ void LLStatBar::draw()
 		if (mPerSec)
 		{
 			current = last_frame_recording.getPerSec(*mCountFloatp);
-			min = frame_recording.getPeriodMinPerSec(*mCountFloatp);
-			max = frame_recording.getPeriodMaxPerSec(*mCountFloatp);
-			mean = frame_recording.getPeriodMeanPerSec(*mCountFloatp);
+			min = frame_recording.getPeriodMinPerSec(*mCountFloatp, mNumFrames);
+			max = frame_recording.getPeriodMaxPerSec(*mCountFloatp, mNumFrames);
+			mean = frame_recording.getPeriodMeanPerSec(*mCountFloatp, mNumFrames);
 		}
 		else
 		{
 			current = last_frame_recording.getSum(*mCountFloatp);
-			min = frame_recording.getPeriodMin(*mCountFloatp);
-			max = frame_recording.getPeriodMax(*mCountFloatp);
-			mean = frame_recording.getPeriodMean(*mCountFloatp);
+			min = frame_recording.getPeriodMin(*mCountFloatp, mNumFrames);
+			max = frame_recording.getPeriodMax(*mCountFloatp, mNumFrames);
+			mean = frame_recording.getPeriodMean(*mCountFloatp, mNumFrames);
 		}
 	}
 	else if (mCountIntp)
@@ -131,16 +131,16 @@ void LLStatBar::draw()
 		if (mPerSec)
 		{
 			current = last_frame_recording.getPerSec(*mCountIntp);
-			min = frame_recording.getPeriodMinPerSec(*mCountIntp);
-			max = frame_recording.getPeriodMaxPerSec(*mCountIntp);
-			mean = frame_recording.getPeriodMeanPerSec(*mCountIntp);
+			min = frame_recording.getPeriodMinPerSec(*mCountIntp, mNumFrames);
+			max = frame_recording.getPeriodMaxPerSec(*mCountIntp, mNumFrames);
+			mean = frame_recording.getPeriodMeanPerSec(*mCountIntp, mNumFrames);
 		}
 		else
 		{
 			current = last_frame_recording.getSum(*mCountIntp);
-			min = frame_recording.getPeriodMin(*mCountIntp);
-			max = frame_recording.getPeriodMax(*mCountIntp);
-			mean = frame_recording.getPeriodMean(*mCountIntp);
+			min = frame_recording.getPeriodMin(*mCountIntp, mNumFrames);
+			max = frame_recording.getPeriodMax(*mCountIntp, mNumFrames);
+			mean = frame_recording.getPeriodMean(*mCountIntp, mNumFrames);
 		}
 	}
 	else if (mMeasurementFloatp)
@@ -148,18 +148,18 @@ void LLStatBar::draw()
 		LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); 
 
 		current = last_frame_recording.getLastValue(*mMeasurementFloatp);
-		min = frame_recording.getPeriodMin(*mMeasurementFloatp);
-		max = frame_recording.getPeriodMax(*mMeasurementFloatp);
-		mean = frame_recording.getPeriodMean(*mMeasurementFloatp);
+		min = frame_recording.getPeriodMin(*mMeasurementFloatp, mNumFrames);
+		max = frame_recording.getPeriodMax(*mMeasurementFloatp, mNumFrames);
+		mean = frame_recording.getPeriodMean(*mMeasurementFloatp, mNumFrames);
 	}
 	else if (mMeasurementIntp)
 	{
 		LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); 
 
 		current = last_frame_recording.getLastValue(*mMeasurementIntp);
-		min = frame_recording.getPeriodMin(*mMeasurementIntp);
-		max = frame_recording.getPeriodMax(*mMeasurementIntp);
-		mean = frame_recording.getPeriodMean(*mMeasurementIntp);
+		min = frame_recording.getPeriodMin(*mMeasurementIntp, mNumFrames);
+		max = frame_recording.getPeriodMax(*mMeasurementIntp, mNumFrames);
+		mean = frame_recording.getPeriodMean(*mMeasurementIntp, mNumFrames);
 	}
 
 	current *= mUnitScale;
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index 9ca5f07f35b8fb5fa5f83ac09f85009142eb9179..1f5bdc85892f3d019bde2e012c5ba51e07b73a65 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -170,7 +170,7 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 &center,
 	add(sVelocityStat, dpos);
 	add(sAngularVelocityStat, drot);
 	
-	mAverageSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sVelocityStat);
+	mAverageSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sVelocityStat, 50);
 	mAverageAngularSpeed = LLTrace::get_frame_recording().getPeriodMeanPerSec(sAngularVelocityStat);
 	mCosHalfCameraFOV = cosf(0.5f * getView() * llmax(1.0f, getAspect()));