System Design Interview
Design a Free Local Gig Marketplace (Small Jobs Platform)
A zero-fee platform where students, refugees, and households find each other for babysitting, cooking, pet care, and painting — trust built through reviews alone
The Interview Question
"Design a free platform where people can post and find small local jobs — babysitting, cooking, pet care, painting, cleaning. The platform is used by students, refugees, and households. It must cost nothing to use: no registration fee, no payment processing, no subscription. People communicate through the app, arrange payment between themselves, and leave reviews. The only thing the platform provides is discovery, messaging, and a review system that builds trust over time."
This question tests marketplace design without the usual payment rails, trust and safety without payment data as a signal, geo-based discovery, and how to build a useful product with near-zero operating cost. Most candidates over-engineer this — the discipline is knowing what to leave out.
Step 1: Requirements
Functional
- Anyone can post a job: title, description, category, location, when, approximate pay expectation
- Anyone can post a profile: skills, availability, location, languages spoken, short bio
- Search and browse jobs/profiles by category, distance, and availability
- In-app messaging between job posters and workers (pre-hire conversations)
- Review system: after a job, both parties can leave a rating (1–5) and text review
- No payment processing — parties agree and pay each other directly (cash, Vipps, etc.)
- Multi-language support (Norwegian, English, Arabic, Somali, Polish — common in Norway)
Non-functional
- Free to use — zero fees for users, zero registration cost
- Mobile-first: many users are on phones only, low-end Android devices
- Accessible to users with low digital literacy
- 100,000 active users (realistic scale for a regional Norwegian platform)
- Location search: results within user-specified radius (1–20 km)
- Message delivery latency: under 3 seconds
What this platform explicitly does NOT do:
- Process payments
- Verify identities (no BankID requirement — excludes refugees without Norwegian ID)
- Guarantee job completion
- Handle disputes
Step 2: The Core Design — What Makes This Different
Most gig platforms (Uber, TaskRabbit, Fiverr) use payment processing as the trust backbone:
- You can't be a fake worker if you've provided bank details
- Reviews are attached to completed, paid transactions — hard to fake
- Disputes are resolved via payment holds and chargebacks
This platform has none of that. Trust must be built entirely through reviews. This changes every major design decision.
Gig platform with payments:
Trust signal: payment history + verified bank account + completed jobs
Fraud cost: high (chargebacks, refunds, fake accounts)
This platform (no payments):
Trust signal: reviews only
Fraud risk: fake accounts with fake reviews — must be designed against
Operating cost: dramatically lower (no payment processor, no compliance)Step 3: The Review System — The Most Important Feature
Since reviews are the only trust signal, fake reviews destroy the platform. The design must make review manipulation expensive.
Rule: you can only review someone after a confirmed conversation.
Job flow:
1. Worker sees job post → sends message to poster
2. Poster replies → "conversation confirmed" (both parties have messaged)
3. Job happens in the real world (platform not involved)
4. Either party can submit a review for the other
→ Only unlocked if a confirmed conversation exists between them
→ One review per conversation (no repeat reviews for same job)
→ Review window: 14 days after last message in conversation
REVIEW table:
reviewer_id UUID
reviewee_id UUID
conversation_id UUID UNIQUE ← one review per conversation per reviewer
rating INT CHECK (rating BETWEEN 1 AND 5)
text TEXT (max 500 chars)
created_at TIMESTAMPTZWhy "confirmed conversation" and not "confirmed job"? The platform cannot know if a job actually happened — it has no payment record. But it can verify that two real people had a real exchange in the app. This requires a non-trivial effort from a fake account: create an account, initiate a conversation, have the other account reply, then leave a review. This is possible but significantly harder than just clicking a star rating.
Additional anti-manipulation rules:
- New account: cannot leave reviews until account is 7 days old
- Rate limiting: max 3 reviews posted per user per day
- Review flagging: any user can flag a review as suspicious
→ Flagged reviews go into a moderation queue
→ 3+ flags → review hidden pending manual review
- Score displayed only after ≥ 3 reviews (prevents gaming with 1 fake 5-star)Step 4: Discovery — Geo-Based Job Search
Users search for jobs or workers near them. This is a spatial query.
Job post contains:
location_lat DECIMAL
location_lng DECIMAL
location_display TEXT ("Grünerløkka, Oslo") ← shown to users
location_hidden BOOLEAN ← user can hide exact address
Worker profile contains:
location_lat DECIMAL
location_lng DECIMAL
max_distance_km INT (how far they'll travel)PostGIS for spatial queries:
-- Find jobs within 5km of user at (59.91, 10.75)
SELECT *
FROM job_posts
WHERE status = 'open'
AND ST_DWithin(
location::geography,
ST_MakePoint(10.75, 59.91)::geography,
5000 -- metres
)
ORDER BY ST_Distance(
location::geography,
ST_MakePoint(10.75, 59.91)::geography
)
LIMIT 20;At 100,000 users with moderate activity, this is well within PostgreSQL + PostGIS capabilities. A spatial index (CREATE INDEX ON job_posts USING GIST(location)) makes these queries fast — no need for Redis geospatial at this scale.
Search filters:
Category: babysitting | cooking | pet care | cleaning | painting | other
Distance: 1km | 5km | 10km | 20km
When: flexible | specific date
Pay range: "around 150 NOK/hr" (free text — not enforced)
Language: Norwegian | English | Arabic | Polish | otherStep 5: Messaging — Simple and Lightweight
In-app messaging is not a nice-to-have — it's the core safety feature. If users message on WhatsApp or Facebook, the platform loses its only window into the conversation needed for review eligibility.
The messaging design:
Two-party only (no group chats at launch)
Persistent history (users scroll back, no TTL)
No typing indicators, no read receipts (reduces server complexity significantly)
Push notification on new message
CONVERSATIONS table:
id UUID PRIMARY KEY
job_post_id UUID (nullable — can start from a profile too)
participant_a UUID
participant_b UUID
created_at TIMESTAMPTZ
last_message_at TIMESTAMPTZ
UNIQUE (participant_a, participant_b, job_post_id) ← one thread per job per pair
MESSAGES table:
id UUID PRIMARY KEY
conversation_id UUID REFERENCES conversations(id)
sender_id UUID
body TEXT
sent_at TIMESTAMPTZMessage delivery:
Sender sends message → POST /api/messages
→ Write to PostgreSQL (durable)
→ Publish to Redis Pub/Sub: channel msg:{recipient_id}
→ If recipient has active WebSocket → push immediately
→ If recipient offline → FCM/APNs push notification
Recipient opens app → GET /api/conversations/{id}/messages?since={last_seen}
→ Fetch all new messages (polling fallback for poor connections)Why polling fallback? Low-end Android phones on poor mobile data drop WebSocket connections constantly. A simple REST poll every 30 seconds ensures messages arrive even on 2G.
Step 6: Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Mobile App (iOS / Android) Web App (browser) │
│ Low-bandwidth optimised Progressive Web App (PWA) │
└────────────────────┬───────────────────────┬────────────────────┘
│ │
┌───────────▼────────────────────────▼──────┐
│ API Gateway │
│ (rate limiting, auth, language headers) │
└───┬───────────┬───────────────┬────────────┘
│ │ │
┌─────────▼──┐ ┌─────▼──────┐ ┌────▼───────────┐
│ Job/ │ │ Message │ │ Review │
│ Profile │ │ Service │ │ Service │
│ Service │ │ │ │ │
└─────────┬──┘ └─────┬──────┘ └────┬───────────┘
│ │ │
┌─────────▼───────────▼───────────────▼───────────┐
│ PostgreSQL + PostGIS │
│ job_posts · profiles · conversations │
│ messages · reviews · users │
└─────────────────────────────────────────────────┘
│
┌─────────▼──────────────────────────────────────┐
│ Redis FCM / APNs │
│ Pub/Sub (live msgs) Push notifications │
└────────────────────────────────────────────────┘Why PostgreSQL for everything and not microservices?
At 100,000 users, this is a small platform. The complexity budget should go into product features (trust, safety, multi-language) not infrastructure. One PostgreSQL database with PostGIS handles all data. One Redis instance handles messaging pub/sub. The entire backend runs on two small cloud VMs — total cost under €100/month, which matters for a free platform.
Step 7: Trust & Safety — Without Payment Data
Without payment verification, the platform must rely on other signals to catch bad actors:
Account reputation signals (computed, not user-facing):
trust_score (internal, not shown to users):
+ days since account created (older = more trusted)
+ number of confirmed conversations
+ number of reviews received
+ average review rating
- number of reports received
- number of reviews flagged as fake
Accounts with trust_score < threshold:
→ Cannot initiate more than 3 conversations/day
→ Reviews from them weighted lower in recipient's average
→ Shown less prominently in search resultsReport system:
Any user can report another for:
- Inappropriate messages
- No-show (arranged job, didn't appear)
- Harassment
Report → logged → if 3+ reports from different accounts within 30 days:
→ Account flagged → manual review by moderator
→ Temporary messaging block while under reviewSafe messaging:
Automatic content scanning on messages:
- Phone numbers in first 2 messages → warning shown ("Stay safe, keep conversations in-app")
- Personal address sharing in first message → flagged for review
- Hate speech / explicit content → auto-blocked + reported
Note: this is moderation assistance, not surveillance.
Messages are scanned by an automated system, not read by staff.
Privacy policy is transparent about this.Step 8: Multi-Language — First Class, Not an Afterthought
The platform serves refugees and immigrants. Language is a core feature, not a translation layer.
User profile: preferred_language (ENUM: no, en, ar, so, pl, other)
App UI: fully translated into all 5 languages at launch
Job posts: posted in user's language
→ Google Translate API: auto-translate button per job post (optional)
Search: language filter ("show jobs where poster speaks Arabic")
→ Lets a worker who speaks Arabic + Norwegian find Arabic-speaking households
→ Critical for domestic jobs (cooking, childcare) where communication matters
Push notifications: sent in user's preferred language
→ Notification templates translated, no runtime translation neededStep 9: The Sustainability Problem
The platform is free. This is a constraint, not a bug. But it has to run on something.
Revenue options that preserve the free-for-users promise:
Option A: Open source + community hosting
Platform code is public. Communities (municipalities, NGOs) can self-host.
Cost borne by the hosting community, not users.
Option B: Optional "boost" for job posts
Free: post a job, appears in search normally
Paid boost (50 NOK): post appears at top of search in your area for 48h
Workers and searchers still free — only job posters pay for visibility.
Doesn't touch the core promise of "free to use".
Option C: Grant / municipal funding
Norwegian municipalities actively fund integration tools for refugees.
NAV (Norwegian Labour and Welfare Administration) could sponsor.For the interview: Option B is the cleanest answer — it creates a sustainable business without charging the most price-sensitive users (refugees, students).
What the Interviewer Is Actually Testing
- Do you understand that no payment processing dramatically simplifies the architecture — and do you lean into that rather than adding unnecessary complexity?
- Can you design a review system that's hard to fake without payment-verified transactions — using conversation-gating, rate limits, and age requirements?
- Do you choose PostgreSQL + PostGIS for geo-search at this scale rather than over-engineering with Redis geospatial?
- Do you design messaging with a polling fallback for low-end devices on unreliable connections?
- Do you treat multi-language as a core feature, not a feature flag?
- Do you address the sustainability paradox — free platform with real operating costs?
- Do you scope the product correctly — no payment processing, no identity verification, no dispute resolution — and explain why those exclusions are correct for this user base?
Related Case Studies
Go Deeper
Case studies teach the "what". Our courses teach the "how" — the patterns behind these decisions, built up from first principles.
Explore Courses