Surge
Real-time bar occupancy tracker so nightgoers always know where to go
Project Details
Going out at night is a gamble — you drive across town only to find a bar packed beyond capacity or a dead room with no atmosphere. Door staff track occupancy with hand-held clickers that produce no shared data, no records, and no visibility for anyone outside the venue. There was no layer between the bouncer's counter and the person deciding where to spend their night.
Surge gives every bar a live slot on a public leaderboard showing real-time occupancy, entry rate, and capacity percentage. Bouncers tap + or − on their phone using a secure access-code link, and every press instantly pushes an update to every viewer via Server-Sent Events. Bar owners self-register venues and manage staff, admins approve listings and pull per-venue traffic CSV reports — all without a single spreadsheet or third-party integration.
What It Does
Live Occupancy Leaderboard
A public SSE-powered feed ranks every approved venue by crowd level in real time, with colour-coded capacity bars (green / amber / red) and live entry-rate calculations from the last 10 minutes of events.
Bouncer Counter Interface
Door staff open a URL pre-loaded with their access code and bar ID, select their name, then tap + or − to log each entry or exit. Every event is persisted with a timestamp, previous count, and the bouncer's identity for full audit trails.
Bar Owner Self-Service
Approved bar owners register venues, upload photos directly to Azure Blob Storage, set max capacity, manage specials with date ranges, and generate 12-character access codes that produce a ready-to-share counter URL.
Admin Control Centre
Admins approve or reject both bar-owner accounts and individual venue listings through a dual-queue workflow, reset all occupancy counts before opening, and download per-venue CSV traffic reports broken into 5-minute intervals.
Multi-Location Filtering
Venues are tagged to named locations (e.g. a street or neighbourhood), letting users filter the leaderboard down to only the area they're heading to — useful when a city has dozens of bars across multiple districts.
Resilient Real-Time Updates
The frontend connects via EventSource for push updates; if SSE fails after three reconnect attempts it automatically falls back to 30-second HTTP polling so the leaderboard always stays fresh even on flaky connections.
In Action
Highlights
What We Built
Surge is a real-time nightlife occupancy platform built for two audiences simultaneously: the general public who want to know where to go, and the venues that want to surface that information without any hardware investment. The architecture is a Next.js 15 frontend backed by a FastAPI service, with Azure Cosmos DB holding bars, users, events, and locations in separate containers. Supabase handles authentication and JWT validation, while Azure Blob Storage takes venue photos. Three distinct user roles — public viewer, bar owner, and admin — each get a purpose-built section of the app with route protection enforced at both the middleware and API layers.
The Hardest Problems
The trickiest piece was making leaderboard updates feel instant without polling. We used Server-Sent Events on FastAPI via sse-starlette, and the backend keeps a list of in-memory subscriber queues; whenever a bouncer hits the counter endpoint, the service immediately fans out the updated bar list to every connected client. Getting the frontend to handle SSE gracefully — reconnecting up to three times with exponential back-off before degrading to polling — took more edge-case handling than expected, especially around correctly cleaning up EventSource instances when components unmount. The entry-rate calculation was also non-trivial: rather than updating each bar independently, a single Cosmos DB query fetches all plus events from the last 10 minutes and counts them per bar in one pass, avoiding N+1 queries as the venue count grows.
What We Learned
The approval-queue pattern (separate pending states for both users and bars) was the right call — it means a rogue sign-up can't push a fake bar to the leaderboard — but it added more route logic than initially scoped. In hindsight, a simple role-based middleware factory would have eliminated a lot of the repeated is_admin / is_bar_owner guard code scattered across routers. We also learned that Cosmos DB's cross-partition queries have enough latency to matter when the leaderboard service reloads on every request; moving to a proper in-memory cache that only invalidates on counter events (rather than re-querying Cosmos on every HTTP call) would meaningfully cut response time at scale.
The Result
Surge is a fully functional end-to-end platform: bar owners register and go live in under five minutes, bouncers tap a link from any phone with no app install required, and the public sees crowd levels update live across every venue. The admin layer gives operators full oversight — approvals, traffic reports, and counter resets — without ever touching a database directly. It proves that real-time crowd intelligence doesn't need proprietary sensors or expensive integrations; it needs one person at the door and a single web page.
Like what you see?
Let's build your next product together.