← All writing

The Engineering Behind Matching Two People

Exploring Gale–Shapley, reciprocal matching, and how Hinge's recommendation system has evolved.

By Herin Soni26 September 20268 min read

The Problem

Many of you people might already know about feed & matching algos used in apps like Instagram, Twitter, Youtube, Amazon etc .. but in most of these cases we focus on one sided likability. for example .. while creating a feed for Instagram Reels I truly care about whether user likes that particular piece of content or not?

For Hinge or similar platforms , story is bit different .. Here, We care for reciprocal likeability ,not one-sided (XD) ..

For example , Let's assume Sam likes Dario. Now, on this sole assumption if we show Dario in Sam's feed then we will most likely not achieve success . why?

Because in this case, success requires mutual interest. Even if Sam sends Dario a Like, Dario might not reciprocate. Maybe he's simply not interested in Sam.

And here comes the problem:

How can we find a person X whom Sam is likely to like, and who is also likely to like Sam back?

That's what we're going to try to figure out.

How Do We Solve This?

Suppose we know Sam's preferences that means we can rank people based on sam's preferences

  • Andrej 0.78
  • Elon 0.67
  • Alex 0.97
  • Dario 0.14

Based on these scores, Sam's preference list would look something like this: Sam : Alex > Andrej > Elon > Dario

and let's assume for Alex : Andrej > Dario > Sam > Elon

noticed the gap? , Sam ranks Alex first, but Alex ranks Sam third !

Knowing Sam's preferences alone doesn't tell us whether Alex would reciprocate. We need both people's preference lists.

and this problem leads us to a very intuitive and simple , "Gale–Shapley algorithm"

The idea is to find a stable matching. Not necessarily a matching where everyone gets their first choice, but one where no two people would both prefer each other over their currently assigned partners.

Hinge's original Most Compatible feature was famously associated with a variation of this algorithm. This is probably the easiest explanation of the algorithm I've come across:

youtube.comhttps://www.youtube.com/watch?v=0m_YW1zVs-Q

Let's Actually Try It With an Example

For the classical Gale–Shapley algorithm, we'll use two separate groups, each with two people.

Diagram

Now let's assume Group A proposes.

Round 1: Both Sam and Noah propose to Alex. But Alex prefers Noah, so Alex tentatively accepts Noah and rejects Sam.

Round 2: Sam moves to his next preference, Dario, who accepts his proposal.

And we're done! Our final matching is :

  • Sam ↔ Dario
  • Noah ↔ Alex

But wait, Sam wanted Alex more than Dario. So why are we calling this a successful matching? Because Alex prefers Noah over Sam. There isn't a pair of people who would BOTH rather leave their assigned partners and match with each other. That's what makes it stable. Also, notice that the algorithm never needed our numerical compatibility scores. It only needed the preference rankings. And that's an important distinction we'll come back to.

But Wait, Where Did These Preference Lists Come From?

Remember how we started with "Suppose we know Sam's preferences"?

Well, that's a pretty big assumption. We simply assigned Alex a score of 0.97, Andrej 0.78, and so on. But where did these numbers come from in the first place? ofc It's not like Sam opens Hinge and manually ranks every single person on the platform XD. In practice, we would have to estimate these preferences using the information we have about Sam and his previous interactions. His likes, skips, stated preferences, and the profiles he has actually been shown could all help us generate these scores.

Let's say our system estimates:

  • Sam → Alex : 0.97
  • Alex → Sam : 0.32
  • Notice something?
  • These are two different, directional scores.

We need to estimate preferences in both directions. But once we have these scores, there's another interesting question: should we optimise for the highest reciprocal compatibility score, or for a stable matching? Turns out, those two objectives don't necessarily give us the same result.

Stable Matching ≠ Maximum Compatibility

Now that we have directional preference scores, there's something interesting we can test.

Let's take the same four people from our Gale–Shapley example and assign them a new set of hypothetical preference scores, just for this experiment.

These numbers produce the exact preference lists we used earlier.
These numbers produce the exact preference lists we used earlier.

Now, just for experimentation, let's define a reciprocal score by multiplying the two directional scores:

R(A, B) = S(A → B) × S(B → A)

Here are the results:

Diagram

Remember the matching Gale–Shapley gave us?

Sam–Dario and Noah–Alex.

Their combined reciprocal score is just 0.1365.

But what if we instead matched Sam–Alex and Noah–Dario? Their combined score would be 0.6965.

So why didn't Gale–Shapley choose the second assignment? Because it would be unstable. Noah and Alex prefer each other over their respective partners, forming what is called a blocking pair. And this illustrates something important:

Gale–Shapley guarantees stability, not the maximum possible sum of compatibility scores.

Neither objective automatically means two people will actually Like each other back. Stability is a mathematical property of the supplied preference lists, not a prediction of real-world consent or connection.

Also, our multiplication formula is just a toy heuristic. We're not claiming it's Hinge's actual formula, or that multiplying arbitrary preference scores produces a valid probability of matching.

So, What Does Hinge Actually Do?

The Original Approach (2018) :

When Hinge introduced its Most Compatible feature in 2018, it was publicly described as using a Gale–Shapley-inspired approach.

The interesting part was that it wasn't simply trying to find someone you might like. It was trying to find a pairing where the preferences aligned on both sides.

Hinge's founder Justin McLeod explained at the time that the person being recommended to you would also see you. The system learned from users' Likes and passes, then used those preferences to identify promising pairings. One interesting detail: classical Gale–Shapley works with two separate groups. The 2018 reporting also discussed Hinge adapting the matching problem for people outside that two-group structure, referencing the Stable Roommates Problem. So even back then, it wasn't as simple as copying the textbook algorithm and calling it a day XD.

techcrunch.comhttps://techcrunch.com/2018/07/11/hinge-employs-new-algorithm-to-find-your-most-compatible-match-for-you/

But Hinge Has Changed Since Then :

This is important because a lot of articles on the internet still explain Hinge as though it runs the same Gale–Shapley algorithm from 2018. In 2025, Hinge introduced a new deep-learning recommendation system for its Discover experience.

In fact, Hinge itself now describes its system as a collection of algorithms rather than one algorithm doing everything.

According to its official explanation, the system considers:

  • Your compatibility preferences: Things like age, distance, religion,relationship type..
  • Dealbreakers: (Non-negotiable preferences)
  • Your previous behaviour: Likes, matches, skips etc

And the interesting bit is that Hinge explicitly says its newer system attempts to understand not just whom you might like, but who might like you back.

Sounds familiar, right? That's exactly the problem we started with.

hinge.cohttps://hinge.co/how-we-connect-daters

Are They Still Using Gale–Shapley Today?

Hinge's original Most Compatible feature was associated with a Gale–Shapley-inspired approach in 2018. However, in 2025, Hinge introduced a new deep-learning recommendation system for Discover. Its exact architecture isn't public, so we can't confirm whether Gale–Shapley is still part of the current pipeline.

But here's the interesting distinction: Gale–Shapley solves a stable assignment problem, while a recommendation system solves a prediction and ranking problem. Gale–Shapley takes already-ranked preference lists and finds a matching with no blocking pair. It doesn't generate preference scores, maximise total compatibility, or predict whether someone will actually send a Like back. Our earlier reciprocal scoring formula was just a simplified example, NOT Hinge's actual implementation.

And IMO, generating those preference lists is where the real engineering begins. A system needs to filter eligible candidates, estimate preferences in both directions, rank promising pairs, and continuously learn from interactions. Even the feedback is tricky: Sam skipping Alex might be a negative signal, but Sam never seeing Alex tells us nothing. Treating both as rejection would introduce bias into our training data. So what started as a simple matching algorithm quickly turns into a much larger problem involving candidate retrieval, reciprocal ranking, exposure bias, and continuously changing preferences.

A Tiny Experiment: No Like ≠ Dislike

There's one more interesting problem I wanted to test.

Suppose we have 100 users, and our recommendation system has shown them two different profiles:

Diagram

Now, if we naively treat everyone who didn't Like a profile as someone who rejected it, we get:

  • Alex: 8 / 100 = 8%
  • Dario: 20 / 100 = 20%

Looks like Dario is doing much better, right? But wait, Alex was only shown to 10 people in the first place XD. What happens if we calculate the Like rate using only the people who were actually shown each profile?

  • Alex: 8 / 10 = 80%
  • Dario: 20 / 50 = 40%

Our ranking just flipped! We were mixing two completely different things: how frequently our algorithm showed a profile, and how people responded after seeing it. Mathematically, what we measured initially was:

P(Shown AND Liked) = P(Shown) × P(Liked | Shown)

So the first score wasn't purely measuring preference. It was also affected by how much exposure each profile received. And even the second calculation isn't a perfect representation of everyone's preferences, because the existing recommendation algorithm decides who gets shown what. This is where exposure bias enters the picture. Our future training data is partially determined by our previous recommendations.

If You Want to Go Further

If you found this interesting, try implementing Gale–Shapley yourself. It's barely ~30 lines of code. Run it on simulated preference lists and compare the result against a greedy matcher that simply picks the pair with the highest reciprocal score first.

Compare their combined scores and count how many blocking pairs each matching produces. It's a nice little experiment to understand why maximising compatibility and finding a stable matching are two different objectives. And there's more to explore. Is one-to-one stable matching even the right abstraction when people can have multiple matches simultaneously? How would we shortlist candidates without exhaustively scoring millions of pairs? One possible approach involves two-tower embeddings and approximate nearest-neighbour search (FAISS/HNSW), followed by more expensive reciprocal ranking. And remember our exposure-bias experiment? Look into inverse propensity weighting and bandit-style exploration. The former uses logged exposure probabilities to correct certain selection biases, while the latter helps us learn about candidates we might otherwise never recommend.

That's It!

I initially thought Gale–Shapley was the interesting part of Hinge, but turns out, stable matching is only one part of a much bigger recommendation problem. And my favourite takeaway from this rabbit hole? A mathematically stable match, a high compatibility score, and two people actually liking each other are three very different things XD.