diff --git a/src/discordas.ts b/src/discordas.ts
index 49c65c1a4c5e638d810247a4b6ae99d57efc599c..1f020159e12eb1a4a64c682c7e2d69b04d7b69c4 100644
--- a/src/discordas.ts
+++ b/src/discordas.ts
@@ -30,8 +30,6 @@ import { Response } from "express";
 
 const log = new Log("DiscordAS");
 
-const ADMIN_ROOMS_KEY = 'uk.half-shot.discord.admin-rooms';
-
 const commandOptions = [
     { name: "config", alias: "c", type: String },
     { name: "url", alias: "u", type: String },
@@ -230,20 +228,44 @@ async function run(): Promise<void> {
 
 }
 
-interface AdminRooms {
-    [mxid: string]: string;
+async function findDMRoom(client: MatrixClient, targetMxid: string): Promise<string|undefined> {
+    const rooms = await client.getJoinedRooms();
+    const roomsWithMembers = await Promise.all(rooms.map(async (id) => {
+        return {
+            id,
+            memberships: await client.getRoomMembers(id, undefined, ['join', 'invite']),
+        }
+    }));
+
+    return roomsWithMembers.find(
+        room => room.memberships.length == 2
+             && !!room.memberships.find(member => member.stateKey === targetMxid)
+    )?.id;
 }
 
-async function notifyBridgeAdmin(client: MatrixClient, adminMxid: string, message: string) {
-    log.verbose(`Looking up admin room for ${adminMxid}`);
-    let adminRooms = await client.getAccountData<AdminRooms>(ADMIN_ROOMS_KEY).catch(() => null) || {};
-    if (!adminRooms[adminMxid]) {
-        log.verbose(`Creating an admin room for ${adminMxid}`);
-        adminRooms[adminMxid] = await client.createRoom();
-        await client.inviteUser(adminMxid, adminRooms[adminMxid]);
-        await client.setAccountData(ADMIN_ROOMS_KEY, adminRooms);
+async function ensureDMRoom(client: MatrixClient, mxid: string): Promise<string> {
+    const existing = await findDMRoom(client, mxid);
+    if (existing) {
+        log.verbose(`Found existing DM room with ${mxid}: ${existing}`);
+        return existing;
+    }
+
+    const roomId = await client.createRoom();
+    try {
+        await client.inviteUser(mxid, roomId);
+    } catch (err) {
+        log.verbose(`Failed to invite ${mxid} to ${roomId}, cleaning up`);
+        client.leaveRoom(roomId); // no point awaiting it, nothing we can do if we fail
+        throw err;
     }
-    await client.sendText(adminRooms[adminMxid], message)
+
+    log.verbose(`Created ${roomId} to DM with ${mxid}`);
+    return roomId;
+}
+
+async function notifyBridgeAdmin(client: MatrixClient, adminMxid: string, message: string) {
+    const roomId = await ensureDMRoom(client, adminMxid);
+    await client.sendText(roomId, message)
 }
 
 let adminNotified = false;