@@ -275,6 +275,8 @@ def tool_calls?
275275 alias_method :has_tool_calls? , :tool_calls?
276276
277277 # Returns real-time dashboard data for the Now Strip
278+ # Optimized: 3 queries (current aggregate + previous aggregate + running count)
279+ # instead of ~15 individual count/sum/average queries.
278280 #
279281 # @param range [String] Time range: "today", "7d", "30d", or "90d"
280282 # @return [Hash] Now strip metrics with period-over-period comparisons
@@ -293,38 +295,31 @@ def self.now_strip_data(range: "today")
293295 else yesterday
294296 end
295297
296- current = {
297- running : running . count ,
298- success_today : current_scope . status_success . count ,
299- errors_today : current_scope . status_error . count ,
300- timeouts_today : current_scope . status_timeout . count ,
301- cost_today : current_scope . sum ( :total_cost ) || 0 ,
302- executions_today : current_scope . count ,
303- success_rate : calculate_period_success_rate ( current_scope ) ,
304- avg_duration_ms : current_scope . avg_duration &.round || 0 ,
305- total_tokens : current_scope . total_tokens_sum || 0
306- }
307-
308- previous = {
309- success : previous_scope . status_success . count ,
310- errors : previous_scope . status_error . count ,
311- cost : previous_scope . sum ( :total_cost ) || 0 ,
312- avg_duration_ms : previous_scope . avg_duration &.round || 0 ,
313- total_tokens : previous_scope . total_tokens_sum || 0
314- }
298+ curr = aggregate_period_stats ( current_scope )
299+ prev = aggregate_period_stats ( previous_scope )
315300
316- current . merge (
301+ {
302+ running : running . count ,
303+ success_today : curr [ :success ] ,
304+ errors_today : curr [ :errors ] ,
305+ timeouts_today : curr [ :timeouts ] ,
306+ cost_today : curr [ :cost ] ,
307+ executions_today : curr [ :total ] ,
308+ success_rate : curr [ :success_rate ] ,
309+ avg_duration_ms : curr [ :avg_duration_ms ] ,
310+ total_tokens : curr [ :tokens ] ,
317311 comparisons : {
318- success_change : pct_change ( previous [ :success ] , current [ :success_today ] ) ,
319- errors_change : pct_change ( previous [ :errors ] , current [ :errors_today ] ) ,
320- cost_change : pct_change ( previous [ :cost ] , current [ :cost_today ] ) ,
321- duration_change : pct_change ( previous [ :avg_duration_ms ] , current [ :avg_duration_ms ] ) ,
322- tokens_change : pct_change ( previous [ :total_tokens ] , current [ :total_tokens ] )
312+ success_change : pct_change ( prev [ :success ] , curr [ :success ] ) ,
313+ errors_change : pct_change ( prev [ :errors ] , curr [ :errors ] ) ,
314+ cost_change : pct_change ( prev [ :cost ] , curr [ :cost ] ) ,
315+ duration_change : pct_change ( prev [ :avg_duration_ms ] , curr [ :avg_duration_ms ] ) ,
316+ tokens_change : pct_change ( prev [ :tokens ] , curr [ :tokens ] )
323317 }
324- )
318+ }
325319 end
326320
327321 # Returns Now Strip data for a custom date range
322+ # Optimized: 3 queries instead of ~15.
328323 #
329324 # Compares the selected range against the same-length window
330325 # immediately preceding it.
@@ -339,35 +334,27 @@ def self.now_strip_data_for_dates(from:, to:)
339334 previous_to = from - 1 . day
340335 previous_scope = where ( created_at : previous_from . beginning_of_day ..previous_to . end_of_day )
341336
342- current = {
343- running : running . count ,
344- success_today : current_scope . status_success . count ,
345- errors_today : current_scope . status_error . count ,
346- timeouts_today : current_scope . status_timeout . count ,
347- cost_today : current_scope . sum ( :total_cost ) || 0 ,
348- executions_today : current_scope . count ,
349- success_rate : calculate_period_success_rate ( current_scope ) ,
350- avg_duration_ms : current_scope . avg_duration &.round || 0 ,
351- total_tokens : current_scope . total_tokens_sum || 0
352- }
353-
354- previous = {
355- success : previous_scope . status_success . count ,
356- errors : previous_scope . status_error . count ,
357- cost : previous_scope . sum ( :total_cost ) || 0 ,
358- avg_duration_ms : previous_scope . avg_duration &.round || 0 ,
359- total_tokens : previous_scope . total_tokens_sum || 0
360- }
337+ curr = aggregate_period_stats ( current_scope )
338+ prev = aggregate_period_stats ( previous_scope )
361339
362- current . merge (
340+ {
341+ running : running . count ,
342+ success_today : curr [ :success ] ,
343+ errors_today : curr [ :errors ] ,
344+ timeouts_today : curr [ :timeouts ] ,
345+ cost_today : curr [ :cost ] ,
346+ executions_today : curr [ :total ] ,
347+ success_rate : curr [ :success_rate ] ,
348+ avg_duration_ms : curr [ :avg_duration_ms ] ,
349+ total_tokens : curr [ :tokens ] ,
363350 comparisons : {
364- success_change : pct_change ( previous [ :success ] , current [ :success_today ] ) ,
365- errors_change : pct_change ( previous [ :errors ] , current [ :errors_today ] ) ,
366- cost_change : pct_change ( previous [ :cost ] , current [ :cost_today ] ) ,
367- duration_change : pct_change ( previous [ :avg_duration_ms ] , current [ :avg_duration_ms ] ) ,
368- tokens_change : pct_change ( previous [ :total_tokens ] , current [ :total_tokens ] )
351+ success_change : pct_change ( prev [ :success ] , curr [ :success ] ) ,
352+ errors_change : pct_change ( prev [ :errors ] , curr [ :errors ] ) ,
353+ cost_change : pct_change ( prev [ :cost ] , curr [ :cost ] ) ,
354+ duration_change : pct_change ( prev [ :avg_duration_ms ] , curr [ :avg_duration_ms ] ) ,
355+ tokens_change : pct_change ( prev [ :tokens ] , curr [ :tokens ] )
369356 }
370- )
357+ }
371358 end
372359
373360 # Calculates percentage change between old and new values
@@ -391,6 +378,39 @@ def self.calculate_period_success_rate(scope)
391378 ( scope . successful . count . to_f / total * 100 ) . round ( 1 )
392379 end
393380
381+ # Returns aggregate stats for a scope in a single query using conditional aggregation
382+ #
383+ # Replaces ~9 individual count/sum/average queries with one SQL query.
384+ #
385+ # @param scope [ActiveRecord::Relation] Time-filtered scope
386+ # @return [Hash] Aggregated metrics
387+ def self . aggregate_period_stats ( scope )
388+ total , success , errors , timeouts , cost , avg_dur , tokens = scope . pick (
389+ Arel . sql ( "COUNT(*)" ) ,
390+ Arel . sql ( "SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END)" ) ,
391+ Arel . sql ( "SUM(CASE WHEN status = 'error' THEN 1 ELSE 0 END)" ) ,
392+ Arel . sql ( "SUM(CASE WHEN status = 'timeout' THEN 1 ELSE 0 END)" ) ,
393+ Arel . sql ( "COALESCE(SUM(total_cost), 0)" ) ,
394+ Arel . sql ( "AVG(duration_ms)" ) ,
395+ Arel . sql ( "COALESCE(SUM(total_tokens), 0)" )
396+ )
397+
398+ total = total . to_i
399+ success = success . to_i
400+
401+ {
402+ total : total ,
403+ success : success ,
404+ errors : errors . to_i ,
405+ timeouts : timeouts . to_i ,
406+ cost : cost . to_f ,
407+ avg_duration_ms : avg_dur . to_i ,
408+ tokens : tokens . to_i ,
409+ success_rate : ( total > 0 ) ? ( success . to_f / total * 100 ) . round ( 1 ) : 0.0
410+ }
411+ end
412+ private_class_method :aggregate_period_stats
413+
394414 private
395415
396416 # Calculates and sets total_tokens from input and output
0 commit comments