Inspiration

Basically, I like happy hours. Searching high and low across company websites, Google Maps, and social posts to find one is a pain. So our humble app makes it easier for you to have a good time and save a couple bucks. And in this economy, that's priceless.

What it does

It's for the moment you're already out, or about to be, and want to know what's cheap(er) nearby in the next hour.

Open Happy Hour Round Up, see a tiki-styled map of the happy hours around you, and tap "Round up happy hours." A durable server pipeline finds nearby bars and restaurants, reads their actual websites (HTML, PDF menus, even photos of menus), pulls out the specials and streams the results onto the map: days, hours, what's discounted, and real prices right on the pins.

Every deal confirms how recent it is: "Rounded up from saltyiguana.com · checked 2 days ago · high confidence." If we're not confident, you don't get a price pin. If we checked a place and came up empty, it says so, so you can tell "we looked, there's nothing" apart from "nobody has looked here yet." As of this writing that's 3,419 venues checked, 608 with a happy hour found, and 2,684 checked and confirmed empty. The empty ones are on the map too.

Works on the web and as a native iOS app, with a RevenueCat credit wallet. A credit is spent to run a round up and when we actually find you a happy hour.

Awards we're entering

Help Apps Make Money (HAMM). The pricing model is the main feature. We charge per happy hour found (plus one to run the check to prevent constant re-searches). We priced the packs off a measured find rate so a thin margin still maintains profitability. Details in Challenges below.

Best Design. Web and iOS share one set of named design tokens, one named gradient for the round-up fade, and one generated copy file, so the two clients say the same words and cannot drift apart. Every deal on the map has a source: a check date and confidence level (low confidence never gets a price pin.)

How we built it

  • Next.js 16 (App Router) on Vercel, Neon Postgres + Drizzle (embedded PGlite locally), Clerk auth, MapLibre GL + OpenFreeMap tiles restyled into a custom "Tiki Hour" palette.
  • Vercel Workflows for the round-up pipeline (discover, scrape, extract, persist), with one durable retryable step per venue, so a run survives crashes and timeouts.
  • claude-sonnet-5 for extraction. Google Places (New) as an ephemeral server-side discovery seed. US Census / Nominatim for geocoding.
  • RevenueCat Virtual Currency for the wallet, plus a native SwiftUI iOS app that shares a fixture-tested API contract with web.
  • Scraper politeness is non-negotiable: robots.txt, one in-flight request per domain, 1 to 2 second jitter, and an identifiable bot UA with a public /bot page explaining who we are.

Challenges we ran into

Google's Terms of Service are a real architectural constraint. You can't store Places data or render it on a non-Google map. So Places became a discovery seed only. We keep nothing but the place_id, and every name, address, and menu you see comes from the venue's own website. Coordinate fallbacks expire inside 30 days and get purged nightly.

Nearby Search caps at 20 results. Dense neighborhoods (exactly the ones with the good happy hours) came back looking half empty. We fixed it with quadtree subdivision, so a busy viewport gets carved into smaller tiles until the coverage is honest.

Then making every search cheaper than the last one. Discovery is the expensive part, so we cache it: a second round-up over ground someone has already worked costs nothing to discover and only reads the venues nobody has read yet. The lasso sizes itself to how dense the venues are, so a downtown block and a suburban strip cost about the same. And a venue checked recently gets skipped instead of read again. This is what lets one person's round-up permanently make the map cheaper for the next person.

Monetization. We wanted this cheap for users and still profitable, which made the pricing unit the real issue. We looked at three options: charge per round-up, charge only for happy hours we actually find, or pass through raw cost per run. We picked 1 & 2. We would have liked to keep just charging for happy hours found, but the downside was too large, until we can figure out a more predictable model. Passing through raw cost makes the price unpredictable. Only about one venue in six has a happy hour at all (a measured 17.2% find rate), so a consumed credit costs us about 30 cents to earn. The packs charge 40 to 50 cents a credit, and being in Apple's Small Business Program means the store takes 15% rather than 30%, which is what makes a margin that thin survive. New users get 5 free venue checks to start.

Accomplishments that we're proud of

No matter the monetization model, we figured out how to deliver this at a genuinely low cost. Every user who rounds up their own neighborhood permanently improves the map for everyone else, and the credit model keeps that expansion close to breakeven instead of turning into a subscription nobody wants. A few bucks builds out a whole city.

What we learned

A lot of the hardest work here went into surfacing uncertainty (low confidence, stale checks, unchecked areas) rather than papering over it. Users trust a map that admits what it doesn't know, and it made the product better.

What's next for Happy Hour Round Up

  • Persistent coverage-gap notes on the map ("14 venues here we've never checked")
  • Push notifications when a saved spot changes its happy hour
  • Social and sharing features
  • Venue owner claiming, since the eventual business is bars paying to keep their own listing accurate
  • Exploring more cost effective alternatives to Google Maps that don't sacrifice findability
  • Exploring Jev to reduce cost for finding happy hours

Built With

Share this project:

Updates

Submission history