diff --git a/include/ircd/m/dbs/dbs.h b/include/ircd/m/dbs/dbs.h
index ba1087cda..8af363d8c 100644
--- a/include/ircd/m/dbs/dbs.h
+++ b/include/ircd/m/dbs/dbs.h
@@ -28,7 +28,7 @@ namespace ircd::m::dbs
 	extern std::shared_ptr<db::database> events;
 
 	// [SET (txn)] Basic write suite
-	string_view write(db::txn &, const event &, const write_opts &);
+	void write(db::txn &, const event &, const write_opts &);
 }
 
 /// Database description
@@ -51,7 +51,7 @@ namespace ircd::m::dbs::appendix
 #include "event_type.h"             // type | event_idx
 #include "event_sender.h"           // hostpart | localpart, event_idx
 #include "room_head.h"              // room_id | event_id => event_idx
-#include "room_events.h"            // room_id | depth, event_idx => node_id
+#include "room_events.h"            // room_id | depth, event_idx
 #include "room_joined.h"            // room_id | origin, member => event_idx
 #include "room_state.h"             // room_id | type, state_key => event_idx
 #include "room_state_space.h"       // room_id | type, state_key, depth, event_idx
@@ -72,13 +72,6 @@ struct ircd::m::dbs::write_opts
 	/// be zero for blacklisting, but the blacklist option must be set.
 	uint64_t event_idx {0};
 
-	/// The state btree root to perform the update on.
-	string_view root_in;
-
-	/// After the update is performed, the new state btree root is returned
-	/// into this buffer.
-	mutable_buffer root_out;
-
 	/// Fuse panel to toggle transaction elements.
 	std::bitset<64> appendix {appendix_all};
 
@@ -92,14 +85,6 @@ struct ircd::m::dbs::write_opts
 	/// event_horizon for this event.
 	std::bitset<256> horizon_resolve {event_refs_all};
 
-	/// Whether the present state table `room_state` should be updated by
-	/// this operation if appropriate.
-	bool present {true};
-
-	/// Whether the history state btree `state_node` + `room_events` value
-	/// should be updated by this operation if appropriate.
-	bool history {false};
-
 	/// Whether the event.source can be used directly for event_json. Defaults
 	/// to false unless the caller wants to avoid a redundant re-stringify.
 	bool json_source {false};
@@ -136,9 +121,6 @@ struct ircd::m::dbs::write_opts
 enum ircd::m::dbs::appendix::index
 :std::underlying_type<ircd::m::dbs::appendix::index>::type
 {
-	/// This bit offers coarse control over all the EVENT_ appendices.
-	EVENT,
-
 	/// Involves the event_idx column; translates an event_id to our internal
 	/// index number. This bit can be dark during re-indexing operations.
 	EVENT_ID,
@@ -174,20 +156,8 @@ enum ircd::m::dbs::appendix::index
 	/// Involves the event_type column (reverse index on the event type).
 	EVENT_TYPE,
 
-	/// Take branch to handle events with a room_id
-	ROOM,
-
-	/// Take branch to handle room state events.
-	STATE,
-
-	/// Perform state btree manip for room history.
-	HISTORY,
-
-	/// Take branch to handle room redaction events.
-	REDACT,
-
-	/// Take branch to handle other types of events.
-	OTHER,
+	/// Involves room_events table.
+	ROOM_EVENTS,
 
 	/// Whether the event should be added to the room_head, indicating that
 	/// it has not yet been referenced at the time of this write. Defaults
@@ -198,17 +168,17 @@ enum ircd::m::dbs::appendix::index
 	/// room_head. This defaults to true and should almost always be true.
 	ROOM_HEAD_RESOLVE,
 
-	/// Involves room_events table.
-	ROOM_EVENTS,
-
-	/// Involves room_joined table.
-	ROOM_JOINED,
-
 	/// Involves room_state (present state) table.
 	ROOM_STATE,
 
 	/// Involves room_space (all states) table.
 	ROOM_STATE_SPACE,
+
+	/// Involves room_joined table.
+	ROOM_JOINED,
+
+	/// Take branch to handle room redaction events.
+	ROOM_REDACT,
 };
 
 struct ircd::m::dbs::init
@@ -220,16 +190,14 @@ struct ircd::m::dbs::init
 // Internal interface; not for public. (TODO: renamespace)
 namespace ircd::m::dbs
 {
-	void _index__room_state_space(db::txn &,  const event &, const write_opts &);
-	void _index__room_state(db::txn &,  const event &, const write_opts &);
-	void _index__room_events(db::txn &,  const event &, const write_opts &, const string_view &);
-	void _index__room_joined(db::txn &, const event &, const write_opts &);
-	void _index__room_head_resolve(db::txn &, const event &, const write_opts &);
-	void _index__room_head(db::txn &, const event &, const write_opts &);
-	string_view _index_state(db::txn &, const event &, const write_opts &);
-	string_view _index_redact(db::txn &, const event &, const write_opts &);
-	string_view _index_other(db::txn &, const event &, const write_opts &);
-	string_view _index_room(db::txn &, const event &, const write_opts &);
+	void _index_room_joined(db::txn &, const event &, const write_opts &);
+	void _index_room_redact(db::txn &, const event &, const write_opts &);
+	void _index_room_state_space(db::txn &,  const event &, const write_opts &);
+	void _index_room_state(db::txn &, const event &, const write_opts &);
+	void _index_room_head_resolve(db::txn &, const event &, const write_opts &);
+	void _index_room_head(db::txn &, const event &, const write_opts &);
+	void _index_room_events(db::txn &,  const event &, const write_opts &);
+	void _index_room(db::txn &, const event &, const write_opts &);
 	void _index_event_type(db::txn &, const event &, const write_opts &);
 	void _index_event_sender(db::txn &, const event &, const write_opts &);
 	void _index_event_horizon_resolve(db::txn &, const event &, const write_opts &);
diff --git a/ircd/m_dbs.cc b/ircd/m_dbs.cc
index 584b78d15..cc9581e91 100644
--- a/ircd/m_dbs.cc
+++ b/ircd/m_dbs.cc
@@ -215,16 +215,13 @@ namespace ircd::m::dbs
 	static void blacklist(db::txn &txn, const event::id &, const write_opts &);
 }
 
-ircd::string_view
+void
 ircd::m::dbs::write(db::txn &txn,
                     const event &event,
                     const write_opts &opts)
 {
 	if(opts.event_idx == 0 && opts.blacklist)
-	{
-		blacklist(txn, at<"event_id"_>(event), opts);
-		return {};
-	}
+		return blacklist(txn, at<"event_id"_>(event), opts);
 
 	if(unlikely(opts.event_idx == 0))
 		throw panic
@@ -232,14 +229,9 @@ ircd::m::dbs::write(db::txn &txn,
 			"Cannot write to database: no index specified for event."
 		};
 
-	if(opts.appendix.test(appendix::EVENT))
-		_index_event(txn, event, opts);
-
-	if(opts.appendix.test(appendix::ROOM))
-		if(json::get<"room_id"_>(event))
-			return _index_room(txn, event, opts);
-
-	return {};
+	_index_event(txn, event, opts);
+	if(json::get<"room_id"_>(event))
+		_index_room(txn, event, opts);
 }
 
 void
@@ -492,7 +484,7 @@ ircd::m::dbs::_index_event_refs_prev(db::txn &txn,
 		{
 			txn, dbs::event_refs,
 			{
-				opts.op, key, string_view{}
+				opts.op, key
 			}
 		};
 	}
@@ -548,7 +540,7 @@ ircd::m::dbs::_index_event_refs_auth(db::txn &txn,
 		{
 			txn, dbs::event_refs,
 			{
-				opts.op, key, string_view{}
+				opts.op, key
 			}
 		};
 	}
@@ -563,9 +555,6 @@ ircd::m::dbs::_index_event_refs_state(db::txn &txn,
 	assert(opts.event_refs.test(uint(ref::NEXT_STATE)) ||
 	       opts.event_refs.test(uint(ref::PREV_STATE)));
 
-	if(!opts.present)
-		return;
-
 	if(!json::get<"room_id"_>(event))
 		return;
 
@@ -614,7 +603,7 @@ ircd::m::dbs::_index_event_refs_state(db::txn &txn,
 		{
 			txn, dbs::event_refs,
 			{
-				opts.op, key, string_view{}
+				opts.op, key
 			}
 		};
 	}
@@ -630,7 +619,7 @@ ircd::m::dbs::_index_event_refs_state(db::txn &txn,
 		{
 			txn, dbs::event_refs,
 			{
-				opts.op, key, string_view{}
+				opts.op, key
 			}
 		};
 	}
@@ -691,7 +680,7 @@ ircd::m::dbs::_index_event_refs_m_receipt_m_read(db::txn &txn,
 	{
 		txn, dbs::event_refs,
 		{
-			opts.op, key, string_view{}
+			opts.op, key
 		}
 	};
 }
@@ -788,7 +777,7 @@ ircd::m::dbs::_index_event_refs_m_relates_m_reply(db::txn &txn,
 	{
 		txn, dbs::event_refs,
 		{
-			opts.op, key, string_view{}
+			opts.op, key
 		}
 	};
 }
@@ -846,7 +835,7 @@ ircd::m::dbs::_index_event_refs_m_room_redaction(db::txn &txn,
 	{
 		txn, dbs::event_refs,
 		{
-			opts.op, key, string_view{}
+			opts.op, key
 		}
 	};
 }
@@ -869,7 +858,7 @@ ircd::m::dbs::_index_event_horizon(db::txn &txn,
 	{
 		txn, dbs::event_horizon,
 		{
-			opts.op, key, string_view{}
+			opts.op, key
 		}
 	};
 }
@@ -918,7 +907,6 @@ ircd::m::dbs::_index_event_horizon_resolve(db::txn &txn,
 		_opts.op = opts.op;
 		_opts.event_idx = event_idx;
 		_opts.appendix.reset();
-		_opts.appendix.set(appendix::EVENT);
 		_opts.appendix.set(appendix::EVENT_REFS);
 		_opts.event_refs = opts.horizon_resolve;
 		_opts.interpose = &txn;
@@ -963,7 +951,7 @@ ircd::m::dbs::_index_event_sender(db::txn &txn,
 	{
 		txn, dbs::event_sender,
 		{
-			opts.op, key, string_view{}
+			opts.op, key
 		}
 	};
 }
@@ -987,169 +975,72 @@ ircd::m::dbs::_index_event_type(db::txn &txn,
 	{
 		txn, dbs::event_type,
 		{
-			opts.op, key, string_view{}
+			opts.op, key
 		}
 	};
 }
 
-ircd::string_view
+void
 ircd::m::dbs::_index_room(db::txn &txn,
                           const event &event,
                           const write_opts &opts)
 {
-	assert(opts.appendix.test(appendix::ROOM));
+	assert(!empty(json::get<"room_id"_>(event)));
+
+	if(opts.appendix.test(appendix::ROOM_EVENTS))
+		_index_room_events(txn, event, opts);
 
 	if(opts.appendix.test(appendix::ROOM_HEAD))
-		_index__room_head(txn, event, opts);
+		_index_room_head(txn, event, opts);
 
 	if(opts.appendix.test(appendix::ROOM_HEAD_RESOLVE))
-		_index__room_head_resolve(txn, event, opts);
+		_index_room_head_resolve(txn, event, opts);
 
-	if(opts.appendix.test(appendix::STATE) && defined(json::get<"state_key"_>(event)))
-		return _index_state(txn, event, opts);
+	if(defined(json::get<"state_key"_>(event)))
+	{
+		if(opts.appendix.test(appendix::ROOM_STATE))
+			_index_room_state(txn, event, opts);
 
-	if(opts.appendix.test(appendix::REDACT) && json::get<"type"_>(event) == "m.room.redaction")
-		return _index_redact(txn, event, opts);
+		if(opts.appendix.test(appendix::ROOM_STATE_SPACE))
+			_index_room_state_space(txn, event, opts);
 
-	if(opts.appendix.test(appendix::OTHER))
-		return _index_other(txn, event, opts);
+		if(opts.appendix.test(appendix::ROOM_JOINED) && at<"type"_>(event) == "m.room.member")
+			_index_room_joined(txn, event, opts);
+	}
 
-	return {};
+	if(opts.appendix.test(appendix::ROOM_REDACT) && json::get<"type"_>(event) == "m.room.redaction")
+		_index_room_redact(txn, event, opts);
 }
 
-ircd::string_view
-ircd::m::dbs::_index_state(db::txn &txn,
-                           const event &event,
-                           const write_opts &opts)
-try
+/// Adds the entry for the room_events column into the txn.
+void
+ircd::m::dbs::_index_room_events(db::txn &txn,
+                                 const event &event,
+                                 const write_opts &opts)
 {
-	assert(opts.appendix.test(appendix::STATE));
+	assert(opts.appendix.test(appendix::ROOM_EVENTS));
 
-	const auto &type
+	thread_local char buf[ROOM_EVENTS_KEY_MAX_SIZE];
+	const ctx::critical_assertion ca;
+	const string_view &key
 	{
-		at<"type"_>(event)
+		room_events_key(buf, at<"room_id"_>(event), at<"depth"_>(event), opts.event_idx)
 	};
 
-	const auto &room_id
+	db::txn::append
 	{
-		at<"room_id"_>(event)
-	};
-
-	const string_view &new_root
-	{
-		opts.op == db::op::SET &&
-		opts.appendix.test(appendix::HISTORY) &&
-		opts.history?
-			state::insert(txn, opts.root_out, opts.root_in, event):
-			strlcpy(opts.root_out, opts.root_in)
-	};
-
-	if(opts.appendix.test(appendix::ROOM_EVENTS))
-		_index__room_events(txn, event, opts, new_root);
-
-	if(opts.appendix.test(appendix::ROOM_JOINED))
-		_index__room_joined(txn, event, opts);
-
-	if(opts.appendix.test(appendix::ROOM_STATE))
-		_index__room_state(txn, event, opts);
-
-	if(opts.appendix.test(appendix::ROOM_STATE_SPACE))
-		_index__room_state_space(txn, event, opts);
-
-	return new_root;
-}
-catch(const std::exception &e)
-{
-	log::error
-	{
-		"Failed to update state: %s", e.what()
-	};
-
-	throw;
-}
-
-ircd::string_view
-ircd::m::dbs::_index_redact(db::txn &txn,
-                            const event &event,
-                            const write_opts &opts)
-try
-{
-	assert(opts.appendix.test(appendix::REDACT));
-
-	const auto &target_id
-	{
-		at<"redacts"_>(event)
-	};
-
-	const m::event::idx target_idx
-	{
-		find_event_idx(target_id, opts)
-	};
-
-	if(unlikely(!target_idx))
-		log::error
+		txn, room_events,
 		{
-			"Redaction from '%s' missing redaction target '%s'",
-			at<"event_id"_>(event),
-			target_id
-		};
-
-	const m::event::fetch target
-	{
-		target_idx, std::nothrow
-	};
-
-	const string_view new_root
-	{
-		target.valid &&
-		defined(json::get<"state_key"_>(target)) &&
-		opts.appendix.test(appendix::HISTORY) &&
-		opts.history?
-			//state::remove(txn, state_root_out, state_root_in, target):
-			strlcpy(opts.root_out, opts.root_in):
-			strlcpy(opts.root_out, opts.root_in)
-	};
-
-	if(opts.appendix.test(appendix::ROOM_EVENTS))
-		_index__room_events(txn, event, opts, opts.root_in);
-
-	if(opts.appendix.test(appendix::ROOM_STATE))
-		if(target.valid && defined(json::get<"state_key"_>(target)))
-		{
-			auto _opts(opts);
-			_opts.op = db::op::DELETE;
-			_index__room_state(txn, target, _opts);
+			opts.op,        // db::op
+			key,            // key,
 		}
-
-	return new_root;
-}
-catch(const std::exception &e)
-{
-	log::error
-	{
-		"Failed to update state from redaction: %s", e.what()
 	};
-
-	throw;
-}
-
-ircd::string_view
-ircd::m::dbs::_index_other(db::txn &txn,
-                           const event &event,
-                           const write_opts &opts)
-{
-	assert(opts.appendix.test(appendix::OTHER));
-
-	if(opts.appendix.test(appendix::ROOM_EVENTS))
-		_index__room_events(txn, event, opts, opts.root_in);
-
-	return strlcpy(opts.root_out, opts.root_in);
 }
 
 void
-ircd::m::dbs::_index__room_head(db::txn &txn,
-                                const event &event,
-                                const write_opts &opts)
+ircd::m::dbs::_index_room_head(db::txn &txn,
+                               const event &event,
+                               const write_opts &opts)
 {
 	const ctx::critical_assertion ca;
 	thread_local char buf[ROOM_HEAD_KEY_MAX_SIZE];
@@ -1173,9 +1064,9 @@ ircd::m::dbs::_index__room_head(db::txn &txn,
 }
 
 void
-ircd::m::dbs::_index__room_head_resolve(db::txn &txn,
-                                        const event &event,
-                                        const write_opts &opts)
+ircd::m::dbs::_index_room_head_resolve(db::txn &txn,
+                                       const event &event,
+                                       const write_opts &opts)
 {
 	assert(opts.appendix.test(appendix::ROOM_HEAD_RESOLVE));
 
@@ -1212,47 +1103,128 @@ ircd::m::dbs::_index__room_head_resolve(db::txn &txn,
 	}
 }
 
-/// Adds the entry for the room_events column into the txn.
-/// You need find/create the right state_root before this.
 void
-ircd::m::dbs::_index__room_events(db::txn &txn,
-                                  const event &event,
-                                  const write_opts &opts,
-                                  const string_view &new_root)
+ircd::m::dbs::_index_room_state(db::txn &txn,
+                                const event &event,
+                                const write_opts &opts)
 {
-	assert(opts.appendix.test(appendix::ROOM_EVENTS));
+	assert(opts.appendix.test(appendix::ROOM_STATE));
 
-	thread_local char buf[ROOM_EVENTS_KEY_MAX_SIZE];
 	const ctx::critical_assertion ca;
+	thread_local char buf[ROOM_STATE_KEY_MAX_SIZE];
 	const string_view &key
 	{
-		room_events_key(buf, at<"room_id"_>(event), at<"depth"_>(event), opts.event_idx)
+		room_state_key(buf, at<"room_id"_>(event), at<"type"_>(event), at<"state_key"_>(event))
+	};
+
+	const string_view val
+	{
+		byte_view<string_view>(opts.event_idx)
 	};
 
 	db::txn::append
 	{
-		txn, room_events,
+		txn, room_state,
 		{
-			opts.op,   // db::op
-			key,       // key
-			new_root   // val
+			opts.op,
+			key,
+			value_required(opts.op)? val : string_view{},
+		}
+	};
+}
+
+void
+ircd::m::dbs::_index_room_state_space(db::txn &txn,
+                                      const event &event,
+                                      const write_opts &opts)
+{
+	assert(opts.appendix.test(appendix::ROOM_STATE_SPACE));
+
+	const ctx::critical_assertion ca;
+	thread_local char buf[ROOM_STATE_SPACE_KEY_MAX_SIZE];
+	const string_view &key
+	{
+		room_state_space_key(buf, at<"room_id"_>(event), at<"type"_>(event), at<"state_key"_>(event), at<"depth"_>(event), opts.event_idx)
+	};
+
+	db::txn::append
+	{
+		txn, room_state_space,
+		{
+			opts.op,
+			key,
+		}
+	};
+}
+
+
+void
+ircd::m::dbs::_index_room_redact(db::txn &txn,
+                                 const event &event,
+                                 const write_opts &opts)
+{
+	assert(opts.appendix.test(appendix::ROOM_REDACT));
+	assert(json::get<"type"_>(event) == "m.room.redaction");
+
+	const auto &target_id
+	{
+		at<"redacts"_>(event)
+	};
+
+	const m::event::idx target_idx
+	{
+		find_event_idx(target_id, opts)
+	};
+
+	if(unlikely(!target_idx))
+		log::error
+		{
+			"Redaction from '%s' missing redaction target '%s'",
+			at<"event_id"_>(event),
+			target_id
+		};
+
+	char state_key_buf[event::STATE_KEY_MAX_SIZE];
+	const string_view &state_key
+	{
+		m::get(std::nothrow, target_idx, "state_key", state_key_buf)
+	};
+
+	if(!state_key)
+		return;
+
+	char type_buf[event::TYPE_MAX_SIZE];
+	const string_view &type
+	{
+		m::get(std::nothrow, target_idx, "type", type_buf)
+	};
+
+	assert(!empty(type));
+	const ctx::critical_assertion ca;
+	thread_local char buf[ROOM_STATE_SPACE_KEY_MAX_SIZE];
+	const string_view &key
+	{
+		room_state_key(buf, at<"room_id"_>(event), type, state_key)
+	};
+
+	db::txn::append
+	{
+		txn, room_state,
+		{
+			db::op::DELETE,
+			key,
 		}
 	};
 }
 
 /// Adds the entry for the room_joined column into the txn.
 void
-ircd::m::dbs::_index__room_joined(db::txn &txn,
-                                   const event &event,
-                                   const write_opts &opts)
+ircd::m::dbs::_index_room_joined(db::txn &txn,
+                                  const event &event,
+                                  const write_opts &opts)
 {
 	assert(opts.appendix.test(appendix::ROOM_JOINED));
-
-	if(!opts.present)
-		return;
-
-	if(at<"type"_>(event) != "m.room.member")
-		return;
+	assert(at<"type"_>(event) == "m.room.member");
 
 	thread_local char buf[ROOM_JOINED_KEY_MAX_SIZE];
 	const ctx::critical_assertion ca;
@@ -1298,62 +1270,6 @@ ircd::m::dbs::_index__room_joined(db::txn &txn,
 	};
 }
 
-void
-ircd::m::dbs::_index__room_state(db::txn &txn,
-                                 const event &event,
-                                 const write_opts &opts)
-{
-	assert(opts.appendix.test(appendix::ROOM_STATE));
-
-	if(!opts.present)
-		return;
-
-	const ctx::critical_assertion ca;
-	thread_local char buf[ROOM_STATE_KEY_MAX_SIZE];
-	const string_view &key
-	{
-		room_state_key(buf, at<"room_id"_>(event), at<"type"_>(event), at<"state_key"_>(event))
-	};
-
-	const string_view val
-	{
-		byte_view<string_view>(opts.event_idx)
-	};
-
-	db::txn::append
-	{
-		txn, room_state,
-		{
-			opts.op,
-			key,
-			value_required(opts.op)? val : string_view{},
-		}
-	};
-}
-
-void
-ircd::m::dbs::_index__room_state_space(db::txn &txn,
-                                       const event &event,
-                                       const write_opts &opts)
-{
-	assert(opts.appendix.test(appendix::ROOM_STATE_SPACE));
-
-	const ctx::critical_assertion ca;
-	thread_local char buf[ROOM_STATE_SPACE_KEY_MAX_SIZE];
-	const string_view &key
-	{
-		room_state_space_key(buf, at<"room_id"_>(event), at<"type"_>(event), at<"state_key"_>(event), at<"depth"_>(event), opts.event_idx)
-	};
-
-	db::txn::append
-	{
-		txn, room_state_space,
-		{
-			opts.op, key, string_view{}
-		}
-	};
-}
-
 ircd::m::event::idx
 ircd::m::dbs::find_event_idx(const event::id &event_id,
                              const write_opts &wopts)
diff --git a/ircd/m_room.cc b/ircd/m_room.cc
index 1242841a8..87e8af561 100644
--- a/ircd/m_room.cc
+++ b/ircd/m_room.cc
@@ -117,15 +117,12 @@ ircd::m::room::state::force_present(const m::event &event)
 			json::get<"event_id"_>(event)
 		};
 
-	m::dbs::write_opts opts;
+	dbs::write_opts opts;
 	opts.event_idx = m::index(event);
-	opts.present = true;
-	opts.history = false;
-	opts.appendix.reset(dbs::appendix::ROOM_HEAD);
-	opts.appendix.reset(dbs::appendix::ROOM_HEAD_RESOLVE);
-
-	m::dbs::_index__room_state(txn, event, opts);
-	m::dbs::_index__room_joined(txn, event, opts);
+	opts.appendix.reset();
+	opts.appendix.set(dbs::appendix::ROOM_STATE);
+	opts.appendix.reset(dbs::appendix::ROOM_JOINED);
+	dbs::write(txn, event, opts);
 
 	txn();
 	return true;
@@ -157,13 +154,10 @@ ircd::m::room::state::rebuild_present(const state &state)
 		const m::event &event{*it};
 		m::dbs::write_opts opts;
 		opts.event_idx = event_idx;
-		opts.present = true;
-		opts.history = false;
-		opts.appendix.reset(dbs::appendix::ROOM_HEAD);
-		opts.appendix.reset(dbs::appendix::ROOM_HEAD_RESOLVE);
-
-		m::dbs::_index__room_state(txn, event, opts);
-		m::dbs::_index__room_joined(txn, event, opts);
+		opts.appendix.reset();
+		opts.appendix.set(dbs::appendix::ROOM_STATE);
+		opts.appendix.set(dbs::appendix::ROOM_JOINED);
+		dbs::write(txn, event, opts);
 		++ret;
 	}
 
@@ -174,132 +168,13 @@ ircd::m::room::state::rebuild_present(const state &state)
 size_t
 ircd::m::room::state::rebuild_history(const state &state)
 {
-	size_t ret{0};
-	const auto create_idx
-	{
-		state.get("m.room.create")
-	};
-
-	static const m::event::fetch::opts fopts
-	{
-		{ db::get::NO_CACHE }
-	};
-
-	const m::room room
-	{
-		state.room_id, nullptr, state.fopts
-	};
-
-	m::room::messages it
-	{
-		room, create_idx, &fopts
-	};
-
-	if(!it)
-		return ret;
-
-	db::txn txn
-	{
-		*m::dbs::events
-	};
-
-	uint r(0);
-	char root[2][64] {0};
-	m::dbs::write_opts opts;
-	opts.root_in = root[++r % 2];
-	opts.root_out = root[++r % 2];
-	opts.present = false;
-	opts.history = true;
-	opts.appendix.reset(dbs::appendix::ROOM_HEAD);
-	opts.appendix.reset(dbs::appendix::ROOM_HEAD_RESOLVE);
-
-	int64_t depth{0};
-	for(; it; ++it)
-	{
-		const m::event &event{*it};
-		opts.event_idx = it.event_idx();
-		if(at<"depth"_>(event) == depth + 1)
-			++depth;
-
-		if(at<"depth"_>(event) != depth)
-			throw ircd::error
-			{
-				"Incomplete room history: gap between %ld and %ld [%s]",
-				depth,
-				at<"depth"_>(event),
-				string_view{at<"event_id"_>(event)}
-			};
-
-		if(at<"type"_>(event) == "m.room.redaction")
-		{
-			opts.root_in = m::dbs::_index_redact(txn, event, opts);
-			opts.root_out = root[++r % 2];
-			txn();
-			txn.clear();
-		}
-		else if(defined(json::get<"state_key"_>(event)))
-		{
-			opts.root_in = m::dbs::_index_state(txn, event, opts);
-			opts.root_out = root[++r % 2];
-			txn();
-			txn.clear();
-		}
-		else m::dbs::_index_other(txn, event, opts);
-
-		++ret;
-	}
-
-	txn();
-	return ret;
+	return 0;
 }
 
-//TODO: state btree.
 size_t
 ircd::m::room::state::clear_history(const state &state)
 {
-	static const db::gopts gopts
-	{
-		db::get::NO_CACHE
-	};
-
-	db::txn txn
-	{
-		*m::dbs::events
-	};
-
-	auto it
-	{
-		m::dbs::room_events.begin(state.room_id, gopts)
-	};
-
-	size_t ret{0};
-	for(; it; ++it, ret++)
-	{
-		const auto pair
-		{
-			m::dbs::room_events_key(it->first)
-		};
-
-		const auto &depth{std::get<0>(pair)};
-		const auto &event_idx{std::get<1>(pair)};
-		thread_local char buf[m::dbs::ROOM_EVENTS_KEY_MAX_SIZE];
-		const string_view key
-		{
-			m::dbs::room_events_key(buf, state.room_id, depth, event_idx)
-		};
-
-		db::txn::append
-		{
-			txn, m::dbs::room_events,
-			{
-				db::op::SET,
-				key
-			}
-		};
-	}
-
-	txn();
-	return ret;
+	return 0;
 }
 
 namespace ircd::m
@@ -2997,8 +2872,6 @@ ircd::m::room::state::space::rebuild::rebuild()
 
 	dbs::write_opts wopts;
 	wopts.appendix.reset();
-	wopts.appendix.set(dbs::appendix::ROOM);
-	wopts.appendix.set(dbs::appendix::STATE);
 	wopts.appendix.set(dbs::appendix::ROOM_STATE_SPACE);
 
 	event::fetch event;
@@ -3604,7 +3477,7 @@ ircd::m::room::head::rebuild(const head &head)
 	{
 		const m::event &event{*it};
 		opts.event_idx = it.event_idx();
-		m::dbs::_index__room_head(txn, event, opts);
+		m::dbs::_index_room_head(txn, event, opts);
 		++ret;
 	}
 
@@ -3657,14 +3530,14 @@ ircd::m::room::head::reset(const head &head)
 		}
 
 		opts.event_idx = event_idx;
-		m::dbs::_index__room_head(txn, event, opts);
+		m::dbs::_index_room_head(txn, event, opts);
 		++ret;
 	});
 
 	// Finally add the replacement to the txn
 	opts.op = db::op::SET;
 	opts.event_idx = it.event_idx();
-	m::dbs::_index__room_head(txn, replacement, opts);
+	m::dbs::_index_room_head(txn, replacement, opts);
 
 	// Commit txn
 	txn();
@@ -3690,7 +3563,7 @@ ircd::m::room::head::modify(const m::event::id &event_id,
 	m::dbs::write_opts opts;
 	opts.op = op;
 	opts.event_idx = event.event_idx;
-	m::dbs::_index__room_head(txn, event, opts);
+	m::dbs::_index_room_head(txn, event, opts);
 
 	// Commit txn
 	txn();
diff --git a/modules/vm.cc b/modules/vm.cc
index 08cbf41d9..7c07623fc 100644
--- a/modules/vm.cc
+++ b/modules/vm.cc
@@ -840,51 +840,13 @@ ircd::m::vm::write_append(eval &eval,
 
 	// Preliminary write_opts
 	m::dbs::write_opts wopts(opts.wopts);
-	m::state::id_buffer new_root_buf;
-	wopts.root_out = new_root_buf;
-	wopts.present = opts.present;
-	wopts.history = opts.history;
+	wopts.appendix.set(dbs::appendix::ROOM_STATE, opts.present);
+	wopts.appendix.set(dbs::appendix::ROOM_JOINED, opts.present);
+	wopts.appendix.set(dbs::appendix::ROOM_STATE_SPACE, opts.history);
 	wopts.appendix.set(dbs::appendix::ROOM_HEAD, opts.room_head);
 	wopts.appendix.set(dbs::appendix::ROOM_HEAD_RESOLVE, opts.room_head_resolve);
 	wopts.json_source = opts.json_source;
 	wopts.event_idx = eval.sequence;
-
-	if(at<"type"_>(event) == "m.room.create")
-	{
-		dbs::write(*eval.txn, event, wopts);
-		return;
-	}
-
-	const bool require_head
-	{
-		opts.fetch_state_check || opts.history
-	};
-
-	const id::event::buf head
-	{
-		require_head?
-			m::head(std::nothrow, at<"room_id"_>(event)):
-			id::event::buf{}
-	};
-
-	if(unlikely(require_head && !head))
-		throw error
-		{
-			fault::STATE, "Required head for room %s not found.",
-			string_view{at<"room_id"_>(event)}
-		};
-
-	const m::room room
-	{
-		at<"room_id"_>(event), head
-	};
-
-	const m::room::state state
-	{
-		room
-	};
-
-	wopts.root_in = state.root_id;
 	dbs::write(*eval.txn, event, wopts);
 }