Skip to content

perf: return TimerSequenceID by value instead of pointer - #11177

Merged
yiminc merged 3 commits into
temporalio:mainfrom
mykaul:perf/timer-sequence-by-value
Aug 19, 2026
Merged

perf: return TimerSequenceID by value instead of pointer#11177
yiminc merged 3 commits into
temporalio:mainfrom
mykaul:perf/timer-sequence-by-value

Conversation

@mykaul

@mykaul mykaul commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Motivation

TimerSequenceID (~48 bytes) is heap-allocated and returned as a *TimerSequenceID from 5 getter functions: getUserTimerTimeout, getActivityScheduleToStartTimeout, getActivityScheduleToCloseTimeout, getActivityStartToCloseTimeout, and getActivityHeartbeatTimeout. These are called for every pending timer/activity during LoadAndSortUserTimers() and LoadAndSortActivityTimers() — a hot path in every workflow task.

Callers were already dereferencing the pointer before appending to the value-type []TimerSequenceID slice, so the existing code was allocating on the heap only to immediately copy to the stack.

Changes

  • TimerSequenceID is now returned by value with a (TimerSequenceID, bool) tuple
  • Idiomatic Go pattern (same as map access) replaces nil-check sentinel
  • All 5 getter methods updated + call sites and tests adapted

Impact

Eliminates one heap allocation per getter call on the timer-sorting hot path.

Tests

  • service/history/workflow (1075 tests): ✅ passed

Change timer helper functions to return (TimerSequenceID, bool) instead
of *TimerSequenceID to avoid heap allocations on every call. Eliminates
~171MB of allocations per 5-minute benchmark run.
@mykaul
mykaul requested review from a team as code owners July 21, 2026 14:41
TimerCreated: timerInfo.TaskStatus == TimerTaskStatusCreated,
Attempt: 1,
}
}, true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is always true, so it is fine if we don't return the boolean here.

@prathyushpv prathyushpv added the reliability-2026 Reliability related changes label Aug 19, 2026
Resolves conflicts with temporalio#11565, which split the activity timer getters into
free functions plus thin method wrappers. Both forms now return
(TimerSequenceID, bool), and getActivityTimerDeadlines iterates over the
getters instead of over their results.
@prathyushpv
prathyushpv requested a review from a team August 19, 2026 01:23
Unlike the activity getters, this one has no early returns, so the bool
could never be false and the conditional around the call never filtered
anything.
@yiminc
yiminc enabled auto-merge (squash) August 19, 2026 03:59
@yiminc
yiminc merged commit fb8894c into temporalio:main Aug 19, 2026
54 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

reliability-2026 Reliability related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants