write a new articles with
For the better part of twenty years, my optimization models lived inside Excel. Staff schedules, vehicle routes, blending problems — real mixed-integer programs, built with SolverStudio, a plugin that embeds Python and the PuLP modeling library directly in a workbook. They planned real operations, week after week. And every single one of them had the same limitation: the model was wherever the workbook was, and nowhere else.
Why Excel, and why it eventually isn’t enough
Excel gets a lot of condescension from software people, and almost all of it misses the point. Excel is where the data already lives. It’s the one tool every planner, dispatcher, and analyst already trusts, and SolverStudio let me put serious optimization behind that familiar grid instead of asking anyone to learn new software. For internal work, it was close to ideal.
The ceiling shows up when a model needs to outlive its workbook. Sharing means emailing attachments. Versioning means filenames with dates in them, and an argument about which one is current. IT departments can deploy an application; they cannot reasonably deploy a macro-enabled workbook with a Python plugin to a hundred machines. A model that runs a weekly operation from one analyst’s laptop isn’t infrastructure — it’s a bus-factor problem wearing a spreadsheet costume.
The architecture decision that made it work
When I started converting the models to web applications, the decision that mattered most wasn’t a technology choice — it was a separation. Each model became a pure Python engine with no web code in it at all: it reads input, builds the mathematical model, calls the solver, returns results. The web application is a deliberately thin wrapper around that engine — one upload endpoint, one solve call, one results page.
Just as important: Excel stayed. The web version of my vehicle routing model takes the same kind of workbook the Excel version used — a sheet of stops, a sheet of vehicles, a sheet of parameters. Users upload it and get results on a map plus a downloadable file. Nobody had to abandon the interface they trusted; the solver just stopped living on one laptop. If you take one idea from this article, take that one: move the computation, keep the spreadsheet.
The mathematics survived the move almost untouched. The routing model had existed as roughly 1,500 lines of C#; it became about 480 lines of Python on Google OR-Tools, and the formulation — capacities, time windows, the constraint logic — transplanted nearly one to one. Twenty years of modeling work was never the thing at risk. The plumbing was.
What actually broke
The honest part of this story is the list of things no tutorial warned me about, because tutorials end at ‘the solver returns Optimal’ and production begins there.
Web infrastructure assumes requests finish in milliseconds. The default configuration of a standard Python web server kills any request that takes longer than thirty seconds — and a real optimization run takes minutes. The first deployed version of my scheduler died mid-solve, every time, until the timeout was raised to five minutes. Trivial fix, but only after you know where to look.
Solvers behave differently once they leave your machine. PuLP can call the CBC solver several ways, and the variant that works everywhere on Linux hosting is not the one an Excel-era model was probably using. The same model, the same data, and a solver that simply isn’t found — that combination cost me an evening.
Metaheuristic callbacks don’t mean what you think. My routing model uses OR-Tools’ guided local search, and I wanted a sensible stop rule: halt after a period with no improvement. It turns out the solution callback fires on every accepted move, not just improving ones — so a stagnation timer reset on every callback never fires. You have to watch the objective value itself. That distinction is documented nowhere I could find, and it matters enormously for user experience.
Straight-line distances produce fantasy routes. A routing plan is only as honest as its travel times, so the web version pulls real drive times from OSRM, the open-source routing engine — which brings its own engineering: caching distance matrices, batching requests, respecting rate limits. And one update ran perfectly in every test environment I had, then hung only in production — the one environment that mattered.
Advice for anyone sitting on a drawer of models
Most veteran OR practitioners I know have their own version of my drawer: years of Excel models that work, that proved their value, and that will retire when their author does. If that’s you, the conversion is more approachable than it looks. Separate the engine from the interface first, and test the engine standalone before writing a line of web code. Keep the input format your users already trust — the spreadsheet is a feature, not a legacy. And resist the urge to improve the mathematics while porting it; transplant first, optimize later. The model earned its logic over years of real use. The web is just a better place for it to live.
Two of my converted models are live and free to use — a vehicle routing optimizer at routing.kindoflost.com and a staff scheduler at staff-scheduling.kindoflost.com. Both run the same mathematics the Excel versions did; they just no longer need me in the room.
About the author

Mario is an operations research analyst (MS Industrial Engineering, CAP certified) who spent 20+ years building optimization models for manufacturing and aviation. He now converts them into free web tools and documents the process, mistakes included, at kindoflost.com.
into a unique and well structured article. Ensure the new content is plagiarism-free, well-organized, and formatted for seamless integration into WordPress. Use appropriate HTML tags (e.g.,
,
,
) and enhance readability with proper formatting
