← All projects
Case study / Consumer app

Swipe and match APIs for a dating app

The backend for a mobile swipe-and-match loop, tuned to stay consistent under heavy traffic.

Role
Backend developer
Company
SoftwareSeni
Period
2024 — Now
Stack
Laravel, Livewire, Redis, Amazon S3, PHPUnit, Docker
01

Context

A mobile dating app where the core loop is swipe, match, then chat. The mobile team consumed the REST API I built in Laravel, and the client’s admins used a Livewire panel to manage users and content.

02

The problem

As the user base grew, the swipe endpoint slowed down, and two people swiping on each other at the same moment could produce duplicate or missing matches.

03

What I did

  • Built and optimised the swipe and match APIs used by the mobile frontend.
  • Implemented atomic locking with the team so concurrent swipes resolve to exactly one match.
  • Added Redis caching to cut repeat reads from the database.
  • Integrated third-party APIs and stored uploads on Amazon S3.
  • Broke features into smaller tasks so other developers could pick them up.
  • Reviewed code and shared feature ideas directly with the client.
04

The locking fix

The race happened between checking for an existing like and writing the match. Wrapping that pair in a short cache lock made the write atomic without locking whole tables.

// lock the pair so two swipes can't create two matches
$key = "match:" . min($a, $b) . ":" . max($a, $b);
$lock = Cache::lock($key, 5);

if ($lock->get()) {
    try {
        UserMatch::firstOrCreate(['user_a' => $a, 'user_b' => $b]);
    } finally {
        $lock->release();
    }
}
Simplified example of the pattern, not production code.