Skip to content

API Performance

Marcel1853 edited this page Oct 10, 2026 · 3 revisions

🇩🇪 Deutsche Version · ⬅ For mod authors

Performance

UTL is built for many trains and high UPS and keeps the interface cheap. Each mod is responsible for its own performance – here is when UTL calls something and what gets expensive.

What UTL calls

What When How often
delivery events on creation, on every state change, at the end a few times per delivery
on_train_arrived / on_train_departed when a train stops at / leaves a UTL station once per stop
on_train_idle when a train stands free in a depot once per depot visit
on_train_rebuilt when a train UTL knows is rebuilt rarely
on_job_finished at the end of a job once per job
station events when a station is built, removed or changed rarely
on_alert on every UTL alert (with its repeat lock) rarely
on_request_unserved when a requester waits too long without a train at most once per minute per request
train filter only for trips from/to an add-on role, once per dispatch attempt if no train is found, again every few seconds
section in the station window when the window is opened or rebuilt rarely
manager tab when the tab is selected or ⟲ rarely

Without an add-on none of this costs anything: callbacks only happen when something is registered. Events without a listener are almost free. Nothing is called every tick.

Tips

  • On events only remember, calculate later. Doing a lot of work on every arrival slows the game down. Better remember the data and work through it in small portions in your own on_nth_tick (fixed budget per run).
  • Keep train filters fast: only go through the list and look up your own stored data – no path finding, no searching for entities inside the filter.
  • Path finding for jobs and inserted stops: send_job and add_delivery_stop check by path finding that the target is reachable; for a waypoint by position (without rail_direction) the same search also finds the direction. On big maps a search can take a few milliseconds (measured: up to about 10 ms with 384 trains and 880 stations). To save it, give rail and direction directly and set skip_path_check = true when the target is surely reachable.
  • get_station for many stations copies all settings every time – in a loop over hundreds of stations rather get get_stations once and remember the values you need.
  • Do not query lists on a timer: get_stations, get_idle_trains, get_deliveries and the like go through all entries and return copies. Get them once and keep them up to date with the events.
  • Windows: fill them only when opening; refresh them yourself only while open, and only what changed.
  • Measure your own load with /c remote.call("utl", "perf", 600) and Factorio's time usage display (F4 → show-time-usage).

Clone this wiki locally