Marketplaces & booking
Job board - search, apply, and the recruiter's inbox
How listings are indexed for search and applications are routed, and why expired jobs must disappear fast.
What this board gets wrong on purpose
The tension
The board makes a CLOSED job disappear within minutes, but it can only close a job somebody tells it about. A feed job that vanishes from its ATS is noticed at the next poll, up to four hours later, and a directly posted job that was filled last week but never closed stays live until valid_through - thirty days by default - collecting applications from people who will never hear back. Nothing here detects that ghost job, even though the signal is on the board: an inbox nobody has opened for fourteen days. The inbox has its own unanswered question: a remote role takes 2,000 applications in 48 hours, a recruiter reads about the first hundred, and the default sort is newest first - so whether a candidate is seen is decided by the order the board renders a list, not by anything about the candidate. And a webhook to an ATS that answers 200 and then drops the application marks it DELIVERED into a void.
Practise this as an interview
Take Job board - search, apply, and the recruiter's inbox as a timed system design interview on a blank board - on your own, with the requirements to check yourself against, or with a candidate you invite.
Start here
Why this design
A job board is a full-text and geo search over a catalogue that turns over completely every month, plus a delivery system that carries applications to wherever the recruiter really works. Interviewers use it to see how you index fast-changing documents, how you make deletion reliable rather than eventual, and whether you notice that most listings are imported from somebody else's system on a timer.
What you will learn
- Why removing a closed job from search is the product's freshness promise, not housekeeping.
- Why expiry has two mechanisms: an outbox delete and a valid_through filter on every query.
- Why 80% of jobs arrive by feed, re-fetched every four hours, and why a content hash makes that cheap.
- Why an application is routed to the employer's ATS or an inbox, and is one row per candidate per job.
- Why a hot remote job takes 2,000 applications in 48 hours, and what the inbox's sort order decides.
- Why a job that is filled but never closed is the failure this board cannot see.
How to read this board
- Press play once: the walkthrough follows a search, an application, and then a job closing.
- FIND & APPLY: query, freshness filter, index, apply.
- THE RECRUITER'S INBOX: routing to an ATS or the board's own inbox.
- POSTINGS & EXPIRY: direct posts, feed imports, the outbox, the sweeper and the indexer.
- DATA MODEL: jobs with their own expiry date, and applications unique per candidate.
- Then pages 1 to 6 in order: requirements, capacity, storage, availability, how it works, deployment.
1 · Requirements
Two customers with opposite needs: seekers want every live job and no dead ones; recruiters want the right hundred applications, not two thousand.
Ask these before designing
- Where do jobs come from? Direct posts by recruiters, or feeds from applicant tracking systems? Usually both, with feeds the large majority.
- Where do applications go? Our own inbox, the employer's ATS by webhook, or a redirect to the employer's site? Each has a different delivery guarantee.
- How fast must a closed job disappear? Minutes is achievable for jobs we are told about. Jobs we are not told about are the real problem.
- Is a listing paid? A paid listing has a hard end date, which is the one expiry you can always trust.
- Can a candidate apply twice to one job? No - and a double tap on Apply must not send two.
Functional
- Search by keywords, location radius, remote, salary range, seniority, posted date.
- Apply with a stored résumé and screening answers in one step.
- Route each application to the employer's ATS or to the recruiter inbox.
- Recruiter inbox: list, sort, filter and change stage on applications.
- Recruiters post, edit and close jobs; employers' ATS feeds are imported on a schedule.
- Jobs expire automatically at valid_through.
Non-functional
- Search p95 under 250 ms at 8,300 queries/s peak.
- Closed or expired jobs out of search within 5 minutes of the board knowing; and never shown past valid_through.
- Application accepted exactly once per candidate per job, durably, before the seeker sees "sent".
- ATS delivery p99 under 2 minutes, retried for 72 hours.
- Search availability 99.95%; apply 99.9%.
Out of scope
Recommendation and matching models, sponsored-listing auctions, messaging, interview scheduling, salary estimation, employer reviews.
The rest of this board
Available on Tier Slate
This page publishes the question. The answer — 5 more written pages, an 8-step narrated walkthrough and a 5-table schema — is the board itself, and it opens in Tierslate.
- 5written pages
- 8walkthrough steps
- 5tables36 columns
5 pages behind this one
- Capacity estimation
- Storage estimation
- Availability
- How it works
- Deployment plan
More boards
Two-sided systems where inventory must not be sold twice.
- Checkout - holding stock you have not sold yet
- Auction bidding - the clock is part of the system
- Food delivery - three parties and a promise
- Hotel booking - selling a range, on purpose, slightly twice
- Seat sales - fifty thousand people, one hundred seats
- Coupon codes - redeemable once, by anyone, at the same moment
- Rental search - availability is a calendar, not a column