Custom Field Service Software With Route Optimization: What It Really Costs to Build
Adding route optimization to field service software is a solved problem right up until the moment a technician calls in sick at 7:40am. Across 2,000+ projects, Digital Heroes sees a focused route optimization build inside an existing FSM product land at $15,000 to $60,000; a first release with scheduling, a mobile app and dispatch board at $50,000 to $130,000 in 10 to 16 weeks; and a full multi-tenant platform at $150,000 to $350,000 over 6 to 12 months. The optimizer itself is maybe 20 percent of that. Offline sync, time window modeling and the dispatcher override loop are the other 80 percent.
What route optimization actually is once real technicians touch it
Every vendor demo shows the same thing: 30 pins on a map, a button labeled Optimize, and a tidy polyline that saves 14 percent of drive time. That demo is a Traveling Salesman Problem. Your business is not a TSP. Your business is a Vehicle Routing Problem with Time Windows, skills matching, capacity constraints, pickups, and a human dispatcher who will override the machine.
Watch the naive version die. It is 7:40am. Routes were solved and pushed at 5am. Tech #4 calls in sick. He had 7 jobs, including an 11am to 1pm window on a commercial account with a liquidated damages clause in their SLA. The dispatcher hits Re-optimize. The solver, which is stateless and does not know what already happened, returns a globally optimal plan that reassigns 23 of 41 jobs across the whole fleet. Tech #2 is standing in a customer's kitchen with a part in his hand for a job that just got moved to Tech #6, who is 40 minutes away and does not carry that part. Three customers get automated "your tech is on the way" SMS messages naming a different person than the one already at their door.
The optimizer was correct. The system was wrong. What a competent build does is model route state as frozen segments: any job that is EN_ROUTE or IN_PROGRESS, plus anything within a lock horizon (we default to the next 90 minutes), is pinned as a hard constraint. The re-solve only shuffles the unlocked tail. This one decision, freeze semantics, is the single biggest determinant of whether dispatchers trust the software or quietly go back to the whiteboard. Nobody quotes for it.
The solver: you are not writing this, and choosing wrong costs you 6 weeks
Do not write a VRP solver. This is metaheuristics research, not application code, and the people who do it well do it as a career. The real choice is between a self-hosted library and a routing API.
Google OR-Tools is free, Apache 2.0, and its CP-SAT and routing library handle VRPTW, skills via allowed-vehicle constraints, capacity dimensions, and pickup-delivery pairs. It is a C++ core with Python and Java wrappers. The catch: OR-Tools does not know about roads. It wants a distance matrix. For 40 stops that is a 1,600 cell matrix, and if you fetch it live from the Google Distance Matrix API you are billed per element, so every re-solve buys the whole grid again. Ten dispatchers re-solving all day will produce a map bill nobody budgeted and a very awkward conversation. The fix is a self-hosted OSRM or Valhalla instance on OpenStreetMap data for the matrix, and paid APIs only for the turn-by-turn leg the tech actually sees. That swap alone has taken clients from a runaway line item to a rounding error.
The alternative is a managed optimizer. Timefold (the maintained fork lineage of OptaPlanner) is strong if you are on the JVM and need to express weird constraints in a real DSL. Routific, Nextbillion.ai and Mapbox Optimization v2 all expose an HTTP endpoint that takes jobs and vehicles and returns routes. Mapbox Optimization v2 is asynchronous by design: you POST a problem, get a job id, and poll. Build for that from day one, because every serious optimizer is async. A 60 stop, 8 vehicle problem with tight windows takes 5 to 30 seconds of solve time. If your API route waits synchronously on it, you will hit gateway timeouts on AWS Application Load Balancer at 60 seconds and Vercel serverless limits well before that. The correct shape is: enqueue the solve, return a solve id, stream the result over WebSocket or poll, and render an optimistic board.
The other thing nobody tells you: VRP solvers do not have a "correct" answer, they have a time budget. You tell OR-Tools to search for 15 seconds and it gives you the best it found. Same input, same seed, different machine load, slightly different output. That means your test suite cannot assert on exact route order. It must assert on constraint satisfaction and a cost ceiling.
Offline sync, which is where the actual money goes
Technicians work in basements, crawlspaces, elevator shafts, and rural service areas with one bar of LTE. The mobile app must be fully functional offline: read the job, capture photos, collect a signature, add line items, mark complete. Then it reconnects and the fun starts.
Last write wins is what a cheap vendor ships, and it silently destroys data. Tech marks a job complete offline at 2:15pm with 3 parts used. Dispatcher edits the same job at 2:40pm to add a note. Tech's phone syncs at 3:10pm. Under last write wins by client timestamp, the dispatcher note vanishes; under last write wins by server receipt time, the tech's parts list vanishes. Neither is acceptable, and both are invisible until someone audits an invoice.
What a competent build does: field-level merge, not record-level. Job status is a state machine where transitions are monotonic (ASSIGNED cannot overwrite COMPLETED), line items are an append-only log keyed by client-generated UUID so replays are idempotent, and free-text fields that genuinely conflict get surfaced to a human rather than resolved silently. Every mutation the phone makes goes into a local outbox with a client-generated id, and the server dedupes on that id. This is the same idempotency key discipline Stripe uses on payments, applied to job mutations. Without it, a flaky tunnel that retries a request means two invoices.
Practically: on React Native, WatermelonDB or a SQLite-backed store with an explicit outbox table. Photos are the sneaky part. A tech shoots 25 photos at a roof inspection, at 4MB each that is 100MB queued. You resize to 1600px on device, upload via presigned S3 URLs with multipart resume, and never route binaries through your API. iOS will suspend your background upload if you are naive about it; you want URLSession background transfer semantics, which means Expo's plain fetch is not enough and you will be writing a native module or using expo-background-task with real care. Budget 3 to 4 weeks for sync alone. Everyone budgets three days.
Time windows, drive time, and the promises you are making customers
"Arrive between 1pm and 3pm" is a contract. Getting it right requires modeling things the demo ignores.
Service duration is not a constant. A water heater swap is 90 minutes for your best tech and 150 for a new hire. If you feed the solver an average, you overbook the fast techs and starve the slow ones. Real builds carry per-job-type duration with a per-tech multiplier derived from historical actuals, and even a naive rolling median of the last 20 completions beats a static estimate substantially.
Traffic is time dependent. A 20 minute hop at 10am is 45 minutes at 4:30pm. OR-Tools supports time-dependent transit callbacks but you have to bucket the day and feed it a matrix per bucket, which multiplies your matrix cost. Most builds compromise: three buckets (AM peak, midday, PM peak) is the sweet spot between accuracy and compute.
Then the constraints that make it a real VRP: skills (only 2 of 9 techs hold an EPA 608 Type II cert for that refrigerant job), licensing by region, capacity (the truck holds 4 water heaters), lunch breaks as a soft constraint with a penalty rather than a hard window, overtime as a cost not a wall, and technician home start and end depots since most techs take the truck home. Add sequence dependence, where a 2-person job needs two vehicles at the same node in the same window, and you have crossed into constraint programming territory that a route API cannot express. That is usually the moment you commit to OR-Tools or Timefold and the estimate moves up a tier.
Push, tracking and the 3am page
Route changes are worthless if the tech's phone does not learn about them. APNs and FCM are best effort, not guaranteed delivery. Apple's APNs will collapse notifications sharing an apns-collapse-id, which you want for "route updated" so a tech waking up from a dead zone gets one badge, not eleven. Both platforms churn tokens: reinstall, restore from backup, and Android's periodic token rotation all invalidate the old token. If you do not process the FCM unregistered response and APNs 410 Gone by deleting the token row, your notification success metric quietly rots over 18 months and nobody notices until a tech misses a same-day emergency dispatch. The rule: push is a hint to wake up and sync, never a payload of record. The phone always re-fetches truth.
Live GPS tracking is the other trap. Continuous location on iOS requires the Always authorization, which triggers a periodic system prompt asking the user to reconsider, and App Store review will reject you if your purpose string is vague. Android's foreground service requires a persistent notification and, since Android 14, a declared foregroundServiceType of location with a Play Console declaration. Then there is battery: naive 5 second GPS polling drains a phone by 2pm. Use significant-change and geofence-based updates, with high frequency only while EN_ROUTE. And the 3am page is real: your ETA recalculation job that fires on every location ping will, at 300 techs times one ping per 10 seconds, generate 2.6 million writes a day into whatever table your ETAs live in, and your Postgres autovacuum will fall behind. Location history belongs in a time-series or partitioned table with a retention policy, not in your jobs table.
What this costs, honestly
These are Digital Heroes delivery bands from 2,000+ projects, not market averages.
Route optimization added to an existing field service product: $15,000 to $60,000. The low end is a real thing: you already have jobs, techs and a dispatch board, you accept a hosted optimizer, you have 15 or fewer vehicles, single depot, soft time windows, and no offline requirement. That is 3 to 5 weeks. The top of the band is skills matching, multi-depot, time-dependent traffic and a drag-to-override dispatch board.
As part of a first release: $50,000 to $130,000 over 10 to 16 weeks. This buys the scheduler, the dispatch board, a technician mobile app with offline sync, customer ETA notifications, and the optimizer.
Full platform: $150,000 to $350,000 over 6 to 12 months. Multi-tenant, integrations, reporting, role permissions, and the operational hardening that survives 500 concurrent techs.
What specifically pushes this capability's number up, in rough order of damage:
Offline mobile is an architecture decision, not a feature, and it can add $20,000 to $35,000 on its own. If your techs genuinely always have signal, say so out loud and save the money.
Constraint count. Each hard constraint (certifications, two-person jobs, parts-on-truck inventory, union break rules) is a modeling exercise plus a test suite plus a "why did it not schedule this job" explainability surface. Dispatchers demand to know why the solver refused, and building that infeasibility explanation is a genuine chunk of work most quotes omit entirely.
Fleet size crossing roughly 50 vehicles and 300 daily jobs. Below that, almost anything works. Above it, you need clustering into territories before the solve, incremental re-solves, and a solve time budget, because a single monolithic solve stops converging.
Existing ERP (Enterprise Resource Planning) or accounting integration. If jobs originate in ServiceTitan, NetSuite or Sage and must flow back, the sync contract is often larger than the optimizer.
When you should not build this
Take a clear position: if you are a single-trade contractor with fewer than 40 technicians and your workflow is dispatch, do work, invoice, do not build this. Buy ServiceTitan, Jobber, Housecall Pro or Skedulo. Their routing is decent, their mobile apps have survived a decade of basements, and you will pay per-tech per-month for something you could not match for $200,000. The correct answer for that buyer is a subscription and maybe $10,000 of integration work.
Build custom when one of three things is true. One: your constraints are genuinely not expressible in an off-the-shelf product, for example medical oxygen delivery with pharmacy chain-of-custody, or utility crews where a job cannot start until an inspector signs off on a different job. Two: routing is your product, meaning you are selling FSM software to a vertical rather than using it. Three: you are at a scale where per-seat pricing has crossed your build cost, which for most is somewhere past 150 to 200 seats, and the vendor cannot model something that costs you real margin.
The middle path that most people miss: keep your system of record, and use a routing API as a service inside it. That is the $15,000 to $60,000 band, and it is the right answer far more often than either extreme.
How to brief and vet a developer for this
Brief with numbers, not adjectives. Vehicles, daily job volume, depot count, time window tightness, list of hard constraints, whether techs start from home, whether offline is real, and what the system of record is. Half the estimate variance in this capability comes from those eight facts being absent.
"A tech calls in sick at 7:40am with 7 jobs. Walk me through the re-optimize." If they do not immediately talk about locking in-progress and near-horizon jobs, they have never run this in production.
"Where does your distance matrix come from and what does it cost per re-solve?" Someone who has not thought about OSRM or Valhalla versus paid matrix APIs will hand you a surprise bill.
"A tech completes a job offline at 2:15 and dispatch edits the same job at 2:40. What happens?" If the answer is "last write wins" or "we use timestamps", walk. You want to hear field-level merge, monotonic status, append-only line items, and idempotency keys.
"How do you tell a dispatcher why a job could not be scheduled?" Explainability of infeasibility is the tell. It is hard, it is always needed, and only people who have shipped know it exists.
"What happens to a push token when a tech restores their phone from backup?" You want APNs 410 and FCM unregistered handling, and push as a wake-up hint rather than a payload.
"How do you test the optimizer?" If they say snapshot tests on route order, they have not run a real solver. Correct: property tests on constraint satisfaction plus a cost ceiling, since solvers are non-deterministic under a time budget.
"What is your solve time budget and what happens when it is exceeded?" You want a specific number and a fallback plan, usually the previous feasible solution.
Ask for the dispatch board first, not the map. The map is the easy part. The board, with drag to override, conflict warnings, undo, and a clear line between what the solver decided and what a human decided, is where dispatchers either adopt this or ignore it.
The evidence behind this guide
Independent findings on why this investment pays off. Every link goes to the primary source.
- Comparesoft reports the field-service industry-average first-time fix rate is about 80%, best-in-class providers reach roughly 90%, scores below 70% put the business at risk, and providers exceeding 70% FTFR saw customer retention around 86%. Source: Comparesoft (2024) →
- Grand View Research valued the global field service management market at USD 4.43 billion in 2022 and projects it to reach USD 11.78 billion by 2030, a 13.3% CAGR, driven by growing field operations in telecom, utilities, construction and energy. Source: Grand View Research (2023) →
- Only about 30% of digital transformations succeed at meeting their objectives, but getting six critical success factors in place (leadership commitment, talent, agile culture, progress monitoring, clear strategy, and a modernized platform) raises the odds of success from 30% to 80%. Source: Boston Consulting Group (BCG) (2020) →
- The 2024 DORA report found AI adoption significantly increases individual productivity, flow, and job satisfaction, but negatively impacts software delivery throughput and stability - a paradox leaders must manage with fundamentals like smaller batch sizes and robust testing. Source: DORA / Google Cloud (2024) →
Rohan advises mid-market and enterprise teams on ERP, CRM and custom software, and has led delivery on dozens of business-software builds.
Writes for Digital Heroes, shipping business software for 2,000+ brands across 55+ countries since 2017.