fourth.
the missing player
Built for golfers in Colorado Springs, where golf is sold by the group, not by the player. Three golfers with an empty seat either absorb the cost of a no show or spend the week asking around. That missing player is the product, and the name.

Engineering Proof
Verified build benchmarks
Key performance numbers confirmed against our production codebase and release history.
01 / The Problem
No reliable way to fill an open tee time
The brief came from Colorado Springs golfers, and the problem was the same one every week: open spots get re-posted across fragmented group chats, with zero certainty on who is committed until they show up at the first tee.
There is no lightweight channel to reach golfers outside the usual circle, and nobody waiting at home can follow a round in progress. And the moment two people do respond, there is no arbiter. Both believe they have the seat.
02 / What We Built
Post a round, fill the seat, watch it play out
A golfer posts course, date, time, and open places. The round lands in a live feed other golfers join in one tap. Rounds are public or invite only. Once play starts it is tracked hole by hole.
- 01
Tee time creation in under 20 seconds: course, date, time, spot count, and a public or private toggle.
- 02
Real time feed of public rounds with live spot counts, host, and handicap. Private rounds route through a separate invite only join flow.
- 03
Atomic join that decrements spots and registers the golfer in a single database write.
- 04
Hole by hole progress with pace calculations and a shareable web link.
- 05
Colour reserved purely for status: fairway green live, orange low spots, red cancelled or full.

03 / Engineering Challenges
Four problems the build had to solve
A tee time app looks like a list of rounds until two people tap Join in the same second, and the coordination problem it replaces is mostly a trust problem.
Two golfers claiming the last spot at once
Read the spot count then write, and both players read one seat free and both write. The round ends up with five golfers and a host who has to uninvite someone.
Joining runs as an atomic transaction that decrements the spot count and registers the golfer in a single database write, so the race condition cannot produce a double booking.
Reaching golfers outside the usual group
When a spot opens there is no lightweight channel to anyone beyond the existing friends circle. The round either goes short or the host spends the week asking around.
A public feed of open rounds, each card showing the course, date, time and exactly how many spots remain, joinable in one tap without an introduction or a group chat.
No single source of truth on who is committed
Tee times get re-posted across several messaging threads, so nobody knows who has actually confirmed until they turn up at the first tee.
One record per round holds the confirmed group. Hosts are notified the moment someone joins, and players are alerted if the host cancels, so commitment is visible in one place rather than inferred from a chat.
Following a round you are not playing in
People waiting at home, or at the clubhouse, have no way to see where a group has got to or roughly when they will finish.
Rounds are tracked hole by hole with pace of play and an estimated finish time, shared through a web link that needs no app on the other end.
04 / Tech Stack & Client Feedback
One Flutter codebase, two app stores
Built with clean architecture, Riverpod state management, and Cloud Firestore.
“The architecture is exactly what we needed, Riverpod keeps everything reactive, the join transaction has never failed, and the deep link routing works perfectly from push notifications.”
Founder, fourth. Golf App
Explore More Work
Related case studies
Let us build your product's fourth.
Tell us the problem your users run into and we will bring the engineering to fix it, end to end.
Start a project