perf: avoid intermediate Date objects in trace aggregation loop

Store timestamps as numbers during the aggregation loop instead of
creating 2 Date objects per LLM call per existing trace entry.
Convert to Date once per trace at the end. Also sort on numeric
timestamps instead of calling .getTime() in the comparator, and
use a for-of loop instead of .forEach for slightly less overhead.
This commit is contained in:
Kevin Turcios 2026-04-11 04:09:20 -05:00
parent 1ef61d1e76
commit bcaf08b508

View file

@ -359,12 +359,13 @@ async function TracesPageContent({
const orgs = await getUniqueOrganizations()
// Group by trace_id and calculate aggregates
const traceMap = new Map<
// Use numeric timestamps during aggregation to avoid creating Date objects per iteration
const traceAggMap = new Map<
string,
{
trace_id: string
first_seen: Date
last_seen: Date
first_seen_ms: number
last_seen_ms: number
call_count: number
total_cost: number
total_tokens: number
@ -375,11 +376,11 @@ async function TracesPageContent({
}
>()
llmCalls.forEach(call => {
if (!call.trace_id) return
for (const call of llmCalls) {
if (!call.trace_id) continue
const callTimestamp = new Date(call.created_at).getTime()
const existing = traceMap.get(call.trace_id)
const existing = traceAggMap.get(call.trace_id)
const { cost: callCost, tokens: callTokens } = safeCostTokens(
call.llm_cost,
call.total_tokens,
@ -392,13 +393,13 @@ async function TracesPageContent({
if (call.status === "failed") existing.failed_calls++
if (call.status === "partial_success") existing.hasPartial = true
if (call.call_type) existing.call_types.add(call.call_type)
existing.first_seen = new Date(Math.min(existing.first_seen.getTime(), callTimestamp))
existing.last_seen = new Date(Math.max(existing.last_seen.getTime(), callTimestamp))
if (callTimestamp < existing.first_seen_ms) existing.first_seen_ms = callTimestamp
if (callTimestamp > existing.last_seen_ms) existing.last_seen_ms = callTimestamp
} else {
traceMap.set(call.trace_id, {
traceAggMap.set(call.trace_id, {
trace_id: call.trace_id,
first_seen: new Date(callTimestamp),
last_seen: new Date(callTimestamp),
first_seen_ms: callTimestamp,
last_seen_ms: callTimestamp,
call_count: 1,
total_cost: callCost,
total_tokens: callTokens,
@ -408,13 +409,24 @@ async function TracesPageContent({
call_types: new Set(call.call_type ? [call.call_type] : []),
})
}
})
}
// Convert to array and sort by last_seen desc
// Convert to final shape with Date objects and sort by last_seen desc
// No need to paginate here - already done at database level
const traces = Array.from(traceMap.values()).sort(
(a, b) => b.last_seen.getTime() - a.last_seen.getTime(),
)
const traces = Array.from(traceAggMap.values())
.sort((a, b) => b.last_seen_ms - a.last_seen_ms)
.map(t => ({
trace_id: t.trace_id,
first_seen: new Date(t.first_seen_ms),
last_seen: new Date(t.last_seen_ms),
call_count: t.call_count,
total_cost: t.total_cost,
total_tokens: t.total_tokens,
failed_calls: t.failed_calls,
hasPartial: t.hasPartial,
status: t.status,
call_types: t.call_types,
}))
const totalPages = Math.ceil(totalTracesCount / pageSize)
return (