How Frae ranks group availability

Dr Marcus Judge, CEO of Frae · · Updated · 8 min read

On the surface, Frae looks simple. Friends tap the dates they can make, the app surfaces the best date, the host picks. But the moment you start writing the algorithm down, you realise it isn't simple at all. There are at least three different definitions of "best date", and they conflict with each other in interesting ways.

This post describes the comparator in the current server code. There is no predictive model and no hidden reliability score. The ordering comes from four explicit rules.

The naive version

When I first sat down to write the scheduling logic, my instinct was the same as everyone's: count votes. The date with the most yeses wins. Done.

This works for the trivial case. Six friends, the 14th gets all six, the 14th wins. But it falls over the moment you have a tie. And it falls over even harder when you think about what "I haven't responded yet" actually means.

Imagine an event with six invitees. Three have responded. One date has all three of them as available. A second date has two responders available. Naive vote counting tells you the first date is twice as good as the second. But what if the three people who haven't responded are systematically more likely to be free on the second date? You don't know. You're picking based on incomplete information and pretending it's complete.

Non-responders stay unknown

Frae only counts dates that people explicitly mark as available. A missing response is not silently converted into a yes or a no. The results also show how many invitees have responded, so the host can decide whether to wait or choose with incomplete information.

The four ranking rules

For each candidate date, Frae splits available responses into two tiers. Tier one contains the organiser and anyone the host marks as must-attend. Tier two contains the remaining invitees. The server then sorts dates in this order:

  1. More tier-one people available. A date that works for more must-attend people ranks above one that does not.
  2. More tier-two people available. If the tier-one count ties, the date that works for more of the rest of the group ranks higher.
  3. The event's day preference. If the counts still tie, an optional preference for weekends or weekdays breaks the tie.
  4. The earlier date. A complete tie resolves to the earliest candidate date, making the result deterministic.

Suppose Saturday works for both must-attend people and three other friends, while Sunday works for one must-attend person and five other friends. Saturday ranks first. The must-attend tier is deliberately evaluated before the total headcount; it prevents a birthday poll from recommending a date the person whose birthday it is cannot attend.

What we deliberately didn't do

There were a few sophisticated approaches we considered and then deliberately rejected.

No reliability score. A person's vote is not worth less because they changed a previous plan.

No prediction for missing answers. Frae does not guess that someone is probably free based on earlier events.

No opaque combined score. The tier counts and tie-breaks remain explainable. The host can see why one date is above another and can still choose differently.

The view from the host's seat

The host sees ranked dates, availability counts and attendee details. Frae does the counting and applies the declared priorities; it does not make the final social judgement. The host may know that a lower-ranked date avoids travel, childcare or another constraint that was never part of the poll.

That is the boundary we want. The algorithm should make the trade-offs legible, then leave the decision with the person organising the plan.

Why publish the rule

Ranking logic affects real plans, so it should be possible to explain it without marketing language. If the comparator changes, this article and its 8 August 2026 update date must change with it. The source code remains the final authority.

The goal has always been the same. Help people get a dinner booked.

← Back to all posts