Skip to main content
iVentureTeam

mrp_timer

A duration that counts up while the operator is clocked on. It asks the server for the real elapsed time rather than trusting the stored value, then keeps ticking locally.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 27, 2026Updated August 28, 20265 min read
Technical namemrp_timer
Field typesfloat
Viewsform, list, kanban
Also registered asa formatter of the same name in the formatters registry
Modulemrp, the Manufacturing app
Used in coreWork order durations across the Manufacturing views
VersionsOdoo 20.0, Odoo 19.0, Odoo 18.0, Odoo 17.0, Odoo 16.0
No-code setupNo. It depends on a companion working flag and a server method
Alternativesfloat_time, timesheet_duration_uom, float, mrp_should_consume

What the manufacturing timer does

A work order's duration is a stored number, updated when the operator clocks off. While they are still working it is out of date by definition, and showing a stale figure on a shop floor screen is worse than showing nothing.

This widget shows a live one. When the record says the current user is working on it, the widget asks the server how long that has actually been, then counts up from there, so the number on screen matches the clock rather than the last save.

When nobody is working, it simply formats the stored value. The same widget therefore serves a running work order and a finished one without the view needing to distinguish them.

What this means for your team

Shop floor time is the input to costing, capacity planning and, in many businesses, payroll. A timer that resets or drifts on a page reload undermines all three, and it is the first thing an operator stops trusting.

Asking the server for the elapsed time rather than counting from when the page loaded is what makes it reliable. An operator who starts a job, walks away and comes back to a refreshed browser sees the real elapsed time, not a timer that restarted.

The practical requirement is that the record carries the flag saying whether the current user is working. Without it the widget has nothing to key the live behavior on, and shows a static number.

Supported options in Odoo 19

The widget declares no options and one supported type. What drives it is a companion field and a server method, both listed below. Read from timer.js, Odoo 19.0.

OptionTypeWhat it does
is_user_workingcompanion fieldRead by literal name. When true the timer runs live; otherwise the stored value is simply formatted.
get_durationserver methodCalled for a running timer to obtain the real elapsed duration, so a page reload does not restart the count.

It registers a formatter too. The same name is added to the formatters registry alongside the widget, so the minute formatting can be reused by other code without instantiating the widget. That is unusual and worth knowing if you are formatting durations elsewhere in Manufacturing.

Working examples

The usual usage

<field name="duration" widget="mrp_timer"/>

Ticks while the current user is working on the record, and formats the stored value otherwise.

The companion field it needs

<field name="is_user_working" invisible="1"/>

Read by literal name. Without it the timer never runs.

A plain duration

<field name="duration" widget="float_time"/>

Hours and minutes with no live behavior, correct for a completed order.

Asking the server rather than counting from page load

The important decision is where the running value comes from. Rather than counting from page load, the widget calls a server method for the record's real duration when it detects that work is in progress, then advances that number locally. That is what makes the display survive a refresh.

The local ticking is a repeating timer stored on the instance, and it is cleared when the component is destroyed. Forgetting that cleanup is the classic way a timer widget leaks, so its presence is worth noting when writing something similar.

Re-syncing is handled in the formatting getter rather than by an observer. If the record is dirty and the field's value differs from what the widget is showing, it adopts the record's value. That covers the case where something else on the form changes the duration while the timer is running.

The formatter registration alongside the widget means the minutes format is available by name to other Manufacturing code, which is why work order durations look consistent across screens that do not all use this widget.

Version compatibility

VersionStatusNotes
Odoo 20.0In developmentNot released. Behavior unchanged on the development branch.
Odoo 19.0VerifiedVerified against the shipped source.
Odoo 18.0VerifiedSame behavior with internal differences.
Odoo 17.0VerifiedSame behavior with older component conventions.
Odoo 16.0VerifiedSame behavior with older component conventions.

Upgrade note. The widget and its companion flag have been stable across Odoo 16 to 19, so views carry over. The internals have moved between versions, so a customization that patched the ticking is more likely to need attention than a view.

What is changing in Odoo 20

Odoo 20 is expected at Odoo Experience in Brussels, 24 to 26 September 2026. The development branch is unstable and this may still change; we re-verify this page after the release.

Behavior is unchanged. The server lookup for a running timer, the local ticking, the cleanup and the re-sync all behave the same. The differences follow the wider component migration and affect patches rather than views.

Common problems and fixes

SymptomCause and fix
The timer does not tickThe record does not carry the working flag, or it is false for the current user. Load that field in the view and check the operator is actually clocked on.
The timer restarts after a reloadIt should not; the widget asks the server for the real duration. Check the server method is reachable and returns a duration.
The value jumps while runningThe record became dirty and the field changed, so the widget adopted the record's value. Expected; something else on the form updated the duration.
The format differs from other screensThose screens may use the registered formatter rather than the widget. Use the formatter of the same name for consistency.
It will not attach to my fieldThe declared supported type is a decimal number. Store the duration as a float.
Missing widget errorThe manufacturing module is not installed in that database. Install Manufacturing, or use the hours and minutes widget.

Manufacturing timer vs the alternatives

WidgetBest forKey difference
mrp_timerWork order durations that must tick while an operator is workingTakes the running value from the server, then counts locally and cleans up after itself
float_timeA completed durationFormats hours and minutes with no live behavior
timesheet_duration_uomDurations that follow a company unit settingUnit-aware rather than live
floatA plain decimalNo time formatting at all
mrp_should_consumeQuantities on the same screensShows a should-consume figure rather than a duration

Use the hours and minutes widget for a completed duration where no live behavior is wanted, and the timesheet duration widget where the unit should follow a company setting. This widget is specific to work orders in that it depends on the working flag and the server method behind it.

Frequently asked questions

How does the timer survive a page reload?+
When it detects that work is in progress it asks the server for the real elapsed duration rather than counting from when the page loaded, then advances that value locally.
What decides whether it ticks?+
A companion field on the record saying whether the current user is working on it, read by literal name. Without that field the widget shows a static value.
Does it leak a timer?+
No. The repeating timer is cleared when the component is destroyed, which is worth copying if you write something similar.
Why is the same name in the formatters registry?+
The widget registers its minutes format as a formatter as well, so other Manufacturing code can reuse the format without the widget.
Does it take options?+
None. It declares one supported type and no options; the behavior comes from the companion field and the server method.

Shop floor data your costing can rely on

Work order timing, scrap and consumption feed straight into product cost, and the shop floor screens decide how honest that data is. We implement Odoo Manufacturing on versions 16 through 19.

Book a free consultation

How this page was produced

The server lookup for a running duration, the local timer and its cleanup, the re-sync in the formatting getter, the companion flag and the formatter registration were read from timer.js on the Odoo 19.0 branch. Version coverage comes from comparing the file across the 16.0, 17.0 and 18.0 branches and against the public development branch. Spotted an error? Tell us and we will correct the page.