diff --git a/applications/reconstruct/src/main.cpp b/applications/reconstruct/src/main.cpp
index 7f34ad8b3e4896c768a006d9c537e1c911292cd5..a4010c776b962b97ea02702a6a9ee9b8594e0c76 100644
--- a/applications/reconstruct/src/main.cpp
+++ b/applications/reconstruct/src/main.cpp
@@ -161,7 +161,7 @@ static void run(ftl::Configurable *root) {
 	ftl::rgbd::Streamer *stream = ftl::create<ftl::rgbd::Streamer>(root, "stream", net);
 	ftl::rgbd::VirtualSource *virt = ftl::create<ftl::rgbd::VirtualSource>(root, "virtual");
 	ftl::render::Splatter *splat = ftl::create<ftl::render::Splatter>(root, "renderer", &scene_B);
-	ftl::rgbd::Group group;
+	ftl::rgbd::Group *group = new ftl::rgbd::Group;
 	ftl::ILW *align = ftl::create<ftl::ILW>(root, "merge");
 
 	int o = root->value("origin_pose", 0) % sources.size();
@@ -184,7 +184,7 @@ static void run(ftl::Configurable *root) {
 	for (size_t i=0; i<sources.size(); i++) {
 		Source *in = sources[i];
 		in->setChannel(Channel::Depth);
-		group.addSource(in);
+		group->addSource(in);
 	}
 
 	// ---- Recording code -----------------------------------------------------
@@ -195,7 +195,7 @@ static void run(ftl::Configurable *root) {
 		ftl::codecs::StreamPacket s = spkt;
 
 		// Patch stream ID to match order in group
-		s.streamID = group.streamID(src);
+		s.streamID = group->streamID(src);
 		writer.write(s, pkt);
 	};
 
@@ -212,14 +212,14 @@ static void run(ftl::Configurable *root) {
 			writer.begin();
 
 			// TODO: Write pose+calibration+config packets
-			auto sources = group.sources();
+			auto sources = group->sources();
 			for (int i=0; i<sources.size(); ++i) {
 				writeSourceProperties(writer, i, sources[i]);
 			}
 
-			group.addRawCallback(std::function(recorder));
+			group->addRawCallback(std::function(recorder));
 		} else {
-			group.removeRawCallback(recorder);
+			group->removeRawCallback(recorder);
 			writer.end();
 			fileout.close();
 		}
@@ -228,14 +228,14 @@ static void run(ftl::Configurable *root) {
 	// -------------------------------------------------------------------------
 
 	stream->setLatency(5);  // FIXME: This depends on source!?
-	stream->add(&group);
+	stream->add(group);
 	stream->run();
 
 	bool busy = false;
 
-	group.setLatency(5);
-	group.setName("ReconGroup");
-	group.sync([splat,virt,&busy,&slave,&scene_A,&scene_B,&align](ftl::rgbd::FrameSet &fs) -> bool {
+	group->setLatency(5);
+	group->setName("ReconGroup");
+	group->sync([splat,virt,&busy,&slave,&scene_A,&scene_B,&align](ftl::rgbd::FrameSet &fs) -> bool {
 		//cudaSetDevice(scene->getCUDADevice());
 
 		if (slave.isPaused()) return true;
@@ -284,6 +284,9 @@ static void run(ftl::Configurable *root) {
 	delete stream;
 	delete virt;
 	delete net;
+	delete group;
+
+	ftl::config::cleanup();  // Remove any last configurable objects.
 	LOG(INFO) << "Done.";
 }
 
diff --git a/components/common/cpp/include/ftl/configurable.hpp b/components/common/cpp/include/ftl/configurable.hpp
index 94a080eaed480fa2e57b113e9c8c3d7bc04388bd..6593119c794205e0bf901814437f79974bb81e00 100644
--- a/components/common/cpp/include/ftl/configurable.hpp
+++ b/components/common/cpp/include/ftl/configurable.hpp
@@ -39,7 +39,7 @@ class Configurable {
 	public:
 	Configurable();
 	explicit Configurable(nlohmann::json &config);
-	virtual ~Configurable() {}
+	virtual ~Configurable();
 
 	/**
 	 * Force the JSON object to have specific properties with a specific type.
diff --git a/components/common/cpp/include/ftl/configuration.hpp b/components/common/cpp/include/ftl/configuration.hpp
index c060b70382d0174d351d836d5476fa5a1f29db61..94fcc7dfa6b57e9bfd59fbcf36c5be80e0b82638 100644
--- a/components/common/cpp/include/ftl/configuration.hpp
+++ b/components/common/cpp/include/ftl/configuration.hpp
@@ -37,6 +37,10 @@ Configurable *configure(int argc, char **argv, const std::string &root);
 
 Configurable *configure(json_t &);
 
+void cleanup();
+
+void removeConfigurable(Configurable *cfg);
+
 /**
  * Change a configuration value based upon a URI. Return true if changed,
  * false if it was not able to change.
diff --git a/components/common/cpp/src/configurable.cpp b/components/common/cpp/src/configurable.cpp
index 7cea5adeb61162f83a62c5724e99b41186b6e8ff..f47e12195e00d6db0bce1ee65ec70339e062448f 100644
--- a/components/common/cpp/src/configurable.cpp
+++ b/components/common/cpp/src/configurable.cpp
@@ -21,6 +21,10 @@ Configurable::Configurable(nlohmann::json &config) : config_(&config) {
 	ftl::config::registerConfigurable(this);
 }
 
+Configurable::~Configurable() {
+	ftl::config::removeConfigurable(this);
+}
+
 void Configurable::required(const char *f, const std::vector<std::tuple<std::string, std::string, std::string>> &r) {
 	bool diderror = false;
 	for (auto i : r) {
diff --git a/components/common/cpp/src/configuration.cpp b/components/common/cpp/src/configuration.cpp
index 8a3849e8ee8799119f3d15700dc277e1dece7654..6881c181ded6db678bd450d19002f1a6ee8cfc26 100644
--- a/components/common/cpp/src/configuration.cpp
+++ b/components/common/cpp/src/configuration.cpp
@@ -470,6 +470,24 @@ Configurable *ftl::config::configure(ftl::config::json_t &cfg) {
 	return rootcfg;
 }
 
+static bool doing_cleanup = false;
+void ftl::config::cleanup() {
+	doing_cleanup = true;
+	for (auto f : config_instance) {
+		delete f.second;
+	}
+	config_instance.clear();
+}
+
+void ftl::config::removeConfigurable(Configurable *cfg) {
+	if (doing_cleanup) return;
+
+	auto i = config_instance.find(cfg->getID());
+	if (i != config_instance.end()) {
+		config_instance.erase(i);
+	}
+}
+
 
 Configurable *ftl::config::configure(int argc, char **argv, const std::string &root) {
 	loguru::g_preamble_date = false;
diff --git a/components/rgbd-sources/include/ftl/rgbd/frame.hpp b/components/rgbd-sources/include/ftl/rgbd/frame.hpp
index 45bf3f4a9b8f862e3d70c22abfcddb096855d7c2..3bf2b87ce29fb53a1ef44de80556518c2667c410 100644
--- a/components/rgbd-sources/include/ftl/rgbd/frame.hpp
+++ b/components/rgbd-sources/include/ftl/rgbd/frame.hpp
@@ -151,9 +151,9 @@ public:
 
 private:
 	struct ChannelData {
+		ftl::cuda::TextureObjectBase tex;
 		cv::Mat host;
 		cv::cuda::GpuMat gpu;
-		ftl::cuda::TextureObjectBase tex;
 	};
 
 	std::array<ChannelData, Channels::kMax> data_;
diff --git a/components/rgbd-sources/src/source.cpp b/components/rgbd-sources/src/source.cpp
index 32cff11c40de330caf788c2a0a7b54817a141995..5539ac612da8bcab109d18dd2a8fcf7afc9c35e9 100644
--- a/components/rgbd-sources/src/source.cpp
+++ b/components/rgbd-sources/src/source.cpp
@@ -59,7 +59,7 @@ Source::Source(ftl::config::json_t &cfg, ftl::net::Universe *net) : Configurable
 }
 
 Source::~Source() {
-
+	if (impl_) delete impl_;
 }
 
 cv::Mat Source::cameraMatrix() const {
@@ -338,6 +338,7 @@ void Source::setCallback(std::function<void(int64_t, cv::Mat &, cv::Mat &)> cb)
 
 void Source::addRawCallback(const std::function<void(ftl::rgbd::Source*, const ftl::codecs::StreamPacket &spkt, const ftl::codecs::Packet &pkt)> &f) {
 	UNIQUE_LOCK(mutex_,lk);
+	LOG(INFO) << "ADD RAW";
 	rawcallbacks_.push_back(f);
 }