diff --git a/applications/gui/src/screen.cpp b/applications/gui/src/screen.cpp
index 187ff7945d608f72ef45f4674101209bb3e2f7f7..b5b642d8925217357b15eedc0ea1adb5b60ed044 100644
--- a/applications/gui/src/screen.cpp
+++ b/applications/gui/src/screen.cpp
@@ -1,5 +1,8 @@
 #include "screen.hpp"
 
+#include <ftl/streams/netstream.hpp>
+#include <ftl/rgbd/frameset.hpp>
+
 #include <nanogui/opengl.h>
 #include <nanogui/glutil.h>
 #include <nanogui/screen.h>
@@ -10,6 +13,8 @@
 #include <nanogui/toolbutton.h>
 #include <nanogui/popupbutton.h>
 
+#include <sstream>
+
 #include <nlohmann/json.hpp>
 
 #include <loguru.hpp>
@@ -60,6 +65,14 @@ namespace {
 		})";
 }
 
+template <typename T>
+std::string to_string_with_precision(const T a_value, const int n = 6) {
+    std::ostringstream out;
+    out.precision(n);
+    out << std::fixed << a_value;
+    return out.str();
+}
+
 ftl::gui::Screen::Screen(ftl::Configurable *proot, ftl::net::Universe *pnet, ftl::ctrl::Master *controller) :
 		nanogui::Screen(Eigen::Vector2i(1024, 768), "FT-Lab Remote Presence"),
 		status_("FT-Lab Remote Presence System") {
@@ -573,6 +586,22 @@ void ftl::gui::Screen::draw(NVGcontext *ctx) {
 	}
 
 	nvgTextAlign(ctx, NVG_ALIGN_RIGHT);
+
+	if (root()->value("show_information", false)) {
+		string msg;
+
+		// FIXME: Do not do this every frame, or cache the results every N frames...
+
+		auto [fps,latency] = ftl::rgbd::Builder::getStatistics();
+		msg = string("Frame rate: ") + std::to_string((int)fps);
+		nvgText(ctx, screenSize[0]-10, 20, msg.c_str(), NULL);
+		msg = string("Latency: ") + std::to_string((int)latency) + string("ms");
+		nvgText(ctx, screenSize[0]-10, 40, msg.c_str(), NULL);	
+
+		msg = string("Bitrate: ") + to_string_with_precision(ftl::stream::Net::getRequiredBitrate(), 2) + string("Mbps");
+		nvgText(ctx, screenSize[0]-10, 60, msg.c_str(), NULL);	
+	}
+
 	nvgText(ctx, screenSize[0]-10, screenSize[1]-20, status_.c_str(), NULL);
 
 	/* Draw the user interface */
diff --git a/components/rgbd-sources/include/ftl/rgbd/frameset.hpp b/components/rgbd-sources/include/ftl/rgbd/frameset.hpp
index eb646b4b4c70d2dd4140abea9bf85c94ca8df931..2f267b55b2367a315546bea3264e43cd24757f7d 100644
--- a/components/rgbd-sources/include/ftl/rgbd/frameset.hpp
+++ b/components/rgbd-sources/include/ftl/rgbd/frameset.hpp
@@ -133,6 +133,12 @@ class Builder : public Generator {
 
 	void setBufferSize(size_t n) { bufferSize_ = n; }
 
+	/**
+	 * Retrieve an fps + latency pair, averaged since last call to this
+	 * function.
+	 */
+	static std::pair<float,float> getStatistics();
+
 	private:
 	std::list<FrameSet*> framesets_;  // Active framesets
 	std::list<FrameSet*> allocated_;  // Keep memory allocations
@@ -141,9 +147,6 @@ class Builder : public Generator {
 	ftl::rgbd::VideoCallback cb_;
 	MUTEX mutex_;
 	int mspf_;
-	float latency_;
-	float fps_;
-	int stats_count_;
 	int64_t last_ts_;
 	int64_t last_frame_;
 	int id_;
@@ -156,6 +159,11 @@ class Builder : public Generator {
 
 	std::string name_;
 
+	static MUTEX msg_mutex__;
+	static float latency__;
+	static float fps__;
+	static int stats_count__;
+
 	/* Insert a new frameset into the buffer, along with all intermediate
 	 * framesets between the last in buffer and the new one.
 	 */
diff --git a/components/rgbd-sources/src/frameset.cpp b/components/rgbd-sources/src/frameset.cpp
index 4c9fa2eada0880949decfa8dfb8a99ff9127bc20..785d991ad8eb04a3ad005ffb495d6f931bd949d3 100644
--- a/components/rgbd-sources/src/frameset.cpp
+++ b/components/rgbd-sources/src/frameset.cpp
@@ -16,6 +16,11 @@ using ftl::codecs::Channel;
 using ftl::rgbd::FrameSet;
 using ftl::codecs::Channels;
 
+float Builder::latency__ = 0.0f;
+float Builder::fps__ = 0.0f;
+int Builder::stats_count__ = 0;
+MUTEX Builder::msg_mutex__;
+
 /*void FrameSet::upload(ftl::codecs::Channels<0> c, cudaStream_t stream) {
 	for (auto &f : frames) {
 		f.upload(c, stream);
@@ -69,10 +74,6 @@ Builder::Builder() : head_(0), id_(0) {
 	mspf_ = ftl::timer::getInterval();
 	name_ = "NoName";
 
-	latency_ = 0.0f;;
-	stats_count_ = 0;
-	fps_ = 0.0f;
-
 	if (size_ > 0) states_.resize(size_);
 }
 
@@ -241,18 +242,33 @@ static void mergeFrameset(ftl::rgbd::FrameSet &f1, ftl::rgbd::FrameSet &f2) {
 }
 
 void Builder::_recordStats(float fps, float latency) {
-	latency_ += latency;
-	fps_ += fps;
-	++stats_count_;
+	UNIQUE_LOCK(msg_mutex__, lk);
+	latency__ += latency;
+	fps__ += fps;
+	++stats_count__;
 
-	if (fps_/float(stats_count_) <= float(stats_count_)) {
+	/*if (fps_/float(stats_count_) <= float(stats_count_)) {
 		fps_ /= float(stats_count_);
 		latency_ /= float(stats_count_);
 		LOG(INFO) << name_ << ": fps = " << fps_ << ", latency = " << latency_;
 		fps_ = 0.0f;
 		latency_ = 0.0f;
 		stats_count_ = 0;
-	}
+	}*/
+}
+
+std::pair<float,float> Builder::getStatistics() {
+	UNIQUE_LOCK(msg_mutex__, lk);
+	if (stats_count__ == 0.0f) return {0.0f,0.0f};
+	fps__ /= float(stats_count__);
+	latency__ /= float(stats_count__);
+	float fps = fps__;
+	float latency = latency__;
+	//LOG(INFO) << name_ << ": fps = " << fps_ << ", latency = " << latency_;
+	fps__ = 0.0f;
+	latency__ = 0.0f;
+	stats_count__ = 0;
+	return {fps,latency};
 }
 
 ftl::rgbd::FrameSet *Builder::_findFrameset(int64_t ts) {
diff --git a/components/streams/include/ftl/streams/netstream.hpp b/components/streams/include/ftl/streams/netstream.hpp
index 3c7aef3c64e917e4daac0722340414b2123dffd8..0db0013196f0fe8aa03adc74480223a004863c95 100644
--- a/components/streams/include/ftl/streams/netstream.hpp
+++ b/components/streams/include/ftl/streams/netstream.hpp
@@ -60,6 +60,12 @@ class Net : public Stream {
 
 	inline const ftl::UUID &getPeer() const { return peer_; }
 
+	/**
+	 * Return the average bitrate of all streams since the last call to this
+	 * function. Units are Mbps.
+	 */
+	static float getRequiredBitrate();
+
 	private:
 	SHARED_MUTEX mutex_;
 	bool active_;
@@ -76,10 +82,10 @@ class Net : public Stream {
 	std::array<std::atomic<int>,32> reqtally_;
 	ftl::codecs::Channels<0> last_selected_;
 
-	float req_bitrate_;
-	float sample_count_;
-	int64_t last_msg_;
-	MUTEX msg_mtx_;
+	static float req_bitrate__;
+	static float sample_count__;
+	static int64_t last_msg__;
+	static MUTEX msg_mtx__;
 
 	std::list<detail::StreamClient> clients_;
 
diff --git a/components/streams/src/netstream.cpp b/components/streams/src/netstream.cpp
index b12480d0e5126feba87e60d49458a487158d3e00..72d435fb57ebe3c26d747e2a124e4b6405fc4057 100644
--- a/components/streams/src/netstream.cpp
+++ b/components/streams/src/netstream.cpp
@@ -17,6 +17,11 @@ using std::optional;
 
 static constexpr int kTallyScale = 10;
 
+float Net::req_bitrate__ = 0.0f;
+float Net::sample_count__ = 0.0f;
+int64_t Net::last_msg__ = 0;
+MUTEX Net::msg_mtx__;
+
 Net::Net(nlohmann::json &config, ftl::net::Universe *net) : Stream(config), active_(false), net_(net), clock_adjust_(0) {
 	// TODO: Install "find_stream" binding if not installed...
 	if (!net_->isBound("find_stream")) {
@@ -40,7 +45,6 @@ Net::Net(nlohmann::json &config, ftl::net::Universe *net) : Stream(config), acti
 	}
 
 	last_frame_ = 0;
-	last_msg_ = 0;
 	time_peer_ = ftl::UUID(0);
 }
 
@@ -378,16 +382,26 @@ void Net::_checkDataRate(size_t tx_size, int64_t tx_latency, int64_t ts) {
     float min_mbps = (float(tx_size) * 8.0f * (1000.0f / float(ftl::timer::getInterval()))) / 1048576.0f;
     //if (actual_mbps > 0.0f && actual_mbps < min_mbps) LOG(WARNING) << "Bitrate = " << actual_mbps << "Mbps, min required = " << min_mbps << "Mbps";
 
-	UNIQUE_LOCK(msg_mtx_,lk);
-	req_bitrate_ += float(tx_size) * 8.0f;
-	sample_count_ += 1.0f;
+	UNIQUE_LOCK(msg_mtx__,lk);
+	req_bitrate__ += float(tx_size) * 8.0f;
+	sample_count__ += 1.0f;
 
-	if (ts - last_msg_ >= 1000) {
+	/*if (ts - last_msg_ >= 1000) {
 		DLOG(INFO) << "Required Bitrate = " << (req_bitrate_ / float(ts - last_msg_) * 1000.0f / 1048576.0f) << "Mbps";
 		last_msg_ = ts;
 		req_bitrate_ = 0.0f;
 		sample_count_ = 0.0f;
-	}
+	}*/
+}
+
+float Net::getRequiredBitrate() {
+	int64_t ts = ftl::timer::get_time();
+	UNIQUE_LOCK(msg_mtx__,lk);
+	float r = (req_bitrate__ / float(ts - last_msg__) * 1000.0f / 1048576.0f);
+	last_msg__ = ts;
+	req_bitrate__ = 0.0f;
+	sample_count__ = 0.0f;
+	return r;
 }
 
 bool Net::end() {