diff --git a/Cargo.lock b/Cargo.lock
index 0e5da6f6..62b13d00 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -157,7 +157,7 @@ dependencies = [
  "addr2line",
  "cfg-if",
  "libc",
- "miniz_oxide 0.4.0",
+ "miniz_oxide 0.4.1",
  "object",
  "rustc-demangle",
 ]
@@ -168,12 +168,6 @@ version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1b20b618342cf9891c292c4f5ac2cde7287cc5c87e87e9c769d617793607dec1"
 
-[[package]]
-name = "base64"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
-
 [[package]]
 name = "base64"
 version = "0.12.3"
@@ -265,7 +259,7 @@ checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b"
 dependencies = [
  "num-integer",
  "num-traits",
- "time 0.1.43",
+ "time 0.1.44",
 ]
 
 [[package]]
@@ -287,7 +281,7 @@ checksum = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
 name = "conduit"
 version = "0.1.0"
 dependencies = [
- "base64 0.12.3",
+ "base64",
  "directories",
  "http",
  "image",
@@ -298,7 +292,7 @@ dependencies = [
  "ring",
  "rocket",
  "ruma",
- "rust-argon2 0.8.2",
+ "rust-argon2",
  "serde",
  "serde_json",
  "sled",
@@ -320,7 +314,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1373a16a4937bc34efec7b391f9c1500c30b8478a701a4f44c9165cc0475a6e0"
 dependencies = [
  "aes-gcm",
- "base64 0.12.3",
+ "base64",
  "hkdf",
  "percent-encoding",
  "rand",
@@ -486,9 +480,9 @@ checksum = "cd56b59865bce947ac5958779cfa508f6c3b9497cc762b7e24a12d11ccde2c4f"
 
 [[package]]
 name = "encoding_rs"
-version = "0.8.23"
+version = "0.8.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8ac63f94732332f44fe654443c46f6375d1939684c17b0afb6cb56b0456e171"
+checksum = "a51b8cf747471cb9499b6d59e59b0444f4c90eba8968c4e44874e92b5b64ace2"
 dependencies = [
  "cfg-if",
 ]
@@ -672,7 +666,7 @@ checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
 dependencies = [
  "cfg-if",
  "libc",
- "wasi",
+ "wasi 0.9.0+wasi-snapshot-preview1",
 ]
 
 [[package]]
@@ -816,7 +810,7 @@ dependencies = [
  "itoa",
  "pin-project",
  "socket2",
- "time 0.1.43",
+ "time 0.1.44",
  "tokio",
  "tower-service",
  "tracing",
@@ -1057,9 +1051,9 @@ dependencies = [
 
 [[package]]
 name = "miniz_oxide"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f"
+checksum = "4d7559a8a40d0f97e1edea3220f698f78b1c5ab67532e49f68fde3910323b722"
 dependencies = [
  "adler",
 ]
@@ -1462,13 +1456,13 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
 
 [[package]]
 name = "redox_users"
-version = "0.3.4"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09b23093265f8d200fa7b4c2c76297f47e681c655f6f1285a8780d6a022f7431"
+checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
 dependencies = [
  "getrandom",
  "redox_syscall",
- "rust-argon2 0.7.0",
+ "rust-argon2",
 ]
 
 [[package]]
@@ -1527,11 +1521,11 @@ dependencies = [
 
 [[package]]
 name = "reqwest"
-version = "0.10.7"
+version = "0.10.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12427a5577082c24419c9c417db35cfeb65962efc7675bb6b0d5f1f9d315bfe6"
+checksum = "e9eaa17ac5d7b838b7503d118fa16ad88f440498bf9ffe5424e621f93190d61e"
 dependencies = [
- "base64 0.12.3",
+ "base64",
  "bytes",
  "encoding_rs",
  "futures-core",
@@ -1813,31 +1807,19 @@ name = "ruma-signatures"
 version = "0.6.0-dev.1"
 source = "git+https://github.com/ruma/ruma?rev=aff914050eb297bd82b8aafb12158c88a9e480e1#aff914050eb297bd82b8aafb12158c88a9e480e1"
 dependencies = [
- "base64 0.12.3",
+ "base64",
  "ring",
  "serde_json",
  "untrusted",
 ]
 
-[[package]]
-name = "rust-argon2"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bc8af4bda8e1ff4932523b94d3dd20ee30a87232323eda55903ffd71d2fb017"
-dependencies = [
- "base64 0.11.0",
- "blake2b_simd",
- "constant_time_eq",
- "crossbeam-utils",
-]
-
 [[package]]
 name = "rust-argon2"
 version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19"
 dependencies = [
- "base64 0.12.3",
+ "base64",
  "blake2b_simd",
  "constant_time_eq",
  "crossbeam-utils",
@@ -1864,7 +1846,7 @@ version = "0.18.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81"
 dependencies = [
- "base64 0.12.3",
+ "base64",
  "log",
  "ring",
  "sct",
@@ -2072,9 +2054,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
 
 [[package]]
 name = "standback"
-version = "0.2.9"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0437cfb83762844799a60e1e3b489d5ceb6a650fbacb86437badc1b6d87b246"
+checksum = "33a71ea1ea5f8747d1af1979bfb7e65c3a025a70609f04ceb78425bc5adad8e6"
 dependencies = [
  "version_check",
 ]
@@ -2088,7 +2070,7 @@ checksum = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028"
 [[package]]
 name = "state-res"
 version = "0.1.0"
-source = "git+https://github.com/ruma/state-res#d93a965ad17781fa9554bb3cea71673c054b9f3f"
+source = "git+https://github.com/ruma/state-res?branch=spec-comp#17958665f6592af3ef478024fd1d75c384a30e7f"
 dependencies = [
  "itertools",
  "js_int",
@@ -2233,11 +2215,12 @@ dependencies = [
 
 [[package]]
 name = "time"
-version = "0.1.43"
+version = "0.1.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
+checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
 dependencies = [
  "libc",
+ "wasi 0.10.0+wasi-snapshot-preview1",
  "winapi 0.3.9",
 ]
 
@@ -2395,9 +2378,9 @@ dependencies = [
 
 [[package]]
 name = "tracing-core"
-version = "0.1.14"
+version = "0.1.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db63662723c316b43ca36d833707cc93dff82a02ba3d7e354f342682cc8b3545"
+checksum = "4f0e00789804e99b20f12bc7003ca416309d28a6f495d6af58d1e2c2842461b5"
 dependencies = [
  "lazy_static",
 ]
@@ -2550,6 +2533,12 @@ version = "0.9.0+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
 
+[[package]]
+name = "wasi"
+version = "0.10.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
+
 [[package]]
 name = "wasm-bindgen"
 version = "0.2.67"
diff --git a/Cargo.toml b/Cargo.toml
index 78d8f760..15cee725 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -32,7 +32,7 @@ thiserror = "1.0.19" # Used for conduit::Error type
 image = { version = "0.23.4", default-features = false, features = ["jpeg", "png", "gif"] } # Used to generate thumbnails for images
 base64 = "0.12.3" # Used to encode server public key
 # state-res = { path = "../../state-res" }
-state-res = { git = "https://github.com/ruma/state-res", version = "0.1.0" }
+state-res = { git = "https://github.com/ruma/state-res", version = "0.1.0", branch = "spec-comp" }
 ring = "0.16.15"
 
 [features]
diff --git a/src/client_server/directory.rs b/src/client_server/directory.rs
index 5e03274b..3b106866 100644
--- a/src/client_server/directory.rs
+++ b/src/client_server/directory.rs
@@ -63,26 +63,11 @@ pub async fn get_public_rooms_route(
     db: State<'_, Database>,
     body: Ruma<get_public_rooms::IncomingRequest>,
 ) -> ConduitResult<get_public_rooms::Response> {
-    let Ruma {
-        body:
-            get_public_rooms::IncomingRequest {
-                limit,
-                server,
-                since,
-            },
-        ..
-    } = body;
-
-    let get_public_rooms_filtered::Response {
-        chunk,
-        prev_batch,
-        next_batch,
-        total_room_count_estimate,
-    } = get_public_rooms_filtered_helper(
+    let response = get_public_rooms_filtered_helper(
         &db,
-        server.as_deref(),
-        limit,
-        since.as_deref(),
+        body.body.server.as_deref(),
+        body.body.limit,
+        body.body.since.as_deref(),
         None, // This is not used
         None, // This is not used
     )
@@ -90,10 +75,10 @@ pub async fn get_public_rooms_route(
     .0;
 
     Ok(get_public_rooms::Response {
-        chunk,
-        prev_batch,
-        next_batch,
-        total_room_count_estimate,
+        chunk: response.chunk,
+        prev_batch: response.prev_batch,
+        next_batch: response.next_batch,
+        total_room_count_estimate: response.total_room_count_estimate,
     }
     .into())
 }
diff --git a/src/client_server/membership.rs b/src/client_server/membership.rs
index 3fa3b6ae..90683e61 100644
--- a/src/client_server/membership.rs
+++ b/src/client_server/membership.rs
@@ -483,12 +483,12 @@ async fn join_room_by_id_helper(
         .await?;
 
         dbg!(&send_join_response);
-        // todo!("Take send_join_response and 'create' the room using that data");
 
         let mut event_map = send_join_response
             .room_state
             .state
             .iter()
+            .chain(send_join_response.room_state.auth_chain.iter())
             .map(|pdu| {
                 pdu.deserialize()
                     .map(StateEvent::Full)
@@ -497,14 +497,6 @@ async fn join_room_by_id_helper(
             .collect::<Result<BTreeMap<EventId, StateEvent>, _>>()
             .map_err(|_| Error::bad_database("Invalid PDU found in db."))?;
 
-        let auth_chain = send_join_response
-            .room_state
-            .auth_chain
-            .iter()
-            .flat_map(|pdu| pdu.deserialize().ok())
-            .map(StateEvent::Full)
-            .collect::<Vec<_>>();
-
         let power_events = event_map
             .values()
             .filter(|pdu| pdu.is_power_event())
@@ -518,9 +510,11 @@ async fn join_room_by_id_helper(
             &power_events,
             &mut event_map,
             &db.rooms,
-            &auth_chain // if we only use it here just build this list in the first place
+            &send_join_response
+                .room_state
+                .auth_chain
                 .iter()
-                .map(|pdu| pdu.event_id())
+                .filter_map(|pdu| Some(StateEvent::Full(pdu.deserialize().ok()?).event_id()))
                 .collect::<Vec<_>>(),
         );
 
diff --git a/src/client_server/room.rs b/src/client_server/room.rs
index 7f4a15fa..3ee21b6d 100644
--- a/src/client_server/room.rs
+++ b/src/client_server/room.rs
@@ -195,7 +195,6 @@ pub fn create_room_route(
             content: match preset {
                 create_room::RoomPreset::PublicChat => {
                     serde_json::to_value(guest_access::GuestAccessEventContent::new(
-                        // In a public room, joining is the only way to access
                         guest_access::GuestAccess::Forbidden,
                     ))
                     .expect("event is valid, we just created it")
diff --git a/src/client_server/state.rs b/src/client_server/state.rs
index 12c5cacb..e7d2bcf3 100644
--- a/src/client_server/state.rs
+++ b/src/client_server/state.rs
@@ -1,5 +1,5 @@
 use super::State;
-use crate::{pdu::PduBuilder, ConduitResult, Database, Error, Ruma};
+use crate::{pdu::PduBuilder, ConduitResult, Database, Error, Result, Ruma};
 use ruma::{
     api::client::{
         error::ErrorKind,
@@ -9,7 +9,7 @@ use ruma::{
         },
     },
     events::{AnyStateEventContent, EventContent},
-    RoomId, UserId,
+    EventId, RoomId, UserId,
 };
 
 #[cfg(feature = "conduit_bin")]
@@ -33,13 +33,16 @@ pub fn send_state_event_for_key_route(
     )
     .map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?;
 
-    send_state_event_for_key_helper(
-        &db,
-        sender_id,
-        &body.content,
-        content,
-        &body.room_id,
-        Some(body.state_key.clone()),
+    Ok(
+        send_state_event_for_key::Response::new(send_state_event_for_key_helper(
+            &db,
+            sender_id,
+            &body.content,
+            content,
+            &body.room_id,
+            Some(body.state_key.clone()),
+        )?)
+        .into(),
     )
 }
 
@@ -67,8 +70,8 @@ pub fn send_state_event_for_empty_key_route(
     )
     .map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid JSON body."))?;
 
-    Ok(send_state_event_for_empty_key::Response::new(
-        send_state_event_for_key_helper(
+    Ok(
+        send_state_event_for_empty_key::Response::new(send_state_event_for_key_helper(
             &db,
             sender_id
                 .as_ref()
@@ -77,11 +80,9 @@ pub fn send_state_event_for_empty_key_route(
             json,
             &body.room_id,
             Some("".into()),
-        )?
-        .0
-        .event_id,
+        )?)
+        .into(),
     )
-    .into())
 }
 
 #[cfg_attr(
@@ -183,7 +184,7 @@ pub fn send_state_event_for_key_helper(
     json: serde_json::Value,
     room_id: &RoomId,
     state_key: Option<String>,
-) -> ConduitResult<send_state_event_for_key::Response> {
+) -> Result<EventId> {
     let sender_id = sender;
 
     if let AnyStateEventContent::RoomCanonicalAlias(canonical_alias) = content {
@@ -224,5 +225,5 @@ pub fn send_state_event_for_key_helper(
         &db.account_data,
     )?;
 
-    Ok(send_state_event_for_key::Response::new(event_id).into())
+    Ok(event_id)
 }
diff --git a/src/client_server/sync.rs b/src/client_server/sync.rs
index ccb25d19..74329605 100644
--- a/src/client_server/sync.rs
+++ b/src/client_server/sync.rs
@@ -475,7 +475,7 @@ pub async fn sync_events_route(
     }
 
     for user_id in left_encrypted_users {
-        let user_target_encrypted = db
+        let still_share_encrypted_room = db
             .rooms
             .get_shared_rooms(vec![sender_id.clone(), user_id.clone()])
             .filter_map(|r| r.ok())
@@ -490,7 +490,7 @@ pub async fn sync_events_route(
             .all(|encrypted| !encrypted);
         // If the user doesn't share an encrypted room with the target anymore, we need to tell
         // them
-        if user_target_encrypted {
+        if still_share_encrypted_room {
             device_list_left.insert(user_id);
         }
     }
diff --git a/src/database/rooms.rs b/src/database/rooms.rs
index 575a2bf0..66af7363 100644
--- a/src/database/rooms.rs
+++ b/src/database/rooms.rs
@@ -4,7 +4,6 @@ pub use edus::RoomEdus;
 
 use crate::{pdu::PduBuilder, utils, Error, PduEvent, Result};
 use log::error;
-// TODO if ruma-signatures re-exports `use ruma::signatures::digest;`
 use ring::digest;
 use ruma::{
     api::client::error::ErrorKind,
@@ -96,9 +95,9 @@ impl StateStore for Rooms {
 }
 
 impl Rooms {
-    /// Builds a `StateMap` by iterating over all keys that start
-    /// with `state_hash`, this gives the full state at event "x".
-    pub fn get_statemap_by_hash(&self, state_hash: StateHashId) -> Result<StateMap<EventId>> {
+    /// Builds a StateMap by iterating over all keys that start
+    /// with state_hash, this gives the full state for the given state_hash.
+    pub fn state_full(&self, state_hash: StateHashId) -> Result<StateMap<EventId>> {
         self.stateid_pduid
             .scan_prefix(&state_hash)
             .values()
@@ -242,8 +241,6 @@ impl Rooms {
     /// Generate a new StateHash.
     ///
     /// A unique hash made from hashing the current states pduid's.
-    /// Because `append_state_pdu` handles the empty state db case it does not
-    /// have to be here.
     fn new_state_hash_id(&self, room_id: &RoomId) -> Result<StateHashId> {
         // Use hashed roomId as the first StateHash key for first state event in room
         if self
@@ -281,7 +278,7 @@ impl Rooms {
 
     /// Checks if a room exists.
     pub fn exists(&self, room_id: &RoomId) -> Result<bool> {
-        let mut prefix = room_id.to_string().as_bytes().to_vec();
+        let mut prefix = room_id.as_bytes().to_vec();
         prefix.push(0xff);
 
         // Look for PDUs in that room.
@@ -300,7 +297,7 @@ impl Rooms {
         let mut hashmap = HashMap::new();
         for pdu in
             self.roomstateid_pduid
-                .scan_prefix(&room_id.to_string().as_bytes())
+                .scan_prefix(&room_id.as_bytes())
                 .values()
                 .map(|value| {
                     Ok::<_, Error>(
@@ -322,13 +319,13 @@ impl Rooms {
         Ok(hashmap)
     }
 
-    /// Returns the all state entries for this type.
+    /// Returns all state entries for this type.
     pub fn room_state_type(
         &self,
         room_id: &RoomId,
         event_type: &EventType,
     ) -> Result<HashMap<String, PduEvent>> {
-        let mut prefix = room_id.to_string().as_bytes().to_vec();
+        let mut prefix = room_id.as_bytes().to_vec();
         prefix.push(0xff);
         prefix.extend_from_slice(&event_type.to_string().as_bytes());
 
@@ -357,7 +354,7 @@ impl Rooms {
         Ok(hashmap)
     }
 
-    /// Returns a single PDU in `room_id` with key (`event_type`, `state_key`).
+    /// Returns a single PDU from `room_id` with key (`event_type`, `state_key`).
     pub fn room_state_get(
         &self,
         room_id: &RoomId,
@@ -459,7 +456,7 @@ impl Rooms {
 
     /// Returns the leaf pdus of a room.
     pub fn get_pdu_leaves(&self, room_id: &RoomId) -> Result<Vec<EventId>> {
-        let mut prefix = room_id.to_string().as_bytes().to_vec();
+        let mut prefix = room_id.as_bytes().to_vec();
         prefix.push(0xff);
 
         let mut events = Vec::new();
@@ -582,7 +579,7 @@ impl Rooms {
                         .split_terminator(|c: char| !c.is_alphanumeric())
                         .map(str::to_lowercase)
                     {
-                        let mut key = pdu.room_id.to_string().as_bytes().to_vec();
+                        let mut key = pdu.room_id.as_bytes().to_vec();
                         key.push(0xff);
                         key.extend_from_slice(word.as_bytes());
                         key.push(0xff);
@@ -752,7 +749,10 @@ impl Rooms {
                         })
                         .collect::<Result<StateMap<_>>>()?,
                 )
-                .ok_or(Error::Conflict("Found incoming PDU with invalid data."))?,
+                .map_err(|e| {
+                    log::error!("{}", e);
+                    Error::Conflict("Found incoming PDU with invalid data.")
+                })?,
                 EventType::RoomCreate => prev_events.is_empty(),
                 // Not allow any of the following events if the sender is not joined.
                 _ if sender_membership != member::MembershipState::Join => false,
@@ -982,13 +982,13 @@ impl Rooms {
         globals: &super::globals::Globals,
     ) -> Result<()> {
         let membership = member_content.membership;
-        let mut userroom_id = user_id.to_string().as_bytes().to_vec();
+        let mut userroom_id = user_id.as_bytes().to_vec();
         userroom_id.push(0xff);
-        userroom_id.extend_from_slice(room_id.to_string().as_bytes());
+        userroom_id.extend_from_slice(room_id.as_bytes());
 
-        let mut roomuser_id = room_id.to_string().as_bytes().to_vec();
+        let mut roomuser_id = room_id.as_bytes().to_vec();
         roomuser_id.push(0xff);
-        roomuser_id.extend_from_slice(user_id.to_string().as_bytes());
+        roomuser_id.extend_from_slice(user_id.as_bytes());
 
         match &membership {
             member::MembershipState::Join => {
@@ -1051,9 +1051,9 @@ impl Rooms {
 
     /// Makes a user forget a room.
     pub fn forget(&self, room_id: &RoomId, user_id: &UserId) -> Result<()> {
-        let mut userroom_id = user_id.to_string().as_bytes().to_vec();
+        let mut userroom_id = user_id.as_bytes().to_vec();
         userroom_id.push(0xff);
-        userroom_id.extend_from_slice(room_id.to_string().as_bytes());
+        userroom_id.extend_from_slice(room_id.as_bytes());
 
         self.userroomid_left.remove(userroom_id)?;
 
@@ -1069,8 +1069,8 @@ impl Rooms {
         if let Some(room_id) = room_id {
             // New alias
             self.alias_roomid
-                .insert(alias.alias(), &*room_id.to_string())?;
-            let mut aliasid = room_id.to_string().as_bytes().to_vec();
+                .insert(alias.alias(), room_id.as_bytes())?;
+            let mut aliasid = room_id.as_bytes().to_vec();
             aliasid.extend_from_slice(&globals.next_count()?.to_be_bytes());
             self.aliasid_alias.insert(aliasid, &*alias.alias())?;
         } else {
@@ -1105,7 +1105,7 @@ impl Rooms {
     }
 
     pub fn room_aliases(&self, room_id: &RoomId) -> impl Iterator<Item = Result<RoomAliasId>> {
-        let mut prefix = room_id.to_string().as_bytes().to_vec();
+        let mut prefix = room_id.as_bytes().to_vec();
         prefix.push(0xff);
 
         self.aliasid_alias
@@ -1119,16 +1119,16 @@ impl Rooms {
 
     pub fn set_public(&self, room_id: &RoomId, public: bool) -> Result<()> {
         if public {
-            self.publicroomids.insert(room_id.to_string(), &[])?;
+            self.publicroomids.insert(room_id.as_bytes(), &[])?;
         } else {
-            self.publicroomids.remove(room_id.to_string())?;
+            self.publicroomids.remove(room_id.as_bytes())?;
         }
 
         Ok(())
     }
 
     pub fn is_public_room(&self, room_id: &RoomId) -> Result<bool> {
-        Ok(self.publicroomids.contains_key(room_id.to_string())?)
+        Ok(self.publicroomids.contains_key(room_id.as_bytes())?)
     }
 
     pub fn public_rooms(&self) -> impl Iterator<Item = Result<RoomId>> {
@@ -1147,7 +1147,7 @@ impl Rooms {
         room_id: &RoomId,
         search_string: &str,
     ) -> Result<(impl Iterator<Item = IVec> + 'a, Vec<String>)> {
-        let mut prefix = room_id.to_string().as_bytes().to_vec();
+        let mut prefix = room_id.as_bytes().to_vec();
         prefix.push(0xff);
 
         let words = search_string
@@ -1233,7 +1233,7 @@ impl Rooms {
     /// Returns an iterator over all joined members of a room.
     pub fn room_members(&self, room_id: &RoomId) -> impl Iterator<Item = Result<UserId>> {
         self.roomuserid_joined
-            .scan_prefix(room_id.to_string())
+            .scan_prefix(room_id.as_bytes())
             .keys()
             .map(|key| {
                 Ok(UserId::try_from(
@@ -1254,7 +1254,7 @@ impl Rooms {
     /// Returns an iterator over all invited members of a room.
     pub fn room_members_invited(&self, room_id: &RoomId) -> impl Iterator<Item = Result<UserId>> {
         self.roomuserid_invited
-            .scan_prefix(room_id.to_string())
+            .scan_prefix(room_id.as_bytes())
             .keys()
             .map(|key| {
                 Ok(UserId::try_from(
@@ -1275,7 +1275,7 @@ impl Rooms {
     /// Returns an iterator over all rooms this user joined.
     pub fn rooms_joined(&self, user_id: &UserId) -> impl Iterator<Item = Result<RoomId>> {
         self.userroomid_joined
-            .scan_prefix(user_id.to_string())
+            .scan_prefix(user_id.as_bytes())
             .keys()
             .map(|key| {
                 Ok(RoomId::try_from(
@@ -1296,7 +1296,7 @@ impl Rooms {
     /// Returns an iterator over all rooms a user was invited to.
     pub fn rooms_invited(&self, user_id: &UserId) -> impl Iterator<Item = Result<RoomId>> {
         self.userroomid_invited
-            .scan_prefix(&user_id.to_string())
+            .scan_prefix(&user_id.as_bytes())
             .keys()
             .map(|key| {
                 Ok(RoomId::try_from(
@@ -1317,7 +1317,7 @@ impl Rooms {
     /// Returns an iterator over all rooms a user left.
     pub fn rooms_left(&self, user_id: &UserId) -> impl Iterator<Item = Result<RoomId>> {
         self.userroomid_left
-            .scan_prefix(&user_id.to_string())
+            .scan_prefix(&user_id.as_bytes())
             .keys()
             .map(|key| {
                 Ok(RoomId::try_from(
@@ -1336,25 +1336,25 @@ impl Rooms {
     }
 
     pub fn is_joined(&self, user_id: &UserId, room_id: &RoomId) -> Result<bool> {
-        let mut userroom_id = user_id.to_string().as_bytes().to_vec();
+        let mut userroom_id = user_id.as_bytes().to_vec();
         userroom_id.push(0xff);
-        userroom_id.extend_from_slice(room_id.to_string().as_bytes());
+        userroom_id.extend_from_slice(room_id.as_bytes());
 
         Ok(self.userroomid_joined.get(userroom_id)?.is_some())
     }
 
     pub fn is_invited(&self, user_id: &UserId, room_id: &RoomId) -> Result<bool> {
-        let mut userroom_id = user_id.to_string().as_bytes().to_vec();
+        let mut userroom_id = user_id.as_bytes().to_vec();
         userroom_id.push(0xff);
-        userroom_id.extend_from_slice(room_id.to_string().as_bytes());
+        userroom_id.extend_from_slice(room_id.as_bytes());
 
         Ok(self.userroomid_invited.get(userroom_id)?.is_some())
     }
 
     pub fn is_left(&self, user_id: &UserId, room_id: &RoomId) -> Result<bool> {
-        let mut userroom_id = user_id.to_string().as_bytes().to_vec();
+        let mut userroom_id = user_id.as_bytes().to_vec();
         userroom_id.push(0xff);
-        userroom_id.extend_from_slice(room_id.to_string().as_bytes());
+        userroom_id.extend_from_slice(room_id.as_bytes());
 
         Ok(self.userroomid_left.get(userroom_id)?.is_some())
     }