Skip to content

Conversation

@ktx-abhay
Copy link
Collaborator

@ktx-abhay ktx-abhay commented Oct 17, 2025

PR Type

Bug fix, Enhancement


Description

  • Cap series per query for PromQL

  • Split SQL series limit across y-axes

  • Prevent multi y-axis performance regressions


Diagram Walkthrough

flowchart LR
  Config["Dashboard config: max_dashboard_series"]
  PromQL["convertPromQLData: per-query cap"]
  SQL["convertSQLData: per-axis cap with breakdown"]
  Performance["Reduced series -> better performance"]

  Config -- "read max limit" --> PromQL
  Config -- "read max/top_results" --> SQL
  PromQL -- "divide by active queries" --> Performance
  SQL -- "divide by yAxisKeys when breakdowns" --> Performance
Loading

File Walkthrough

Relevant files
Enhancement
convertPromQLData.ts
Per-query series limiting for PromQL results                         

web/src/utils/dashboard/convertPromQLData.ts

  • Replace global series cap with per-query cap.
  • Compute active query count and divide max limit.
  • Slice each query's results by per-query limit.
  • Remove decremental cross-query limiting logic.
+10/-4   
Bug fix
convertSQLData.ts
Per-axis series cap for SQL with breakdowns                           

web/src/utils/dashboard/convertSQLData.ts

  • Introduce adaptive limit for multi y-axis charts.
  • Divide series limit by y-axis count when breakdowns present.
  • Preserve top_results and max_dashboard_series constraints.
+8/-1     

@github-actions
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Behavior Change

Per-query capping replaces the previous global rolling cap. This may increase total series when some queries have few/no results (unused budget is no longer reallocated). Validate that total series across queries never exceeds the intended global cap and that UX expectations are met.

// For multiple queries (multi y-axis equivalent), divide the limit equally
const numberOfQueries = searchQueryData.filter(
  (q: any) => q.result?.length > 0,
).length;
const limitPerQuery =
  numberOfQueries > 1 ? Math.floor(maxSeries / numberOfQueries) : maxSeries;

// Limit number of series to limitPerQuery per query
const limitedSearchQueryData = searchQueryData.map((queryData: any) => {
  if (!queryData || !queryData.result) {
    return queryData;
  }
  const remainingSeries = queryData.result.slice(0, limitPerQuery);
  return {
    ...queryData,
    result: remainingSeries,
  };
Edge Case

Division by number of active queries uses floor; when max is less than number of queries, limitPerQuery can become 0 and drop all series for some queries. Confirm desired behavior and consider guaranteeing a minimum of 1 per non-empty query, up to the cap.

const numberOfQueries = searchQueryData.filter(
  (q: any) => q.result?.length > 0,
).length;
const limitPerQuery =
  numberOfQueries > 1 ? Math.floor(maxSeries / numberOfQueries) : maxSeries;
Logic Assumption

SQL capping divides by yAxis count only when breakdowns exist; multi-axis without breakdowns may exceed global cap. Confirm that skipping division in that case is intentional and aligns with performance goals.

// For multi y-axis charts, divide the limit by number of y-axes
// to keep total series count at or below max_dashboard_series
// This applies when there are multiple y-axes AND breakdown fields
if (yAxisKeys.length > 1 && breakDownKeys.length > 0) {
  limitSeries = Math.floor(limitSeries / yAxisKeys.length);
}

@github-actions
Copy link
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Enforce global series budget

Prevent exceeding maxSeries when many queries have data by enforcing a global cap
after per-query truncation. After mapping, trim surplus series from later queries so
the total never surpasses maxSeries.

web/src/utils/dashboard/convertPromQLData.ts [125-133]

+let remainingBudget = maxSeries;
 const limitedSearchQueryData = searchQueryData.map((queryData: any) => {
-  if (!queryData || !queryData.result) {
-    return queryData;
+  if (!queryData || !queryData.result?.length || remainingBudget <= 0) {
+    return { ...queryData, result: [] };
   }
-  const remainingSeries = queryData.result.slice(0, limitPerQuery);
+  const perQueryCap = Math.min(limitPerQuery, remainingBudget);
+  const kept = queryData.result.slice(0, perQueryCap);
+  remainingBudget -= kept.length;
   return {
     ...queryData,
-    result: remainingSeries,
+    result: kept,
   };
 });
Suggestion importance[1-10]: 7

__

Why: Applying a global remaining budget guarantees total series never exceeds maxSeries even with rounding, improving correctness across multiple queries; the change is accurate and integrates with existing mapping.

Medium
Enforce a minimum per-query limit

Guard against division by zero or producing zero-per-query limits when many queries
exist. Ensure limitPerQuery is at least 1 so every non-empty query can contribute at
least one series while still respecting maxSeries.

web/src/utils/dashboard/convertPromQLData.ts [118-123]

 const numberOfQueries = searchQueryData.filter(
   (q: any) => q.result?.length > 0,
 ).length;
-const limitPerQuery =
-  numberOfQueries > 1 ? Math.floor(maxSeries / numberOfQueries) : maxSeries;
+const rawLimit = numberOfQueries > 1 ? Math.floor(maxSeries / numberOfQueries) : maxSeries;
+const limitPerQuery = Math.max(1, rawLimit);
Suggestion importance[1-10]: 6

__

Why: Ensuring limitPerQuery is at least 1 avoids zero allocation when maxSeries < numberOfQueries, which can otherwise drop all series; it's a reasonable safeguard with modest impact and aligns with the new per-query split logic.

Low
Clamp per-axis limit to minimum

Avoid zero or negative limitSeries when many y-axes exist by enforcing a minimum of
1. This prevents empty charts and potential downstream assumptions on non-empty
series.

web/src/utils/dashboard/convertSQLData.ts [308-310]

 if (yAxisKeys.length > 1 && breakDownKeys.length > 0) {
-  limitSeries = Math.floor(limitSeries / yAxisKeys.length);
+  limitSeries = Math.max(1, Math.floor(limitSeries / yAxisKeys.length));
 }
Suggestion importance[1-10]: 6

__

Why: Clamping to at least 1 avoids zero series when dividing by many y-axes, which can cause empty visuals; it's a small but practical robustness improvement consistent with the new logic.

Low

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Summary

Improved dashboard trellis chart performance by optimizing series limiting logic in both PromQL and SQL data converters.

Key changes:

  • convertPromQLData.ts: Replaced sequential "waterfall" series limiting (where later queries get fewer series) with equal distribution across all queries. This ensures fair allocation when multiple y-axes are present.
  • convertSQLData.ts: Added logic to divide the series limit by the number of y-axes when multiple y-axes AND breakdown fields exist, preventing series explosion in trellis charts.

Both changes ensure total series count stays at or below max_dashboard_series configuration value while distributing the limit more fairly across multiple queries/axes.

Confidence Score: 4/5

  • This PR is safe to merge with minimal risk - the changes are focused and improve performance for trellis charts
  • The changes are well-scoped and address a specific performance issue with trellis charts. The logic is straightforward: distributing series limits more fairly across queries/axes. The score is 4 (not 5) because the PR lacks a description and there are no associated tests visible in the changeset to verify the new behavior, though the changes themselves appear sound.
  • No files require special attention - both changes are straightforward performance optimizations

Important Files Changed

File Analysis

Filename Score Overview
web/src/utils/dashboard/convertPromQLData.ts 4/5 Changed series limiting from sequential waterfall approach to equal distribution across queries; improves fairness and performance for multi y-axis charts
web/src/utils/dashboard/convertSQLData.ts 4/5 Added logic to divide series limit by number of y-axes when multiple y-axes and breakdown fields exist; prevents series explosion in trellis charts

Sequence Diagram

sequenceDiagram
    participant Dashboard
    participant convertPromQLData
    participant convertSQLData
    participant Store
    
    Dashboard->>Store: Get max_dashboard_series config
    Store-->>Dashboard: Return maxSeries (default: 100)
    
    alt PromQL Data Path
        Dashboard->>convertPromQLData: searchQueryData, panelSchema
        convertPromQLData->>convertPromQLData: Count queries with results
        convertPromQLData->>convertPromQLData: Calculate limitPerQuery<br/>(maxSeries / numberOfQueries)
        convertPromQLData->>convertPromQLData: Apply equal limit to each query
        convertPromQLData-->>Dashboard: Return limited series data
    else SQL Data Path
        Dashboard->>convertSQLData: data, panelSchema
        convertSQLData->>convertSQLData: Get limitSeries from config
        alt Multi Y-Axis with Breakdown
            convertSQLData->>convertSQLData: Divide limitSeries<br/>by yAxisKeys.length
        end
        convertSQLData->>convertSQLData: Apply limit per y-axis
        convertSQLData-->>Dashboard: Return limited series data
    end
    
    Dashboard->>Dashboard: Render chart with limited series
Loading

2 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

@testdino-playwright-reporter
Copy link

⚠️ Test Run Unstable


Author: ktx-abhay | Branch: fix/dashboard/trellis-chart-peformance-issue-main | Commit: ac69938

Testdino Test Results

Status Total Passed Failed Skipped Flaky Pass Rate Duration
All tests passed 364 342 0 19 3 94% 4m 38s

View Detailed Results

@ktx-abhay ktx-abhay merged commit c9de946 into main Oct 17, 2025
33 checks passed
@ktx-abhay ktx-abhay deleted the fix/dashboard/trellis-chart-peformance-issue-main branch October 17, 2025 06:56
uddhavdave pushed a commit that referenced this pull request Oct 27, 2025
### **PR Type**
Bug fix, Enhancement


___

### **Description**
- Cap series per query for PromQL

- Split SQL series limit across y-axes

- Prevent multi y-axis performance regressions


___

### Diagram Walkthrough


```mermaid
flowchart LR
  Config["Dashboard config: max_dashboard_series"]
  PromQL["convertPromQLData: per-query cap"]
  SQL["convertSQLData: per-axis cap with breakdown"]
  Performance["Reduced series -> better performance"]

  Config -- "read max limit" --> PromQL
  Config -- "read max/top_results" --> SQL
  PromQL -- "divide by active queries" --> Performance
  SQL -- "divide by yAxisKeys when breakdowns" --> Performance
```



<details> <summary><h3> File Walkthrough</h3></summary>

<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>convertPromQLData.ts</strong><dd><code>Per-query series
limiting for PromQL results</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

web/src/utils/dashboard/convertPromQLData.ts

<ul><li>Replace global series cap with per-query cap.<br> <li> Compute
active query count and divide max limit.<br> <li> Slice each query's
results by per-query limit.<br> <li> Remove decremental cross-query
limiting logic.</ul>


</details>


  </td>
<td><a
href="https://github.com/openobserve/openobserve/pull/8835/files#diff-68d70ba6c622911d48cdb567940dc404a4a6468b86c6d24fb54e5f1d8aa5ca2a">+10/-4</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Bug fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>convertSQLData.ts</strong><dd><code>Per-axis series cap
for SQL with breakdowns</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

web/src/utils/dashboard/convertSQLData.ts

<ul><li>Introduce adaptive limit for multi y-axis charts.<br> <li>
Divide series limit by y-axis count when breakdowns present.<br> <li>
Preserve top_results and max_dashboard_series constraints.</ul>


</details>


  </td>
<td><a
href="https://github.com/openobserve/openobserve/pull/8835/files#diff-88c0e865040a20b2c8bb7d77e7f6bd187a5b07c1645c120223bc9d59603752c3">+8/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

</details>

___
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants