Skip to content

Time tracking

Time tracking in OpsMerge captures how long your team spends on each ticket. Billable time feeds into invoices; non-billable time still gets recorded for reporting and capacity planning.

Two ways to log time

  1. The active timer. Start/stop button on each ticket; runs in real time.
  2. Manual entry. Add a time entry after the fact — describe what you did and how long.

Most operators use a mix — the timer for sustained work, manual entry for short interactions ("answered a quick question, 5 minutes").

The active timer

On any ticket header:

  • Start timer begins counting.
  • A small "ticking" indicator appears in the OpsMerge nav bar.
  • The timer survives page navigation — open another tab in OpsMerge, the timer keeps running.
  • Stop timer prompts you for:
    • Billable / non-billable (defaults to billable, but per-contract logic can override).
    • Notes describing what you did (becomes the time entry's description).
    • Service (links to billing category / QBO mapping).

Once stopped, the time entry appears on the ticket's Time tab and counts toward the contract's block-hours (if applicable) and the next invoice.

Stop the timer to commit the time

Closing the ticket while the timer is running discards the running time unless you explicitly stop it first. Auto-close, portal-close, and rule-based close also discard. Only Stop timer from the ticket header commits time. This is deliberate to prevent accidental over-billing, but it means a forgotten timer = lost billable work.

Passive timer (beta)

If you want OpsMerge to auto-start a timer when you open a ticket you're assigned to, enable the passive timer at User profile → Time → Passive timer. It auto-starts on ticket-open, pauses when you switch away, prompts to commit when you close the ticket.

Currently in beta — known to be slightly fragile across page reloads. Off by default. Worth experimenting with if you find yourself forgetting to start the timer.

Manual entries

Ticket → Time tab → + New entry.

Fields:

  • Started at (datetime).
  • Duration (hours and minutes, or just minutes).
  • Description (what you did).
  • Billable / non-billable.
  • Service (billing mapping).

Manual entries are good for short interactions that didn't justify timer overhead, and for retroactively logging time when you forgot the timer.

Billable vs internal

TypeWhat it means
BillableCounts toward the contract's block hours (if any) and bills on the next invoice (pay-as-you-go contracts).
InternalRecorded but not billed — for reporting and capacity. Doesn't draw from block hours.
Pre-paidDrawn from a project's pre-paid hours pool rather than the recurring block.

Default for new entries comes from the contract: per-asset and all-you-can-eat contracts default time to Billable but un-invoiced (included in the flat fee); block contracts default to Billable; pay-as-you-go defaults to Billable; internal-only clients default to Internal.

Time on closed tickets

When a ticket is closed:

  • Time entries are committed — they can't be edited without an audit-logged reason.
  • They flow to the next invoice if billable + pay-as-you-go (or contribute to block-hour accounting).
  • The ticket itself becomes read-only.

If you genuinely need to edit time on a closed ticket (typo, wrong duration): reopen the ticket, edit, close again. The reopen is logged.

How time hits invoices

For each invoice cycle, OpsMerge collects all billable time entries on tickets at this client for the period:

  • Block-hour contracts: subtract from the block; show overage hours as a line at the overage rate.
  • Pay-as-you-go contracts: each time entry (or aggregated by ticket / by description) becomes a line on the invoice.
  • All-you-can-eat contracts: time is recorded but doesn't generate lines on the invoice (it's already paid for in the flat fee).

You can preview how a client's current month-to-date time will affect billing on the client's page.

Time approval (optional)

For MSPs that want a sign-off step:

Settings → PSA → Time approval → Enable.

When enabled, time entries enter "Pending approval" state until a manager approves. Approved time is committed; rejected time is sent back to the operator with notes.

Most MSPs don't enable this — the audit log already captures who logged what, and approval adds friction without preventing fraud (a determined operator can still log false time).

Reports

Reports → Time.

Out of the box:

  • By technician / period — how much time each tech logged, billable vs internal.
  • By client / period — how much time was spent on each client.
  • By ticket type — incident time vs project time.
  • Block usage — block-hour contracts and how much was used.

Custom reports via SQL-builder or via the API.

Cross-tenant rates

If you have multiple operators charged at different rates, each user can have a per-user rate at Settings → Users → user → Hourly rate. The contract's rate is the default; the per-user rate overrides for invoices generated for that user's time.

For most MSPs, the contract rate is the only rate that matters — overriding per-user adds complexity that you only want if you're explicitly billing different rates for different staff.

Common patterns

"Always log time"

Make it a team rule: every ticket gets time logged before closing. Use the active timer for sustained work, manual entry for short interactions.

OpsMerge will prompt on close: "no time logged on this ticket — discard or log now?" The prompt is hard to bypass, which is the point.

"Forgotten timer"

If you realise you forgot to start the timer halfway through:

  1. Start the timer now.
  2. Manually backdate the Started at when you stop.
  3. Note in the description: "started 30 min before timer".

Or, stop and use a manual entry with the right duration.

"Bulk-logging time at end-of-day"

Some operators prefer this. Open the ticket, + New entry, log a 30-minute block with what you did. Repeat for each ticket. Faster than starting/stopping timers, slightly more error-prone.

Common issues

Time entries are missing from an invoice I expected them on. Check the time entries' billable flag and status (committed vs pending). Pending entries don't bill; non-billable entries don't bill; entries on a different client's tickets don't bill against this client. The invoice's "where this came from" detail shows the time entries it picked up.

Timer keeps running after I closed the tab. That's by design — the timer is server-side. Open OpsMerge again and you'll see it ticking. Stop it.

Atomic timer-stop fails for some reason. Pre-2026-05-15 there was a race where rapidly stopping and re-starting a timer could leave both running. Fixed now (atomic StopTimer). If you ever see a double-timer on the same ticket, refresh — the UI may be showing stale state.

Time on a beta-gated feature isn't tracked. Some platform features (e.g. the passive timer) are beta-gated. Check Settings → Beta features to see what's currently enabled for your tenant.

Next

OpsMerge is a product of Brindleford Technologies Ltd, company number 16871436, registered in England and Wales.