Reverse-requirements specification — what the new planning system does, and the rules it plans to.
Kybotech runs its own vans out of Worksop, delivering garden buildings (sheds, summerhouses, log cabins, playhouses) and small spare parts, and collecting returns — often on the same run. Planning is currently done by hand / existing software. This system replaces that with an optimising planner and adds a load-auditing facility to measure how much good planning saves.
Today Kybotech plans with Paragon (off-the-shelf) plus manual adjustment ("frigging") afterwards. Paragon optimises generically — broadly to miles/time — and the planner then hand-corrects it for what Paragon doesn't model. In practice that means mid-day reloads are barely (if ever) used, and two-day runs take long, cautious detours (effectively the return-to-depot dilemma rather than an efficient overnight).
What this bespoke system actually optimises is utilisation of the driver and the vehicle — because the cost is a fixed day-fee per van-day plus mileage, the expensive thing is a van going out at all, and going out under-used. The alpha:
| Lever | Paragon + manual (today) | This bespoke system | The gain |
|---|---|---|---|
| Objective | minimise miles / time (generic) | minimise true cost = van-days × day-fee + miles | targets the ~77% that is the day-fee → fewer driver-days |
| Mid-day reloads | barely used | modelled — one van does a second load before 4pm | fewer vans out |
| Two-day runs | long, cautious detours | efficient overnight (B&B), distance-capped, by discretion | kills the doubled long drive |
| Rolling week | limited | each order on the cheapest day in its window | spreads work so vans fill |
| Fill rate | incidental | 90–95% utilisation target | full vans by design |
| Hand-editing | required (the "frigging") | constraints built in → usable as-is | planner time saved, fewer errors |
| Auditing | none | verify the self-billed invoice + prove the saving | a facility Paragon doesn't have |
| Facility | What it does | Direction |
|---|---|---|
| Load auditing (backtest) | Re-solves a past period optimally under the same rules a planner worked to, and compares the cost against the self-billed contractor invoice (what was actually run and paid). The gap is the achievable saving — and the same figures verify the invoice itself (see §2.1). | Looks back. One-off / periodic. |
| Live planner | Takes the week's orders, produces optimised per-van run sheets (route, ETAs, load on board), shows them on a map, and lets a planner override (move a drop to another van). | Looks forward. Daily use. |
Both use the same optimisation engine — the auditing facility points it at last month; the planner points it at next week.
Kybotech runs self-billing: it raises the contractor's invoice itself — a fixed day-fee per van-day plus mileage (round trip to depot) — and the contractor pays that self-billed invoice. The formula is fixed, so the self-billed invoice is the audit baseline: measured, formulaic, and exactly what was paid. The auditing facility does two jobs with it:
van-days × day-fee + miles × rate + overnight contributions) to the figures the runs were billed on, and flag any arithmetic or rate error, miscounted van-days, or missing/incorrect overnight payments before payment goes out. (Mileage isn't cross-checked against GPS — there's no stored telematics; the audit works on the billed run figures.)Both reduce to the same formula on the same measured inputs, which is why the audit is clean: one number you paid, one number you could have paid, computed identically.
One number, minimised across the whole horizon (a week solved as a single problem, not day-by-day):
The levers it pulls to do that:
Every order is one stop. Two quantities matter for loading — volume (loadspace) and weight — because garden buildings are bulky and heavy; a van fills on whichever binds first.
| Type | Loadspace | Weight | Handball | Notes |
|---|---|---|---|---|
| Shed | low–mid | 150–450 kg | ~20–30 min | the bread & butter |
| Summerhouse | mid–high | 400–800 kg | ~25–40 min | |
| Log cabin | high | 850–1400 kg | ~35–55 min | ~1 per van by weight; may split across 2 drops |
| Playhouse | low–mid | 180–380 kg | ~18–28 min | |
| RDM (spare part) | tiny | 5–40 kg | ~8–12 min | takes a slot, ~no space; good defer candidate |
| Collection | varies | varies | ~15–25 min | a return — adds to the load on the way back |
All handball by the driver, one item at a time — no two-man drops.
These are the hard rules the optimiser honours, and the same rules the auditing baseline is held to.
A van carries up to its loadspace (≈100 units) and its payload (1.5 t). A load is full when either binds. Drops and collected returns are tracked as two commodities so a return can't "fund" a delivery — sheds on board + returns on board ≤ capacity at every stop.
A van can return to Worksop to reload (≈45 min) and go out again — so capacity binds per trip, not per day. The depot closes mid-afternoon (≈16:00), so a second load only happens if the van gets back to reload before the cutoff. (Drivers most often reload in the morning.)
A paid van-day is planned to GB domestic driver hours — roughly a 10-hour driving / 11-hour duty day, including handball. Vans are <3.5 t (GB domestic, not EU rules). This is treated as a prudent single-driver day; although the contractor could swap drivers/vehicles mid-run (only driver codes are tracked), we do not over-spec on that.
The contractor is paid a fixed day-fee + mileage for the round trip back to depot. Drivers actually take the van home, but mileage is billed as if it returned to depot, for completeness — so the model costs the depot → drops → depot round trip. Where the driver lives is their own affair.
A reload does NOT make a run two-day. A reload is mid-day — drive back to the depot for a fresh load and out again — and the van is still home that night, so it's a single-day run. Volume and weight are handled by reloads within a day. A run is two-day for exactly one reason: distance — it is so far to the first drop that the van cannot deliver everything and get home inside one legal day, so it stays out overnight.
Distance limits, from Worksop:
How a two-day run works: Day 1 — drive out, deliver to the hours limit, then sleep at a B&B near wherever the day actually ends (dynamic — not a fixed hub). Day 2 — finish the deliveries and drive home. One drive out, one drive home, the overnight in between. Cost = two day-fees + the round-trip mileage + one overnight subsistence (~£40).
"Tramping" is Kybotech's other word for the two-day overnight run in §5.5 — they are one and the same. There is no separate concept.
Some orders are booked appointments (e.g. AM 08:00–12:00). The van must arrive within the window on whichever day the stop lands. Wide windows give the planner room; narrow ones fragment routes.
The planner works from a rolling pool — the week's orders, each of which must be delivered somewhere in the week. Every order carries an earliest and latest date; the optimiser places each on the cheapest day within that window — usually the day a van already passes nearby. This is the single biggest lever, and it is commercial as much as technical: the more orders you can leave flexible, the lower the cost.
Drops and collections share a run. The van leaves loaded with the trip's drops; drops reduce the load, collections add to it; the running total stays within capacity throughout, and collected goods return to depot.
order_id) is kept on the same van, same day.Only two kinds (see §5.5 for the terminology fix):
From the whole order pool, the optimiser assigns each van a geographically tight cluster that fills a load, on the cheapest day within each order's window, to minimise total van-days + miles — subject to every constraint above. A van's orders are therefore not arbitrary: they are near each other and together make an efficient load. The planner can override any assignment by moving a drop to another van (the route re-sequences live).
For the planner: orders come from Kybotech's own system, so the interface is a defined export (CSV/JSON now, live feed later). Minimum per stop: stop_id, type (drop/collect), location (lat-lon or postcode), volume, earliest_date, latest_date. Recommended: weight, service_min, tw_start/tw_end, product, order_id (for cabin grouping). Fleet (vans, capacity, depot, rates) is configured separately and changes rarely.
For the audit: the self-billed invoice / run records (per van-day: day-fee, miles, overnights, days taken, which van ran what). No telematics feed is needed or wanted — the audit verifies and benchmarks against these billed figures.
One hard fact shapes everything: the optimiser (Google OR-Tools, a C++/Python library) cannot run on the web edge (Cloudflare Workers/Pages are a JavaScript sandbox with no native libraries). So the solve runs on a real computer; the screens are just viewers.
| Area | Status |
|---|---|
| Optimisation engine (cost objective, all §5 constraints, verified) | Built |
| Load-auditing backtest (measured baseline vs optimised) | Built |
| Live planner — run sheets, ETAs, reloads, map, manual move, CSV export | Built (prototype) |
| Rolling-week scheduling within delivery windows | Built |
| Scale to the full fleet (regional decomposition) | Built (heuristic) |
| Exact road distances & geometry (OSRM) | Outstanding — demo approximates |
| Address → coordinates (geocoding) for postcode-only feeds | Outstanding |
| Live feed from the order system (vs file export) | Outstanding |
| Tramping: choose stopovers / optimise the overnight properly | Approximate |
| Hosting the solver for shared use (VM / Cloudflare Container) | Outstanding — runs locally now |
Mainstream route-optimisation platforms (e.g. Descartes, Paragon/Aptean, Verizon Connect, OptimoRoute, Routific, Onfleet, Track-POD) share a common feature set. Below is what they typically offer, and where this system stands — to make the gaps explicit.
| Capability | Standard systems | This system |
|---|---|---|
| Multi-stop optimisation, time windows, capacity (weight/volume/pallets) | Yes | Yes — incl. volume + weight |
| Mixed delivery & collection (backhaul) | Usually | Yes |
| Multi-day / rolling-horizon scheduling within date windows | Sometimes | Yes (a strength here) |
| Driver-hours / WTD / break compliance | Yes (fleet-grade) | Out of scope — contractor's responsibility. Drivers are the contractor's (may swap drivers/vehicles en route); breaks are at driver discretion, and wide windows give the slack. |
| Manual edit / drag-drop reassignment, locked stops | Yes | Move a drop; locked dates (spec'd) |
| Dynamic re-optimisation (mid-day disruptions, add/remove live) | Yes | Re-optimise point spec'd; not yet live-tracked |
| Driver mobile app + navigation | Yes | Have — Kybotech's own driver app |
| Electronic proof of delivery (photo, signature, barcode) | Yes | Have |
| Customer ETA notifications (SMS/email) | Yes | Have |
| Live GPS tracking | Yes (often telematics) | Position comes from the driver app during the day (no telematics, by choice); not stored beyond the day for privacy. Could be surfaced as a live, ephemeral map. |
| Traffic-aware ETAs / live road speeds | Yes | Gap — see options below; OSRM (planning) + a traffic API (live ETAs) |
| Order-system / ERP integration (live feed) | Yes | File export now; live feed to build |
| KPI / utilisation dashboards, fill-rate reporting | Yes | Audit report yes; ongoing dashboard to build |
| Cost-model optimisation (day-rate + mileage, not just miles) | Rare | Yes — core to it |
| Load auditing (measured baseline vs optimised, £ saving) | Rare | Yes — a distinctive facility |
| Skills / vehicle-access / tail-lift constraints, SLA priority tiers | Yes | Not modelled yet |
Two separate things, with different answers:
| Need | Best approach |
|---|---|
| Planning the week's routes | You don't need live traffic to plan ahead. Use OSRM with time-of-day speed profiles (rush-hour slower) baked from historical data — free, fast, accurate enough for next-week scheduling. |
| Live tracking on the day | The driver app already reports position during the day (it powers ePOD & ETAs). Surface that as a live map for the dispatcher — but keep it ephemeral (today only), not stored, per the privacy stance. No telematics needed. |
| Traffic-aware customer ETAs | Use a traffic-aware routing API only for the live ETA (not the bulk optimise): Google Routes API, Mapbox, HERE or TomTom. Called per active stop on the day, the cost is small. Keep OSRM for the heavy weekly optimisation (a traffic API on the full matrix would be expensive). |
Rule of thumb: OSRM (free) for planning, a traffic API (paid, sparingly) for live ETAs. Live GPS comes from the kit you already run.
The demo carries scaffolding to explain the concept — Today-vs-Optimised toggles, "no-reload" comparisons, worked scenarios. The production tool drops all of that. Installed into a real process, everything is already optimised, so those comparisons don't exist. It reduces to:
Plans aren't static. A customer is offered and accepts a date → that order is locked. A customer later demands a switch → the planner moves it and locks the new date. Either way, the system then re-runs the optimiser holding all locked orders fixed and re-sorting the rest of the flexible pool around them — so the week stays optimal without disturbing committed promises. So there are really two states: flexible (the optimiser owns the day) and locked (the customer owns the day, the optimiser plans around it). The re-optimise button reconciles the two whenever something changes.
This document describes the prototype as built, plus the agreed production direction. Numbers and product details use synthetic demo data; the real saving and fleet figures come from Kybotech's own exports.