A few months ago I got tired of how job hunting actually works. You find a role you like, you apply, and then you realize it was posted three days ago and already has 400 applicants. By the time a job shows up in your normal scroll, you're already late.
So I built FindMeJobs to flip that around. Instead of me checking job boards, it checks them for me, constantly, and messages me the second something matches what I'm actually looking for.
Here is how it is put together.
The core idea
You define a search once: keywords, boolean include/exclude rules, location, and so on. From then on a pipeline scrapes fresh postings every few minutes, filters them against your rules, runs the survivors through an AI relevance check, and if something matches you get a Telegram or email alert within minutes of it going live.
Being early is basically the entire value, so the whole system is built around latency.
The stack
The app itself is a fairly standard T3-style setup:
- Next.js 16 (App Router) + React + TypeScript
- tRPC for end-to-end typed APIs
- Drizzle ORM on Postgres
- Supabase for auth
- Stripe for subscriptions
- Tailwind + shadcn/ui on the frontend
Nothing exotic there. The interesting part is the scraping and notification pipeline, which does not live inside the Next.js app at all.
The pipeline (the actually hard part)
Scraping runs entirely on Cloudflare Workers + Queues on a cron schedule:
- An orchestrator worker wakes up on a schedule, pulls every active search from the DB, and enqueues scrape jobs.
- A consumer worker runs the scrape and pushes raw results onto a filter queue.
- A cheap keyword filter worker applies the boolean rules first, so I am not paying for an LLM call on obviously irrelevant jobs.
- Whatever survives goes to an AI filter for relevance scoring and short summaries.
- Matches hit a notification worker that sends the Telegram or email alert.
Splitting it into queue stages meant each step scales on its own, and one slow scrape never blocks notifications for a different user.
Things that bit me
- Full-text search at scale. Postgres GIN indexes on job descriptions made search usable, but I had to be careful about when queries fall back between the ORM and raw SQL.
- Reliable scraping. This was by far the hardest part and where most of my time went. Getting fresh data consistently, without things quietly breaking, took more iteration than the rest of the app combined.
- Latency vs cost. Running an LLM on every scraped job would be both slow and expensive, which is the whole reason the cheap filter runs before the AI one.
If you want to poke at it
The product is live at findmejobs.co, and I put up a repo with more detail and a discussions space here: https://github.com/ali-moussavi/findmejobs. Happy to get into the architecture in the comments.
And if you have job hunted recently, I would honestly like to hear which part of the process annoyed you the most. That is mostly what I have been building against.
Top comments (0)