Public Works Software: Fixing the Work Order and Asset Gaps That Cost Real Money
Build if you run more than roughly 8,000 work orders a year across three or more divisions and your citizen request volume has outgrown what a call log and a Cityworks license can absorb. A focused first release covering intake, dispatch, and the asset register typically runs $60k to $130k and ships in 12 to 16 weeks; a full platform with GIS sync, fleet, inventory, and public portal runs $150k to $400k phased over 6 to 12 months. Below that volume, or if your county already forces you onto Cartegraph, stay bought and spend the money on data cleanup instead.
Why work order and asset software makes or breaks a public works department
Your department owns 340 miles of road, 12,000 storm inlets, 6,800 signs, 41 lift stations, and a fleet of 90 units. The city's records for all of that live in four places: an Esri ArcGIS geodatabase the GIS analyst maintains, a Cityworks or Cartegraph instance the streets superintendent uses, an Excel workbook the sign crew keeps because nobody would give them licenses, and the head of the sewer crew, who has been here 22 years and knows where the tie-ins are that were never mapped.
The leak is not dramatic. It is a foreman spending 40 minutes every morning rekeying yesterday's paper work orders into the system because the field app times out on cellular in the river valley. It is a citizen calling about the same pothole four times because SeeClickFix generated four separate tickets and nobody deduped them. It is $180,000 of concrete work billed against the wrong CIP fund because the crew leader picked the first activity code in an alphabetical dropdown. Across a 60-person department, that is real money and it never shows up on a line item.
Consider the 2:40am water main break. Dispatch pages the on-call crew. The crew excavates, finds a 6-inch cast iron from 1961 that your GIS says is 8-inch ductile from 1988, cuts in a repair clamp, backfills, and goes home. Nobody updates the asset record because the tablet app requires 11 fields and the crew leader is on hour 14. Six months later, engineering designs a replacement project sized for 8-inch ductile. That error was preventable, and the reason it was not prevented is that your software made recording the truth harder than not recording it.
Problem: intake is fragmented and every channel creates a different record
Citizen requests arrive by phone to the clerk, through the city's SeeClickFix or Accela Citizen Access portal, by email to a public.works@ inbox, through a council member forwarding a constituent complaint, and via the 311 line if your city has one. Each channel produces a differently shaped record. The clerk types a free-text description. The portal produces a lat/long and a category from a fixed list. The council forward has a street name and no number.
Off-the-shelf tools do not fix this because they are the destination rather than the funnel. Cityworks will happily accept a service request from its own portal. It has no opinion about the 200 emails a month or the voicemail transcripts. Every vendor's answer is "put everything through our portal," which is a sentence that has never survived contact with a 70-year-old resident who wants to talk to a person.
A custom build makes intake channel-agnostic. Every inbound item, phone, email, portal, SMS, council forward, lands in one queue with a normalized shape: reported location, reporter contact, raw text, channel, timestamp. An LLM extraction step reads the raw text and proposes a category, an asset match, and a priority, and geocodes the location against your own street centerline file rather than a generic Google match that puts "Main St near the school" three towns over. The dispatcher sees a suggestion instead of a blank form, and confirms or corrects in one click. Deduplication runs on the same step: a new report within 50 feet and 14 days of an open request on the same asset class gets attached to the existing work order as an additional complainant rather than spawned as a new ticket. In the departments we have done this for, that single rule cut the open request count by 20 to 35 percent in the first week, and it made response-time metrics honest for the first time.
Problem: the asset register and the GIS drift apart, permanently
Your ArcGIS layers are the system of record for what exists. Your work order system is the system of record for what happened to it. These are supposed to sync. In practice the sync is a nightly job that pushes attributes one direction, and the moment a crew discovers reality differs from the map, there is no path for that discovery to get back into GIS without an email to the GIS analyst who has a backlog of 300 edits.
Cartegraph and Cityworks both integrate with Esri. The integration is real and it is also the source of the problem: it assumes GIS is authoritative and the field is a consumer. The crew that just exposed the pipe knows more than the map does, and the software gives them nowhere to put it.
A custom build makes field discovery a first-class record type. When the crew closes out that 2:40am main break, the close-out form asks three questions rather than eleven: what did you actually find, does it match the record, and a photo. If it does not match, the app writes an asset discrepancy record with the photo, the GPS fix, and the crew leader's note. That record lands in a GIS review queue with a proposed edit already built as a feature-service update. Your analyst approves or rejects in bulk. The loop closes in days instead of never. Over 18 months this is the difference between a geodatabase you trust for capital planning and one engineering quietly re-surveys before every project.
Problem: after-hours and storm events collapse the whole system
Normal operations are fine. Your department's software fails on the 6 days a year that matter: a 4-inch snow event, a derecho, a 100-year rain. Suddenly 400 requests arrive in nine hours, half your staff is on 16-hour rotations, and the mayor wants a map of downed trees for the 6pm press briefing.
This is where off-the-shelf tools break in public, because they were designed around a steady-state work order queue. Dispatchers fall back to a whiteboard and a group text. The event data never enters the system, which means when FEMA reimbursement paperwork comes due, someone reconstructs 400 events from photos and memory. That reconstruction is where you lose money: a category B debris removal claim needs documented labor hours, equipment hours by FEMA equipment code, and location. If you cannot produce it, you eat the cost.
A custom build has an event mode. One toggle changes intake behavior, dispatch layout, and close-out requirements for the duration of a declared event. Requests auto-group by geographic cluster instead of arriving as a flat list. Crews get a route rather than a ticket. Close-out drops to a photo plus a timestamp, because during a storm you capture, you do not classify. Every record silently carries the FEMA fields: equipment code, operator, hours, disposal site. After-hours intake runs through a voice agent that answers on the first ring, takes the address, classifies emergency versus routine against your own escalation rules, pages on-call only for the real ones, and texts everyone else a tracking link. The department that had a clerk answering 60 storm calls at midnight now has a clerk reviewing 60 transcripts at 7am, and a defensible reimbursement package instead of a guess.
Problem: PM schedules exist on paper and nobody runs them
You have a preventive maintenance program for your 41 lift stations, your storm inlets, and your fleet. On paper it is quarterly inspections and an annual cleaning. In the departments we have measured, PM completion lands nearer 55 percent than 100, and the missing 45 percent is not random. It is the stations furthest from the yard. Nobody planned that. It emerged.
Generic CMMS tools generate PM work orders on a calendar. That is the entire feature. They do not know your crew has 14 productive field hours a week after meetings, snow, and reactive work, so they generate 40 hours of PM and the surplus silently rolls over into a backlog you stop looking at.
A custom build schedules PM against real capacity. The system knows each crew's actual completed hours over the trailing 8 weeks, knows the drive time between assets from your own centerline network, and builds a week that fits. It routes: five inlets on the same loop go to the same crew on the same day rather than to three different crews across three weeks. When reactive work eats a day, the PM engine re-plans rather than accumulating a debt. And it forecasts: fed 3 years of your own work history, a model surfaces which assets are generating repeat reactive calls and flags them for capital replacement with the actual cost history attached. That is the report your finance director has been asking for and your current system cannot produce, because it stores cost per work order and not cost per asset over time.
Problem: your data cannot answer a council question
A council member asks how long it takes to fill a pothole in Ward 3 versus Ward 1. This should take four minutes. It takes a week, because your response-time clock starts when a request is entered rather than when it was reported, ward boundaries are not on your work orders, and half of Ward 3's potholes came in as "street defect" and half as "road hazard" depending on which clerk typed them.
Cityworks reporting is real but it reports the data you have. It cannot fix a data model that never captured the ward, the true report time, or a consistent category. Fixing that inside a vendor tool means custom fields and a Crystal Report, which someone builds once and then nobody maintains.
The custom answer is upstream. The data model carries the political and operational geography natively. Every work order stamps ward, council district, pavement management section, sewer basin, and snow route at creation by spatial join, automatically, from your own layers. Every request carries reported_at, entered_at, assigned_at, on_site_at, and closed_at as distinct timestamps, so response time is a real number and you can see whether your problem is dispatch or field capacity. Then the council question is a saved view, and the director walks into the meeting with the answer instead of a promise to follow up.
What this costs and how long it takes
Across 2,000-plus projects, Digital Heroes sees this category land in two bands. A focused first release, unified intake with AI classification and dedupe, the asset register with GIS read/write sync, mobile work orders that function offline, and dispatch, typically runs $60k to $130k and ships in 12 to 16 weeks. A full platform adding fleet and equipment, inventory and parts, the public-facing request portal and status tracking, PM scheduling with routing, FEMA event mode, and finance integration runs $150k to $400k phased over 6 to 12 months.
What drives price up in public works specifically: offline-first mobile is the single biggest multiplier, because a truck in a river valley or a vault has no signal and a sync engine that survives two crews editing the same asset offline is genuinely hard engineering rather than a checkbox. Esri integration cost scales with how clean your geodatabase is; if your layers have no stable asset IDs, budget a data reconciliation phase before anyone writes application code. Financial system integration to Tyler Munis, Springbrook, or Workday is usually a fixed, knowable cost, but only if your finance team will commit to a chart of accounts mapping in writing, and that conversation takes longer than the code. And if you are a utility with SCADA, wiring alarm-to-work-order is a separate project, not a feature.
Build versus buy: the honest line
Stay bought if you are a department under about 25 staff with a single division, or if your county or state has standardized on Cartegraph or Cityworks and you would be fighting procurement and IT for two years to get an exception. Stay bought if your asset data is genuinely bad, because custom software will not clean it, it will just render your bad data faster and more expensively. Fix the data first. Stay bought if your problem is that nobody uses the system you have; a new system does not solve an adoption problem, it resets the clock on it.
Build when three signals show up together. First, you are paying for a tool and still running the real operation in Excel or on a whiteboard, which means the tool never fit and no configuration will make it fit. Second, your annual license plus the consultant you keep on retainer to maintain configurations is over $80k, at which point you are already funding a build and merely renting the result. Third, and this is the one that decides it, your operation has something structurally unusual: a combined utility, a shared services agreement with three neighboring townships, a snow operation that is 40 percent of your winter, an internal fleet shop that bills other departments. Off-the-shelf tools are built for the median department. If you are not the median, every year you spend configuring around that gap is a year you pay for software to make your job harder.
How to choose a developer for public works software
Ask them to model your assets before you sign anything. Give them your inlet layer and ask how they would handle an inlet that belongs to a storm basin, sits in a ward, falls on a snow route, and was replaced in 2019 as part of a CIP project. If they propose a flat asset table with custom fields, they have never built this. The right answer involves hierarchies, effective-dated attributes, and spatial relationships resolved at write time, and they should say so unprompted.
Make them prove the Esri work. Not "we integrate with ArcGIS," which everyone claims. Ask specifically: have you written to a hosted feature service, handled a schema change mid-project, and dealt with a client whose geodatabase had duplicate asset IDs. Ask what they did. The stories are specific or the experience is not real.
Interrogate the offline story before design starts. Ask what happens when two crews edit the same asset offline for six hours and both sync at 4pm. If the answer is "last write wins," walk away. Conflict resolution in field software is a design decision that has to be made early, and a team that has not thought about it will discover it in month five when it is expensive.
Confirm public-sector realities are priced in. Records retention, because your work orders are public records and a records request will land. ADA accessibility on the citizen portal, which is a requirement rather than a nice-to-have. Procurement documentation your purchasing agent can actually process. And source code ownership in the contract, in writing, with a repository handover clause, because the department that owns its code can change vendors and the one that does not is renting forever.
The evidence behind this guide
Independent findings on why this investment pays off. Every link goes to the primary source.
- ServiceTitan's KPI guide cites an average first-time fix rate near 80% (90% ideal) and describes strong technician-utilization rates as falling in the 60-80% band, with average travel time typically 30-60 minutes depending on service-area size. Source: ServiceTitan (2026) →
- IBM frames first-time fix rate as a core field service KPI, noting the industry average sits around 80% (roughly one in five jobs needs a return visit). Correction: IBM cites best-in-class providers at 89-98%, not '85%+'. Source: IBM (2024) →
- Almost half of all the activities people are paid almost $16 trillion in wages to do in the global economy have the potential to be automated by adapting currently demonstrated technologies. Source: McKinsey Global Institute (2017) →
- In PMI's 2014 Pulse of the Profession report on requirements management, inaccurate requirements management is cited as a leading cause of project failure, with 47% of unsuccessful projects failing to meet goals due to poor requirements management. Source: Project Management Institute (PMI) (2014) →
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.