diff --git a/components/streams/include/ftl/streams/builder.hpp b/components/streams/include/ftl/streams/builder.hpp
index 844e7123bd21e092aeb6a6219a5633f69d34601a..c13e979014b57d48a288077cf27af658afe00840 100644
--- a/components/streams/include/ftl/streams/builder.hpp
+++ b/components/streams/include/ftl/streams/builder.hpp
@@ -119,8 +119,12 @@ class ManualSourceBuilder : public LocalBuilder {
 
 	void tick();
 
+	inline void setFrameRate(int fps) { mspf_ = 1000/fps; };
+
 	private:
 	ftl::data::DiscreteSource *src_;
+	int mspf_ = 30;
+	int64_t last_timestamp_=0;
 };
 
 class ForeignBuilder : public BaseBuilder {
diff --git a/components/streams/src/builder.cpp b/components/streams/src/builder.cpp
index ab0991a5367973c33cf0bcf9a491a5b6ccb25297..7dc8400c239c672c2eb287c090026a9887aa6aee 100644
--- a/components/streams/src/builder.cpp
+++ b/components/streams/src/builder.cpp
@@ -171,6 +171,9 @@ void ManualSourceBuilder::tick() {
 	if (!src_) return;
 
 	int64_t ts = ftl::timer::get_time();
+	if (ts < last_timestamp_ + mspf_) return;
+	last_timestamp_ = ts;
+
 	src_->capture(ts);
 
 	auto fs = getNextFrameSet(ts);
diff --git a/components/streams/src/feed.cpp b/components/streams/src/feed.cpp
index 1a61885e0d2b7c4b529a8cd0a57a413fbf65283f..cd168145965193a63abda763ef2a4ae7b917b492 100644
--- a/components/streams/src/feed.cpp
+++ b/components/streams/src/feed.cpp
@@ -643,6 +643,9 @@ uint32_t Feed::add(const std::string &path) {
 
 			// Create local builder instance
 			auto *creator = new ftl::streams::ManualSourceBuilder(pool_.get(), fsid, source);
+			if (uri.getBaseURI() == "device::openvr") creator->setFrameRate(1000);
+			else creator->setFrameRate(30);
+			
 			std::shared_ptr<ftl::streams::BaseBuilder> creatorptr(creator);
 			lk.lock();
 			receiver_->registerBuilder(creatorptr);