Where Denver's 311 Slows Down: Seven Years of Service Requests, Read Like an Operations Manager
Denver publishes every 311 contact as open data. The obvious dashboard (volume by year, average days to close) answers nothing an operations lead can act on. I spent five years owning scheduling and crew dispatch for a commercial field-service division, so I read this data the way I read a schedule board: where does the work come from, how fast does it close, and what would I change on Monday?
The short version: the biggest slowdowns in Denver's 311 data are record-keeping gaps, not service. Where the records are complete, the real stories are specific, measurable, and fixable.
Metric | Value |
Contacts, 2019-2025 | 3,010,330 |
Field requests (tied to a Denver place) | 816,266 (27%) |
Like-for-like field requests, 2019 to 2025 | +5.1% |
Type-years that fail a record-integrity test | 13 of 175 |
Request types that close slower via the app | 14 of 14 |
Phone contacts a published answer could handle | 15% |
The question
Demand: how did volume and mix shift from 2019 to 2025, once you compare like with like? What is the seasonal shape of each kind of work?
Speed: for the top 25 field request types, what are the median (P50) and 90th percentile (P90) times to close, and is the close timestamp even trustworthy?
Channel: does the intake channel (phone, app, email) change how fast a request closes, and which phone questions could be self-service?
Place: after controlling for request type, do some neighborhoods or council districts wait longer?
The data
311 Service Requests, 2019-2025: seven yearly files from the Denver Open Data Catalog, 3.0 million contacts, CC BY 3.0.
Statistical neighborhoods: 78 polygons with ACS 2019-2023 population and income, same catalog.
DOTI Level of Service goals: published on denvergov.org in business days, for the five top request types that have one.
Cleaning
Profiling the raw files turned up more than the usual nulls:
Two publishing formats. 2019-2023 are UTF-8 exports; 2024-2025 are Windows-1252 CSVs with line breaks inside text fields and different headers. Each year is read with its own encoding.
Five documented columns are empty in every year, including Type and Neighborhood. Request type comes from the free-text case summary (48,803 distinct strings), categorized with keyword rules. Neighborhood comes from a point-in-polygon join on coordinates (99.6% matched).
The First Call Resolution flag is Y on 99% of rows, including cases closed weeks later, so it is not used.
21,417 rows store the latitude in the longitude column, 2,015 rows are exact duplicates, and agency and status labels drift across years.
Every step writes to a cleaning log with the rows it touched, and 11 quality checks must pass before any analysis runs.
Method
Field request: a contact tied to a Denver location whose status is answered, resolved, or still open (816,266 rows). Transfers, spam, and duplicates are excluded.
Derived benchmark: each request type's own 2019 P90 time to close. The city does not publish a target for most types, so this benchmark is derived for this analysis, not a city standard. Open cases count as misses.
Published goals: where DOTI publishes a Level of Service goal, requests are also tested against it in business days. The goals are current, so earlier years are a retrospective comparison.
Record gap: a type-year where more than 20% of requests were never closed, or more than 25% of closures landed on one day. Those cells are shown as gaps, not as speed.
Wait index: each closed request's percentile rank within its own type and year, averaged by area. 0.50 is typical. This keeps a neighborhood full of slow request types from looking slow for that reason alone.
Findings
1. Most 311 contacts are questions, not field work

Only 27% of contacts are field requests, and 61% of all contacts close within 15 minutes. Field requests look like they fell 33% from 2019 to 2025, but most of that is solid-waste requests leaving the 311 file (75,873 in 2019, 10 in 2021). On a like-for-like basis, field demand rose 5.1%.


2. The biggest slowdowns are record-keeping gaps

In 2023-2024, 77-92% of weed, sidewalk snow, and trash-in-yard cases never received a close timestamp; they sit at Routed to Agency. Then 83% of the 2025 sidewalk snow closures were stamped on a single day, May 6, 2025. A naive dashboard reads those years as either very fast or very slow. The honest reading is that the 311 record did not receive the agency's outcome, so those cells are excluded from speed claims.

3. Where records are complete, the stories are specific
Business licenses slowed and recovered. New Business License medians went from 1 day (2019) to 8.4 days (2021) and back to 3.9 days (2025).
Potholes are the steadiest service in the file: a median between half a day and 2.5 days every year.
Against DOTI's own goals, potholes meet 5 business days in 78-98% of cases each year. Signal and sign requests held 86-99% through 2023, fell to 61-73% in 2024, and recovered in 2025.

4. App requests close later than phone requests

The PocketGov app's share of field requests rose from 23% (2019) to 48% (2022), then fell back to 26% (2025). In all 14 types with enough volume to compare, app submissions take longer to close. Potholes: a 3-hour median by phone, 50 hours through the app. The data cannot separate the causes, but the gap is consistent.

About 15% of phone contacts are civic questions a published answer could handle: property tax statements, vehicle registration, the trash service schedule (6,297 calls in 2025 alone), mail ballots, courts, and pet adoption.
5. Place explains very little once request mix is controlled

Every council district sits between 0.486 and 0.516 on the wait index, and neighborhood wait does not track income (r = 0.06) or poverty (r = -0.05). Demand does: requests per resident rise with the poverty rate (r = 0.24). This data does not show lower-income areas waiting longer for the same work.
Recommendations
Close the loop before measuring speed. Require agency systems to write outcomes back to 311, and publish a monthly record-integrity check next to any speed metric. Code enforcement in 2023-2024 is the case to fix first.
Triage app submissions like phone calls. Set a same-day triage target for app intake and track the app-minus-phone gap by type. Potholes (47 hours) and signal timing (109 hours) are the clearest tests.
Publish the answers people call for. An address-based trash-day lookup, plus seasonal phone messages timed to property tax statements and elections, target the largest civic question topics.
Staff to the season. Shift inspection capacity toward January-February (sidewalk snow) and summer (weeds, encampments, parks), sized by the seasonal index.
Set goals from the data where none are published. For the 20 top types without a published goal, the 2019 P90 is a defensible starting target.
Watch the wait index, not raw medians, and plan capacity on requests per resident.
Tools
Built 100% native on Apple Silicon:
Python 3.12 and pandas for cleaning, with uv and a Makefile for a reproducible pipeline
DuckDB for analytical SQL, including the spatial extension for the neighborhood join
PostgreSQL 17 for the relational model: typed schema, partial indexes, materialized views, and parity checks against DuckDB
DBeaver as the SQL client for both databases
JupyterLab and matplotlib for four executed notebooks and every figure in this post
Google Sheets for the analyst workbook (aggregates only)
Cursor, Git, and GitHub for code and version control
Reproduce it
Everything runs from one repository: github.com/jasonpellerin-aisolutionist/denver-311-service-analytics. Clone it, run make download, make clean, make load-duckdb, make analyze, and make notebooks, and every number in this post is recomputed from the city's files. The notebooks show the profiling, every cleaning decision, and the findings with their outputs.
Limits: time to close is the life of the 311 record, not proof that work was or was not done. The derived benchmark describes 2019 performance, not a service promise. Neighborhood correlations are descriptive, not causal.
Data: City and County of Denver, Denver Open Data Catalog, CC BY 3.0. This project is independent and not affiliated with the City and County of Denver.




Comments