We've completely rebuilt our matchmaking system with 3 waiting rooms to save you from awkward re-matches!
Nhat Vu
(eme)
Our previous matchmaking system was like throwing strangers into a room blindfolded and hoping they'd hit it off. It worked, mostly. But there was one tiny problem: the dreaded re-match. You know that moment when you've just finished an awkward conversation with someone, hit "next," and there they are again? It's like leaving an awkward coffee shop chat, only to find you parked next to each other. Not fun.
For more information about the previous matchmaking, please read Tyron's blog here
So, we've revamped our matchmaking logic. Instead of one waiting room where everyone might get rematch with the same person, we now have THREE waiting rooms:
This means if you and your chat partner decide to part ways, you'll each be shuffled into separate waiting rooms—dramatically reducing the chance of an awkward reunion. It's like having bouncers escort you out different exits after an awkward meetup :D
Behind the scenes, our matchmaking is still powered by the same Postgres functions but now they're working triple shifts. Here's a simplified look at how the magic happens:
CREATE OR REPLACE FUNCTION find_match(user_id text)
RETURNS TABLE (match_id UUID, user1 text, user2 text, status TEXT) AS $$
BEGIN
-- If already matched, return current match
IF (SELECT EXISTS(SELECT 1 FROM matches WHERE (user1 = user_id OR user2 = user_id) AND status = 'active')) THEN
RETURN QUERY SELECT m.match_id, m.user1, m.user2, 'existing'::TEXT
FROM matches m
WHERE (m.user1 = user_id OR m.user2 = user_id) AND m.status = 'active';
RETURN;
END IF;
-- Clear any existing waiting status
DELETE FROM waiting_room WHERE user_id = user_id;
-- Remove inactive users
DELETE FROM waiting_room WHERE NOT is_online(user_id);
-- Assign to a random waiting room (1-3)
INSERT INTO waiting_room (user_id, room_number)
VALUES (user_id, floor(random() * 3) + 1);
-- Try to find a match in the same waiting room
WITH potential_match AS (
SELECT wr.user_id AS matched_user
FROM waiting_room wr
WHERE wr.user_id != user_id
AND wr.room_number = (SELECT room_number FROM waiting_room WHERE user_id = user_id)
ORDER BY RANDOM()
LIMIT 1
FOR UPDATE SKIP LOCKED
)
SELECT matched_user INTO matched_user FROM potential_match;
IF matched_user IS NOT NULL THEN
-- Found a match!
DELETE FROM waiting_room WHERE user_id IN (user_id, matched_user);
INSERT INTO matches (user1, user2, status)
VALUES (user_id, matched_user, 'active')
RETURNING match_id, user1, user2, status INTO match_id, user1, user2, status;
RETURN QUERY SELECT match_id, user1, user2, 'matched'::TEXT;
ELSE
-- Stay in waiting room
RETURN QUERY SELECT NULL::UUID, user_id, NULL::TEXT, 'waiting'::TEXT;
END IF;
END;
$$ LANGUAGE plpgsql;
Here’s a quick, no-code explanation of how it works:
For AnimoChat user, this means less digital déjà vu and more fresh conversations. You can now hit "next" with confidence, knowing that your paths are unlikely to cross again with that person who thought your joke about String theory was "actually quantum physics" (ugh).
Social interactions can sometimes feel a bit overwhelming. That's why we've built a system that lets you smoothly transition to a new conversation without the awkwardness of running into the same person again. It's all about keeping things fresh and comfortable for you!
In a world where digital connections are random, the least we can do is make sure they're not repetitively random.
AnimoChat's three-room matchmaking isn't just a technical upgrade—it's an awkwardness avoidance system.
So next time you find yourself in a delightfully random conversation on AnimoChat, remember: there's a complex system of digital bouncers working tirelessly to ensure your next match will be someone completely new to judge your memes and typos.
Happy chatting! And remember, if the matchmaking ever feels slow, it's not the system—it's just that everyone else found their digital soulmate before you. (Just kidding :D)
P.S. There's still a slight that that you might match with your ex chat partner again. 😉