HelpRush is launching in India first. See where we're live →

Engineering · Srinagar

Local services is a
distributed systems problem.

It is usually mistaken for a labour problem, which is why it is usually solved with a call centre. Underneath the plumbers and the invoices sits a scheduler, a concurrency problem, an identity system, and a reputation ledger. This is how ours work.

Written by the team that operates it · Last revised 15 August 2026

The constraint

We built this in a city that loses its network on a normal Tuesday.

Most Indian marketplace software is designed in Bangalore and tested on Bangalore's internet. It assumes a request that begins will end. Srinagar does not grant that assumption. Sessions drop mid-transaction, uploads die at eighty percent, and a professional standing in a stairwell has one bar and a customer waiting.

That constraint is the reason for several decisions that look eccentric elsewhere: identity extracted on the handset rather than uploaded, dispatch offers that expire on their own rather than waiting to be cancelled, and state transitions written once and never inferred. Software that survives here is not regionally-adapted. It is simply less fragile.

Seven systems

What actually runs.

01 · Dispatch

RushHour

Parallel offer, tiered escalation

Median match, NOW lane
3.8 s
NOW radius ladder
5 → 10 → 15 → 20 km
Workers
Offer expiry 30 s · escalation 60 s
Exhausted ladder
Ops queue, never silent expiry
Patent
IN 202511047332 (filed)

The obvious way to assign a job is to ask one professional, wait, and ask the next if they decline. It is also the worst way. Every decline costs the full timeout, and the customer pays for a queue they cannot see. Chain five of those together and a burst pipe waits four minutes for someone to look at a phone.

RushHour offers the job to every eligible professional inside the current radius at once and lets them race. First valid acceptance wins; the rest are told immediately that it is over, because a professional who taps and sees nothing happen learns, correctly, to stop tapping.

If nobody accepts, the radius escalates rather than the wait extending. On the NOW lane the ladder runs 5 km → 10 km → 15 km → 20 km, and it stops there on purpose: at Srinagar's measured urban average of 25 km/h, 20 km is already a forty-minute arrival. A ladder that keeps widening is just a slower way to fail.

Two workers drive this — an offer-expiry pass every 30 seconds and an escalation pass every 60. They can race on a tier transition. We dedupe the outcome rather than serialising the workers, because at our volume the occasional jitter costs less than the coordination would. That is a deliberate trade, not an oversight.

When the outer tier is exhausted the job does not quietly expire. It writes an ops-takeover event and lands in a queue a human is looking at. Silent failure is the one outcome the design refuses.

02 · Promises

The thirty-minute contract

A promise that breaks quietly is worse than no promise

Trigger
Projected ETA > 30 min
Model
distance ÷ 25 km/h urban average
Customer window
120 s · timeout = decline
On decline
Re-dispatch, same tier, partner excluded
Scope
NOW lane only

HelpRush tells NOW-lane customers that help arrives within thirty minutes. The failure mode nobody designs for is the one where the system keeps that promise on paper and breaks it in the street: a professional twenty kilometres away accepts, everything reports success, and the customer waits fifty minutes wondering what happened.

So acceptance is not the end of the transaction. On accept, the engine projects arrival from the actual offer distance against a measured urban speed — 25 km/h in Srinagar, a number from the city rather than from a spreadsheet. If the projection clears thirty minutes, the job proceeds exactly as before.

If it does not, the customer is asked instead of told. The assignment parks pending confirmation, no job is created yet, and a push goes out naming the real number: this professional is thirty-five minutes away, yes or no. Two minutes to answer, and silence counts as no.

Decline returns the offer to the pool and re-dispatches at the same tier with that professional excluded. The customer trades a slower yes for an honest one, and the thirty-minute promise stays a promise rather than becoming marketing.

The threshold is projected arrival, not tier number. A distant professional on an empty road and a close one in traffic are the same problem, and only one of those is visible from a radius.

03 · Scheduling

Three lanes

One marketplace, three different physics

NOW
5 → 20 km · latency-optimal
SCHEDULED
10 → 50 km · slot-reserved
Projects
25 → 100 km · milestone escrow, 10% flat
Shared
One job ledger, three lifecycles

Treating every job as the same object is the mistake that makes home-services software feel broken. A burst pipe, a Saturday deep-clean, and a two-week bathroom renovation share a noun and almost nothing else.

NOW optimises for latency. SCHEDULED optimises for certainty — the work is a calendar reservation, so the hard parts are capacity, overlap, and a slot promised on Tuesday still being true on Saturday. Projects optimise for agreement, and abandon dispatch altogether.

The clearest expression of the difference is the radius each one searches. NOW tops out at 20 km because a clock is running. SCHEDULED runs 10 → 25 → 50 km because the professional is planning a day, not abandoning one. Projects run 25 → 50 → 100 km, because multi-day on-site work justifies a single long journey and specialist supply in Kashmir is genuinely sparse.

Projects become a state machine with money in it: milestones proposed, agreed, funded into escrow, delivered, released. The interesting failures there are not routing failures, they are disagreements — which is why the design question stops being who goes and becomes what happens when two people remember the agreement differently.

04 · Identity

Verification at the edge

Read the document on the phone that is holding it

Documents
Aadhaar · PAN
Extraction
On-device OCR (Google ML Kit)
Liveness
On-device face detection, locked after pass
Storage
Encrypted, retained for audit
Third-party sign-in
None in the live path

Most Indian platforms verify identity by uploading images and processing them centrally. HelpRush reads the document on the professional's own device. Google ML Kit performs text recognition locally, and the extracted fields are matched against what the applicant already typed on the web form — a mismatch is rejected on the spot rather than queued for a reviewer who will never meet the person.

To be precise about what that does and does not mean: the extraction happens on the handset, not the recognition of a document we have warehoused. Documents are retained, encrypted, for audit. The claim is that matching is immediate and local, not that nothing is ever stored — that would be a nice sentence and a false one.

The selfie step uses on-device face detection to establish a live human is present, which defeats the two attacks that actually occur in the field: a printed photograph, and a still held up on a second phone. The selfie is locked after verification, and any later change surfaces as a risk signal rather than a silent edit.

There is a bandwidth argument too, and in the Kashmir Valley it is not academic. Uploading identity documents over a connection that drops mid-request produces half-verified accounts and support tickets. Extracting a few hundred bytes of text on the handset produces neither.

05 · Sybil resistance

The Identity Graph

Making a second account expensive

Anchors
Phone · device · Aadhaar hash · PAN hash
Detects
Duplicate documents · linked accounts
Action
Risk signal, not automatic ban
Comparison
Hash-based

Every verification system has the same weakness: a person who fails it can try again as somebody else. Unless being somebody else costs something, the whole apparatus is theatre.

HelpRush anchors each professional to a set of identifiers — phone, device fingerprint, and hashes of the Aadhaar and PAN presented. Anchors are shared across accounts, so re-using any of them under a new identity links the two rather than creating a clean one.

The graph fires on two conditions that matter: the same document appearing on more than one account, and two accounts resolving to a person who should not be two people. Both feed the Risk Engine rather than triggering an automatic ban, because families share phones and the honest explanation is common enough to deserve a human.

Hashes, not images, are what the graph compares. The system can prove two accounts presented the same document without holding a readable copy of it in the comparison path.

06 · Competence

Skill Verification Engine

Knowing who someone is says nothing about whether they can do the work

States
DECLARED → QUIZ_PASSED → PROBATION → VERIFIED → EXPERT
Scope
Per category, never global
Attempts
Professional 3 · Hybrid 5 · Practical unlimited
Cooldown
24 h after a failure
Patent
IN 202511047441 (filed)

KYC answers identity. It is silent on competence, and conflating the two is how marketplaces end up with verified strangers who cannot wire a socket.

Skill is a five-stage progression held separately for every category a professional claims — DECLARED, QUIZ_PASSED, PROBATION, VERIFIED, EXPERT. Nobody is trusted across trades because they cleared one.

Assessments run in English, Hindi and Urdu, because testing a Srinagar carpenter's craft through a language barrier measures the barrier. Attempt limits follow the nature of the trade: three where the knowledge is genuinely professional, five on hybrid paths, and unlimited where the skill is practical and repetition is how anyone actually learns it. A failure carries a twenty-four-hour cooldown, which exists to stop brute force rather than to punish.

Probation does the real work. The first five jobs in a category are supervised and feed a live feedback ledger. Clear it and the engine promotes; accumulate negative signal inside the window and a human reviews before the professional continues.

07 · Reputation

Trust Engine · Risk Engine

A score that moves, and a watcher that acts

Trust Score
0–100 composite, live
Weights
Verify 20 · KYC 15 · Skills 25 · Risk⁻¹ 15 · Jobs 15 · Rating 10
Rating floor
10 reviews for full weight
Risk states
OK → WATCH → FROZEN → BANNED
Breach action
Automatic freeze, human review

A star rating is lagging, gameable and mostly decorative. The Trust Score is a 0–100 composite recomputed whenever something real happens — a completed job, a KYC event, a risk signal — and we publish the weights rather than describing them, because a score whose formula is a secret is just a vibe.

Verification level carries 20, KYC status 15, skill-verification breadth 25, inverse risk 15, completed jobs 15, and customer rating 10. Rating is deliberately the smallest term, and it reaches full weight only past a ten-review floor — the cheapest available defence against a professional with three glowing reviews from three friends.

The Risk Engine runs alongside it across ten signal types: personally identifying information leaking into chat or calls, customer reports, payment anomalies, repeated geographic revisits, device-fingerprint changes, OTP abuse, duplicate documents across accounts, identity links between accounts, and an unlocked avatar after verification. Accounts move OK → WATCH → FROZEN → BANNED, and crossing the threshold freezes automatically, pending a human case review.

The Trust Score is public on every professional's page and it drives dispatch priority and tier eligibility. That is the point: it is not a badge, it is an economic instrument, and the professionals who carry it can see exactly what moves it.

Precision

What we don't claim.

Engineering pages are usually where companies quietly inflate. Ours is a better document if the boundaries are drawn by us rather than by someone trying to catch us out.

  • On dispatch

    Offering a job to many providers at once is not new. Ride hailing and delivery have done it for years, and we are not claiming to have invented it. What is unusual is bringing it to home services, where the prevailing pattern is still a lead forwarded to several businesses who then take turns calling you — and pairing it with a bounded escalation ladder and an ETA contract, which is what the filing actually covers.

  • On known trade-offs

    The offer-expiry and escalation workers can race on a tier transition. We deduplicate the outcome instead of serialising the workers, which leaves a little jitter in escalation timing. At our volume that is cheaper than the coordination. We would rather write it here than have you find it.

  • On patents

    IN 202511047332 and IN 202511047441 are filed, not granted. Indian applications publish and then wait years for examination. Anyone writing about us should say “patent filed” or “patent pending”. We will say the same until an examiner says otherwise.

  • On scale

    One city. Srinagar. The architecture is built to run in many and has not yet been asked to. Our operating numbers are small, real, and published with their caveats on /company/facts. We would rather be checked than believed.

Stack

Boring where it can be.

Novelty is spent on dispatch, identity and trust. Everywhere else we picked the option with the largest number of people who have already hit the bug we are about to hit.

Web
Next.js (App Router), TypeScript, Tailwind
API
NestJS, PostgreSQL, Prisma
Realtime
Server-sent events for dispatch and tracking
Mobile
Two Flutter apps — customer and partner
On-device ML
Google ML Kit — text recognition, face detection
Payments
Razorpay for collection, Cashfree for payouts
Infra
Docker Compose on DigitalOcean, Cloudflare at the edge