Skip to content

perf(analysis): paginate before hydration to fix component search timeout#2446

Open
mrrajan wants to merge 3 commits into
guacsec:mainfrom
mrrajan:TC-4365
Open

perf(analysis): paginate before hydration to fix component search timeout#2446
mrrajan wants to merge 3 commits into
guacsec:mainfrom
mrrajan:TC-4365

Conversation

@mrrajan

@mrrajan mrrajan commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Paginate before hydration: moves pagination from post-hydration array slicing to pre-hydration index-level skip/take via collect_graph_paged, eliminating the timeout caused by hydrating thousands of nodes only to discard most of them.
  • Deterministic ordering: uses BTreeSet for ranked SBOM IDs and adds order_by_asc(sbom_id) to subquery-based loading, ensuring stable pagination across requests.
  • Adds count_matching_nodes for efficient total counting without hydrating any nodes.

Test plan

  • Unit test test_pagination_limits_hydration — verifies only the requested number of nodes are hydrated while total reflects all matches
  • Unit test test_pagination_offset — verifies different offsets produce different results and union matches combined query
  • Unit test test_pagination_cross_graph — verifies pagination spans multiple SBOM graphs without duplicates or gaps
  • Endpoint test test_pagination_through_endpoint — verifies pagination via HTTP returns correct totals and distinct pages

Summary by Sourcery

Apply pagination at the graph index level before node hydration to improve performance and provide deterministic, cross-graph component retrieval with accurate totals.

New Features:

  • Add paginated graph query execution that counts matching nodes without hydrating them and applies global offset/limit across graphs.

Enhancements:

  • Ensure deterministic pagination by sorting ranked SBOM IDs and graph nodes by SBOM and node identifiers.
  • Wire all component retrieval paths to the new paginated graph query flow instead of array-based pagination.

Tests:

  • Add service-level tests to verify hydration is limited by pagination, offsets yield distinct pages, and pagination spans multiple SBOM graphs without gaps or duplicates.
  • Add endpoint-level test to ensure HTTP pagination returns correct totals and non-overlapping pages.

mrrajan and others added 3 commits July 3, 2026 12:44
…eout

Split graph node processing into three phases:
1. Count matching nodes across cached graphs (cheap in-memory filter)
2. Apply offset/limit to the globally-flattened node index iterator
3. Run expensive Collector hydration only for the paged subset

This reduces per-request work from ~39,280 Collector runs to ~25
(the default page limit), a ~1,500x improvement.

Also:
- Add deterministic graph ordering via ORDER BY sbom_id in
  load_graphs_subquery and sorted/deduped Vec in
  load_latest_graphs_query
- Migrate log::debug to tracing::debug in retrieve_latest
- Fix missing tokio feature on async-compression in common crate
- Add 4 pagination tests: limits, offset, cross-graph, endpoint

Implements TC-4365

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assisted-by: Claude Code
Implements TC-4365

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assisted-by: Claude Code
Replace Vec with manual sort()+dedup() with BTreeSet, which provides
sorted unique elements directly via the standard library.

Implements TC-4365

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assisted-by: Claude Code
@sourcery-ai

sourcery-ai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Implements offset/limit pagination at the graph index level before node hydration, adds a lightweight total-count path, and makes graph loading deterministic to prevent component search timeouts and ensure stable pagination across graphs and through the HTTP endpoint.

Sequence diagram for paginated graph query before hydration

sequenceDiagram
    actor Client
    participant AnalysisService
    participant PackageGraph
    participant GraphLoader
    participant Collector

    Client->>AnalysisService: run_graph_query_paged(query, options, graphs, paginated, connection)
    alt paginated.total()
        AnalysisService->>AnalysisService: count_matching_nodes(&query, graphs)
        loop each_graph
            AnalysisService->>PackageGraph: node_indices()
        end
    end
    AnalysisService->>AnalysisService: collect_graph_paged(query, graphs, concurrency, offset, limit, create)
    loop each_graph
        AnalysisService->>PackageGraph: node_indices()
    end
    AnalysisService->>GraphLoader: GraphLoader::new(self)
    loop each_paged_node
        AnalysisService->>Collector: Collector::new(..., Direction::Incoming)
        AnalysisService->>Collector: Collector::new(..., Direction::Outgoing)
        AnalysisService->>Collector: collect()
    end
    AnalysisService-->>Client: PaginatedResults<Node>
Loading

File-Level Changes

Change Details Files
Apply pagination before hydration by introducing a paged graph query pipeline and reusing it from all retrieve paths.
  • Add collect_graph_paged to flatten matching nodes across graphs, sort by (sbom_id, node_id), apply offset/limit at index level, and hydrate only the paged subset with bounded concurrency.
  • Add run_graph_query_paged that wires pagination, total counting, relationship options, and collectors together, returning PaginatedResults.
  • Update retrieve and related methods to call run_graph_query_paged directly instead of hydrating all nodes and paginating in-memory arrays.
  • Short-circuit pagination when limit is zero or offset is beyond precomputed total to avoid unnecessary work.
modules/analysis/src/service/mod.rs
Introduce efficient total-count computation without hydration and validate new pagination behavior with tests.
  • Add count_matching_nodes helper that walks graphs, applies the same filter as the query, and sums node counts across graphs without constructing Node objects.
  • Use count_matching_nodes in run_graph_query_paged when the Pagination object requests total=true.
  • Add service-level tests to verify hydration is limited, offsets produce distinct pages with correct totals, and pagination works correctly across multiple SBOM graphs without duplicates or gaps.
  • Add endpoint test to verify HTTP pagination returns correct totals, page sizes, and distinct items across pages.
modules/analysis/src/service/mod.rs
modules/analysis/src/service/test/mod.rs
modules/analysis/src/endpoints/tests/mod.rs
Make graph loading order deterministic to stabilize pagination across runs.
  • Change latest_ids from HashSet to BTreeSet so ranked sbom IDs are stored in sorted order, ensuring deterministic iteration when building graphs.
  • Add order_by_asc(sbom_id) to the distinct sbom query used when loading graphs by subquery, aligning DB ordering with in-memory ordering expectations.
modules/analysis/src/service/load/mod.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

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.

Hey - I've found 4 issues, and left some high level feedback:

  • collect_graph_paged currently materializes and sorts all matching nodes across all graphs before applying offset/limit; if match sets are large this can still be expensive, so consider an approach that skips the first offset matches on the fly and only stores up to limit items (e.g., streaming iteration with a bounded buffer or a selection algorithm) to reduce memory and sort cost.
  • count_matching_nodes traverses all graphs a second time when total() is true, duplicating the filter work done in collect_graph_paged; if totals are requested frequently, it might be worth sharing the traversal (e.g., counting while collecting) or caching counts to avoid an extra full pass over all node indices.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- collect_graph_paged currently materializes and sorts all matching nodes across all graphs before applying offset/limit; if match sets are large this can still be expensive, so consider an approach that skips the first `offset` matches on the fly and only stores up to `limit` items (e.g., streaming iteration with a bounded buffer or a selection algorithm) to reduce memory and sort cost.
- count_matching_nodes traverses all graphs a second time when total() is true, duplicating the filter work done in collect_graph_paged; if totals are requested frequently, it might be worth sharing the traversal (e.g., counting while collecting) or caching counts to avoid an extra full pass over all node indices.

## Individual Comments

### Comment 1
<location path="modules/analysis/src/service/mod.rs" line_range="524-533" />
<code_context>
     }

+    /// Count nodes matching the query across all graphs, without hydrating them.
+    fn count_matching_nodes(query: &GraphQuery, graphs: &[(Uuid, Arc<PackageGraph>)]) -> u64 {
+        graphs
+            .iter()
+            .map(|(_, graph)| {
+                graph
+                    .node_indices()
+                    .filter(|&i| Self::filter(graph, query, i))
+                    .count() as u64
+            })
+            .sum()
+    }
+
</code_context>
<issue_to_address>
**suggestion (performance):** Avoid double iteration when computing totals for paginated queries to reduce cost on large graphs

When `paginated.total()` is true, this now walks all graphs twice: once in `count_matching_nodes`, and again in `collect_graph_paged` to build the page. On large graphs this doubles the dominant cost. Consider deriving the total from the same `matching` sequence used in `collect_graph_paged` (e.g., via a shared helper that returns both `items` and `total`, or by having `collect_graph_paged` optionally compute/return the total) so you only traverse and filter the nodes once per request.

Suggested implementation:

```rust
            })
    }

```

To fully adopt the "single traversal" approach and remove the double walk:

1. Locate the function that builds paginated results (likely named something like `collect_graph_paged` or similar) in `modules/analysis/src/service/mod.rs`.
2. Remove its dependency on `count_matching_nodes`:
   - Delete any calls to `Self::count_matching_nodes(query, graphs)` (or similar).
3. In the body of `collect_graph_paged`, where you currently iterate over graphs/nodes to produce the `items` for the current page:
   - Introduce a `total` counter initialized to `0u64`.
   - For each node that passes `Self::filter(graph, query, i)`:
     - Increment `total` by 1.
     - Apply pagination (offset/limit) logic to decide whether to push that node into the `items` collection.
   - This way, you build the page and the total in the same loop.
4. Update the return type or construction of the paginated response:
   - If the API allows, have `collect_graph_paged` return both `items` and `total` (or construct a struct that contains both) so callers can access the total without an extra traversal.
   - Only compute/attach `total` when `paginated.total()` (or equivalent flag) is true, to avoid unnecessary counting when totals are not requested.
5. Ensure there are no remaining references to `count_matching_nodes` anywhere in the codebase; if there are, update them to use the new "single traversal" logic described above.

These changes will ensure that totals for paginated queries are derived during the same pass that builds the page, avoiding the double iteration and associated cost on large graphs.
</issue_to_address>

### Comment 2
<location path="modules/analysis/src/service/mod.rs" line_range="575-580" />
<code_context>
+
+        let matching: Vec<_> = matching.into_iter().skip(offset).take(limit).collect();
+
+        stream::iter(matching)
+            .map(|(graph, node_index, package_node)| {
+                let create = create.clone();
+                create(graph, node_index, package_node)
+            })
+            .buffer_unordered(concurrency)
+            .try_collect::<Vec<_>>()
+            .await
</code_context>
<issue_to_address>
**issue (bug_risk):** Using `buffer_unordered` may break deterministic ordering of nodes within a page

`buffer_unordered` can change the order of results based on completion timing, so the final `Vec` may no longer be sorted by `(sbom_id, node_id)`. If callers depend on stable pagination (consistent page contents or resuming by offset), this non-determinism could cause subtle bugs. Consider using `buffered` or re-sorting after collection to retain deterministic ordering while still leveraging concurrency.
</issue_to_address>

### Comment 3
<location path="modules/analysis/src/service/load/mod.rs" line_range="457-459" />
<code_context>
     ) -> Result<Vec<(Uuid, Arc<PackageGraph>)>, Error> {
         let distinct_sbom_ids = sbom::Entity::find()
             .filter(sbom::Column::SbomId.in_subquery(subquery))
+            .order_by_asc(sbom::Column::SbomId)
             .select()
             .all(connection)
</code_context>
<issue_to_address>
**suggestion (performance):** Ordering by `SbomId` at the database layer may have indexing implications

This adds deterministic ordering but may introduce an extra sort on the DB side if there’s no index on `SbomId` (or if it doesn’t match the PK/index). Please check whether an appropriate index exists or whether this ordering can reuse an existing one. If not, and the number of `distinct_sbom_ids` is usually small, consider sorting client-side instead.

Suggested implementation:

```rust
    ) -> Result<Vec<(Uuid, Arc<PackageGraph>)>, Error> {
        // Fetch distinct_sbom_ids without imposing a DB-side sort; we sort client-side below.
        let mut distinct_sbom_ids = sbom::Entity::find()
            .filter(sbom::Column::SbomId.in_subquery(subquery))
            .select()
            .all(connection)
            .await?;

        // Ensure deterministic ordering by sorting in memory by SbomId.
        distinct_sbom_ids.sort_by_key(|model| model.sbom_id);

```

1. This change assumes the SeaORM model for the `sbom` table exposes the primary key/column as `sbom_id`. If the field name differs (e.g. `sbom_id` is nested or renamed), adjust the closure in `sort_by_key` accordingly.
2. If `distinct_sbom_ids` is later used as an iterator or converted into another structure (e.g. mapping to `(Uuid, Arc<PackageGraph>)`), no other changes should be needed, since the vector is now deterministically ordered before subsequent processing.
</issue_to_address>

### Comment 4
<location path="modules/analysis/src/service/test/mod.rs" line_range="976-985" />
<code_context>
+async fn test_pagination_cross_graph(ctx: &TrustifyContext) -> Result<(), anyhow::Error> {
</code_context>
<issue_to_address>
**issue (testing):** The uniqueness check only uses `sbom_id`, which may be too coarse and can make the test misleading or flaky if multiple matches exist in the same SBOM.

This test currently deduplicates only by `sbom_id`:

```rust
let unique: std::collections::HashSet<_> = collected_sbom_ids.iter().collect();
assert_eq!(unique.len(), total, "no duplicate items across pages");
```

If multiple nodes from the same SBOM match, this will incorrectly treat distinct items as duplicates and can both fail valid pagination and miss true `(sbom_id, node_id)` duplicates.

To better assert "no duplicate items, no gaps", collect and deduplicate on `(sbom_id, node_id)` instead, e.g.:

```rust
let mut collected = Vec::new();
...
collected.push((item.base.sbom_id.clone(), item.base.node_id.clone()));
...
let unique: HashSet<_> = collected.iter().cloned().collect();
assert_eq!(unique.len(), total);
```

This makes the test robust when multiple nodes per SBOM are returned.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +524 to +533
fn count_matching_nodes(query: &GraphQuery, graphs: &[(Uuid, Arc<PackageGraph>)]) -> u64 {
graphs
.iter()
.map(|(_, graph)| {
graph
.node_indices()
.filter(|&i| Self::filter(graph, query, i))
.count() as u64
})
.sum()

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.

suggestion (performance): Avoid double iteration when computing totals for paginated queries to reduce cost on large graphs

When paginated.total() is true, this now walks all graphs twice: once in count_matching_nodes, and again in collect_graph_paged to build the page. On large graphs this doubles the dominant cost. Consider deriving the total from the same matching sequence used in collect_graph_paged (e.g., via a shared helper that returns both items and total, or by having collect_graph_paged optionally compute/return the total) so you only traverse and filter the nodes once per request.

Suggested implementation:

            })
    }

To fully adopt the "single traversal" approach and remove the double walk:

  1. Locate the function that builds paginated results (likely named something like collect_graph_paged or similar) in modules/analysis/src/service/mod.rs.
  2. Remove its dependency on count_matching_nodes:
    • Delete any calls to Self::count_matching_nodes(query, graphs) (or similar).
  3. In the body of collect_graph_paged, where you currently iterate over graphs/nodes to produce the items for the current page:
    • Introduce a total counter initialized to 0u64.
    • For each node that passes Self::filter(graph, query, i):
      • Increment total by 1.
      • Apply pagination (offset/limit) logic to decide whether to push that node into the items collection.
    • This way, you build the page and the total in the same loop.
  4. Update the return type or construction of the paginated response:
    • If the API allows, have collect_graph_paged return both items and total (or construct a struct that contains both) so callers can access the total without an extra traversal.
    • Only compute/attach total when paginated.total() (or equivalent flag) is true, to avoid unnecessary counting when totals are not requested.
  5. Ensure there are no remaining references to count_matching_nodes anywhere in the codebase; if there are, update them to use the new "single traversal" logic described above.

These changes will ensure that totals for paginated queries are derived during the same pass that builds the page, avoiding the double iteration and associated cost on large graphs.

Comment on lines +575 to +580
stream::iter(matching)
.map(|(graph, node_index, package_node)| {
let create = create.clone();
create(graph, node_index, package_node)
})
.buffer_unordered(concurrency)

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.

issue (bug_risk): Using buffer_unordered may break deterministic ordering of nodes within a page

buffer_unordered can change the order of results based on completion timing, so the final Vec may no longer be sorted by (sbom_id, node_id). If callers depend on stable pagination (consistent page contents or resuming by offset), this non-determinism could cause subtle bugs. Consider using buffered or re-sorting after collection to retain deterministic ordering while still leveraging concurrency.

Comment on lines 457 to +459
let distinct_sbom_ids = sbom::Entity::find()
.filter(sbom::Column::SbomId.in_subquery(subquery))
.order_by_asc(sbom::Column::SbomId)

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.

suggestion (performance): Ordering by SbomId at the database layer may have indexing implications

This adds deterministic ordering but may introduce an extra sort on the DB side if there’s no index on SbomId (or if it doesn’t match the PK/index). Please check whether an appropriate index exists or whether this ordering can reuse an existing one. If not, and the number of distinct_sbom_ids is usually small, consider sorting client-side instead.

Suggested implementation:

    ) -> Result<Vec<(Uuid, Arc<PackageGraph>)>, Error> {
        // Fetch distinct_sbom_ids without imposing a DB-side sort; we sort client-side below.
        let mut distinct_sbom_ids = sbom::Entity::find()
            .filter(sbom::Column::SbomId.in_subquery(subquery))
            .select()
            .all(connection)
            .await?;

        // Ensure deterministic ordering by sorting in memory by SbomId.
        distinct_sbom_ids.sort_by_key(|model| model.sbom_id);
  1. This change assumes the SeaORM model for the sbom table exposes the primary key/column as sbom_id. If the field name differs (e.g. sbom_id is nested or renamed), adjust the closure in sort_by_key accordingly.
  2. If distinct_sbom_ids is later used as an iterator or converted into another structure (e.g. mapping to (Uuid, Arc<PackageGraph>)), no other changes should be needed, since the vector is now deterministically ordered before subsequent processing.

Comment on lines +976 to +985
async fn test_pagination_cross_graph(ctx: &TrustifyContext) -> Result<(), anyhow::Error> {
ctx.ingest_documents([
"spdx/quarkus-bom-3.2.11.Final-redhat-00001.json",
"spdx/quarkus-bom-3.2.12.Final-redhat-00002.json",
])
.await?;

let service = AnalysisService::new(AnalysisConfig::default(), ReadOnly::new(ctx.db.clone()));

// Given: a query that matches nodes across both SBOMs

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.

issue (testing): The uniqueness check only uses sbom_id, which may be too coarse and can make the test misleading or flaky if multiple matches exist in the same SBOM.

This test currently deduplicates only by sbom_id:

let unique: std::collections::HashSet<_> = collected_sbom_ids.iter().collect();
assert_eq!(unique.len(), total, "no duplicate items across pages");

If multiple nodes from the same SBOM match, this will incorrectly treat distinct items as duplicates and can both fail valid pagination and miss true (sbom_id, node_id) duplicates.

To better assert "no duplicate items, no gaps", collect and deduplicate on (sbom_id, node_id) instead, e.g.:

let mut collected = Vec::new();
...
collected.push((item.base.sbom_id.clone(), item.base.node_id.clone()));
...
let unique: HashSet<_> = collected.iter().cloned().collect();
assert_eq!(unique.len(), total);

This makes the test robust when multiple nodes per SBOM are returned.

@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.95960% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.62%. Comparing base (7a07281) to head (28243b7).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
modules/analysis/src/service/mod.rs 95.91% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2446      +/-   ##
==========================================
+ Coverage   71.52%   71.62%   +0.10%     
==========================================
  Files         453      453              
  Lines       27363    27462      +99     
  Branches    27363    27462      +99     
==========================================
+ Hits        19572    19671      +99     
+ Misses       6668     6660       -8     
- Partials     1123     1131       +8     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ctron ctron added the backport release/0.5.z Backport (0.5.z) label Jul 3, 2026
@rh-jfuller

Copy link
Copy Markdown
Contributor

/scale-test

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown

🛠️ Scale test has started! Follow the progress here: Workflow Run

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Goose Report

Goose Attack Report

Plan Overview

Action Started Stopped Elapsed Users
Increasing 26-07-03 12:26:42 26-07-03 12:26:49 00:00:07 0 → 7
Maintaining 26-07-03 12:26:49 26-07-03 12:56:49 00:30:00 7
Decreasing 26-07-03 12:56:49 26-07-03 12:56:52 00:00:03 0 ← 7

Request Metrics

Method Name # Requests # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
GET /.well-known/trustify 435 (+80) 0 2.11 (-1.47) 1 (0) 46 (+10) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/advisory 432 (+77) 0 59.53 (+29.83) 6 (+1) 176 (+34) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/advisory?deprecated=Consider 435 (+80) 0 67.74 (+25.00) 6 (+2) 211 (+63) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/advisory?offset=100&limit=10 432 (+77) 0 71.01 (+38.39) 9 (+1) 446 (+354) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/advisory?q=CVE-2021- 433 (+78) 0 490.14 (+324.09) 8 (+1) 4870 (+3288) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/advisory?q=identifier%3dCVE-2022-0981 432 (+77) 0 18.30 (+7.01) 2 (0) 80 (+31) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/advisory?q=modified>3 days ago 435 (+80) 0 10.41 (+1.93) 2 (0) 70 (+19) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/advisory?q=title~openssl 435 (+80) 0 53.28 (-288.90) 9 (-14) 167 (-917) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/advisory?sort=modified:desc 435 (+80) 0 31.88 (-1.41) 5 (0) 155 (+49) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/group/sbom 435 (+80) 0 5.56 (+1.04) 1 (0) 60 (+13) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/group/sbom?parents=resolve 434 (+79) 0 5.64 (+2.08) 1 (0) 48 (+6) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/group/sbom?totals=true 434 (+79) 0 4.98 (+1.73) 1 (0) 49 (+10) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/importer 433 (+78) 0 12.04 (+1.44) 1 (0) 69 (+13) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/license 435 (+80) 0 12.99 (-1.38) 2 (0) 65 (-27) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/license/spdx/license 435 (+80) 0 1.42 (+0.12) 1 (0) 32 (+21) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/license/spdx/license?q=apache 31498 (-13678) 0 1.10 (+0.11) 1 (0) 46 (-1) 17.50 (-7.60) 0.00 (+0.00)
GET /api/v3/license/spdx/license?q=gpl 31498 (-13679) 0 1.03 (+0.20) 1 (0) 61 (+10) 17.50 (-7.60) 0.00 (+0.00)
GET /api/v3/license?q=ASL&sort=license:desc 31499 (-13678) 0 14.48 (+6.00) 1 (0) 174 (-34) 17.50 (-7.60) 0.00 (+0.00)
GET /api/v3/license?q=license~Apache 31498 (-13679) 0 6.63 (+2.36) 1 (0) 85 (-274) 17.50 (-7.60) 0.00 (+0.00)
GET /api/v3/license?q=license~GPL 31498 (-13678) 0 6.85 (+2.47) 1 (0) 389 (+304) 17.50 (-7.60) 0.00 (+0.00)
GET /api/v3/organization 432 (+77) 0 9.91 (+3.95) 1 (0) 49 (-15) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/organization?sort=name:asc 434 (+79) 0 8.41 (+0.97) 1 (0) 56 (-1) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/product 433 (+77) 0 9.67 (+4.18) 1 (-1) 58 (+18) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/product?q=name~openshift 434 (+79) 0 13.54 (+2.35) 2 (0) 91 (+11) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/product?sort=name:asc 434 (+79) 0 15.25 (+5.11) 2 (0) 71 (+17) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/purl 433 (+78) 0 6.52 (+2.46) 1 (0) 51 (+5) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/purl/base 435 (+80) 0 7.63 (-0.45) 1 (0) 74 (+15) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/purl/base?q=namespace=redhat 434 (+79) 0 7.78 (+2.05) 1 (0) 66 (+24) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/purl/base?q=type=rpm 434 (+79) 0 7.22 (+1.70) 1 (0) 61 (+18) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/purl/base?sort=name:asc 434 (+79) 0 219.43 (+77.76) 48 (+17) 739 (+451) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/purl?offset=100&limit=10 433 (+78) 0 5.80 (+2.56) 1 (0) 48 (+28) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/purl?q=curl 433 (+77) 0 25.74 (-6137.24) 3 (-971) 96 (-15644) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/purl?q=license~GPLv3+ with exceptions Apache&sort=name:desc 31498 (-13679) 0 5.39 (+2.01) 1 (0) 101 (+22) 17.50 (-7.60)
GET /api/v3/purl?q=name=curl 433 (+77) 0 8.93 (-25.07) 1 (-8) 61 (-125) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/purl?q=purl:namespace=redhat 434 (+79) 0 6.34 (+0.42) 1 (0) 49 (+4) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/purl?q=purl:ty=rpm 434 (+79) 0 8.10 (+0.70) 2 (0) 56 (-2) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/purl?sort=purl:name:asc 434 (+79) 0 8.95 (-0.43) 2 (+1) 57 (-2) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/sbom 866 (+154) 0 238.30 (+105.58) 62 (+2) 831 (+159) 0.48 (+0.09) 0.00 (+0.00)
GET /api/v3/sbom-labels 435 (+80) 0 36.51 (+6.82) 5 (-1) 100 (+10) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/sbom?offset=100&limit=10 866 (+159) 0 235.45 (+101.64) 41 (-4) 1060 (+647) 0.48 (+0.09) 0.00 (+0.00)
GET /api/v3/sbom?q=label:type=product 435 (+80) 0 11.83 (+4.44) 1 (0) 58 (-11) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/sbom?q=license~GPL&sort=name:desc 31498 (-13679) 0 6.72 (+2.56) 1 (0) 163 (+64) 17.50 (-7.60) 0.00 (+0.00)
GET /api/v3/sbom?q=name~redhat 435 (+80) 0 206.76 (-10.34) 10 (-2) 1294 (+713) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/sbom?q=published>2024-01-01 435 (+80) 0 293.44 (+138.15) 60 (+1) 774 (+324) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/sbom?sort=ingested:desc 435 (+80) 0 213.43 (+64.52) 38 (+10) 599 (+199) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/vulnerability 433 (+78) 0 11.79 (+5.32) 2 (0) 99 (+37) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/vulnerability?offset=100&limit=10 433 (+78) 0 10.50 (+4.18) 1 (-1) 279 (+222) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/vulnerability?q=base_score>=7.0 435 (+80) 0 15.43 (+4.40) 2 (0) 118 (-105) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/vulnerability?q=base_severity=high 435 (+80) 0 22.07 (+7.54) 2 (0) 422 (+240) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/vulnerability?q=cwes=CWE-79 435 (+80) 0 20.46 (+6.52) 2 (0) 201 (+110) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/vulnerability?sort=base_score:desc 435 (+80) 0 845.45 (+208.73) 220 (+79) 3322 (+2240) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/weakness 435 (+80) 0 8.81 (+0.88) 1 (0) 54 (+3) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/weakness?q=description~injection 434 (+79) 0 6.96 (+2.57) 1 (0) 55 (+13) 0.24 (+0.04) 0.00 (+0.00)
GET /api/v3/weakness?sort=id:asc 434 (+79) 0 6.60 (+2.05) 1 (0) 58 (+4) 0.24 (+0.04) 0.00 (+0.00)
GET count_sbom_by_package[pkg:oci/web-ter…=1.15-1770672845] 432 (+77) 0 17.75 (+4.04) 3 (+1) 74 (+10) 0.24 (+0.04) 0.00 (+0.00)
GET download_advisory[f1e5eb17-2f31-4…b46-c11f52398375] 432 (+77) 432 17.37 (+4.33) 2 (0) 91 (+16) 0.24 (+0.04) 0.24 (+0.04)
GET download_sbom[sha256:a04260d9…a6046a828fcd17e5] 432 (+77) 432 132.09 (+61.97) 26 (+7) 524 (-4) 0.24 (+0.04) 0.24 (+0.04)
GET get_advisory[f1e5eb17-2f31-4…b46-c11f52398375] 432 (+77) 0 14.78 (+3.89) 1 (0) 79 (-37) 0.24 (+0.04) 0.00 (+0.00)
GET get_base_purl[pkg:golang/k8s.…d/golang/reflect] 432 (+77) 0 64.33 (-0.36) 5 (+1) 487 (+267) 0.24 (+0.04) 0.00 (+0.00)
GET get_organization[53d3fae7-574a-4…66b-5a704e8b289a] 432 (+77) 0 358.34 (+79.90) 99 (+45) 1341 (+744) 0.24 (+0.04) 0.00 (+0.00)
GET get_product[761f2bc9-f3a4-5…ee5-fd2aa3aef38b] 432 (+77) 0 14.03 (+2.56) 2 (+1) 83 (-27) 0.24 (+0.04) 0.00 (+0.00)
GET get_purl_details[00001592-edf0-5…ed9-396e8c9d149f] 432 (+77) 0 611.07 (+147.88) 198 (+114) 1485 (+682) 0.24 (+0.04) 0.00 (+0.00)
GET get_sbom[sha256:a04260d9…a6046a828fcd17e5] 434 (+79) 0 145.14 (+70.88) 26 (+6) 387 (+123) 0.24 (+0.04) 0.00 (+0.00)
GET get_sbom_license_export[urn:uuid:019cf0…76e-43a3bfd8a2f5] 432 (+77) 0 21.16 (+5.16) 1 (0) 95 (-353) 0.24 (+0.04) 0.00 (+0.00)
GET get_sbom_license_ids[urn:uuid:019cf0…76e-43a3bfd8a2f5] 433 (+78) 0 12.90 (+3.66) 1 (0) 74 (+18) 0.24 (+0.04) 0.00 (+0.00)
GET get_spdx_license[MIT] 432 (+77) 0 1.81 (-0.79) 1 (0) 17 (0) 0.24 (+0.04) 0.00 (+0.00)
GET list_advisory_labels 437 (+82) 0 13383.55 (-505.67) 5794 (+763) 26976 (+7985) 0.24 (+0.05) 0.00 (+0.00)
GET sbom_by_package[pkg:oci/web-ter…=1.15-1770672845] 434 (+79) 0 90.96 (+35.73) 18 (+9) 678 (+298) 0.24 (+0.04) 0.00 (+0.00)
POST get_recommendations[batch=10] 1296 (+231) 0 151.73 (+54.87) 22 (+5) 961 (+431) 0.72 (+0.13) 0.00 (+0.00)
POST post_extract_sbom_purls 435 (+80) 0 2.40 (-1.69) 1 (0) 34 (-13) 0.24 (+0.04) 0.00 (+0.00)
POST post_vulnerability_analyze[pkg:rpm/redhat/squid] 433 (+78) 0 6.57 (+2.96) 1 (0) 63 (+21) 0.24 (+0.04) 0.00 (+0.00)
POST post_vulnerability_analyze_v3 435 (+80) 0 1429.38 (+343.16) 315 (+98) 3597 (+1196) 0.24 (+0.04) 0.00 (+0.00)
Aggregated 250408 (-90326) 864 41.26 (+11.38) 1 (0) 26976 (+7985) 139.12 (-50.18) 0.48 (+0.09)

Response Time Metrics

Method Name 50%ile (ms) 60%ile (ms) 70%ile (ms) 80%ile (ms) 90%ile (ms) 95%ile (ms) 99%ile (ms) 100%ile (ms)
GET /.well-known/trustify 1 (0) 1 (-1) 2 (-1) 2 (-1) 4 (-2) 6 (-13) 23 (-8) 46 (+10)
GET /api/v3/advisory 55 (+27) 66 (+36) 75 (+42) 83 (+44) 94 (+44) 100 (+37) 150 (+73) 176 (+36)
GET /api/v3/advisory?deprecated=Consider 73 (+35) 77 (+35) 83 (+33) 88 (+30) 97 (+24) 110 (+30) 130 (+31) 210 (+62)
GET /api/v3/advisory?offset=100&limit=10 69 (+39) 80 (+47) 89 (+53) 97 (+57) 110 (+64) 120 (+66) 170 (+90) 446 (+354)
GET /api/v3/advisory?q=CVE-2021- 190 (+130) 270 (+193) 390 (+280) 600 (+450) 1,000 (+500) 2,000 (+1,000) 4,000 (+3,000) 4,870 (+3,288)
GET /api/v3/advisory?q=identifier%3dCVE-2022-0981 12 (+3) 15 (+5) 18 (+6) 25 (+11) 49 (+29) 58 (+30) 73 (+33) 80 (+31)
GET /api/v3/advisory?q=modified>3 days ago 7 (0) 8 (+1) 10 (+1) 13 (+2) 21 (+6) 36 (+12) 57 (+14) 70 (+19)
GET /api/v3/advisory?q=title~openssl 53 (-207) 59 (-261) 65 (-335) 71 (-529) 81 (-719) 92 (-808) 140 (-860) 167 (-833)
GET /api/v3/advisory?sort=modified:desc 21 (-13) 28 (-11) 39 (-5) 54 (+1) 68 (+2) 76 (+1) 95 (+5) 155 (+49)
GET /api/v3/group/sbom 3 (0) 3 (0) 4 (0) 6 (0) 9 (0) 28 (+14) 46 (+11) 60 (+13)
GET /api/v3/group/sbom?parents=resolve 3 (+1) 3 (0) 4 (+1) 6 (+2) 11 (+6) 28 (+20) 44 (+14) 48 (+6)
GET /api/v3/group/sbom?totals=true 3 (0) 3 (0) 4 (+1) 5 (+1) 9 (+4) 19 (+13) 43 (+18) 49 (+10)
GET /api/v3/importer 8 (-1) 11 (+1) 13 (+2) 17 (+5) 31 (+15) 45 (+22) 62 (+17) 69 (+13)
GET /api/v3/license 9 (0) 11 (0) 13 (0) 16 (-1) 36 (-5) 44 (-5) 53 (-8) 65 (-27)
GET /api/v3/license/spdx/license 1 (0) 1 (0) 1 (0) 1 (0) 2 (0) 6 (+2) 11 (+3) 32 (+21)
GET /api/v3/license/spdx/license?q=apache 1 (0) 1 (0) 1 (0) 1 (0) 1 (0) 2 (0) 3 (0) 46 (-1)
GET /api/v3/license/spdx/license?q=gpl 1 (0) 1 (0) 1 (0) 1 (0) 1 (0) 1 (0) 3 (+1) 61 (+10)
GET /api/v3/license?q=ASL&sort=license:desc 5 (+2) 7 (+4) 13 (+8) 36 (+28) 42 (+7) 46 (+4) 54 (+3) 170 (-38)
GET /api/v3/license?q=license~Apache 3 (+1) 4 (+2) 5 (+2) 6 (+2) 12 (+5) 39 (+27) 53 (+5) 85 (-274)
GET /api/v3/license?q=license~GPL 3 (+1) 4 (+2) 5 (+2) 7 (+3) 12 (+5) 41 (+28) 52 (+3) 389 (+304)
GET /api/v3/organization 4 (+1) 5 (+1) 8 (+4) 17 (+10) 33 (+18) 37 (+14) 46 (+8) 49 (-15)
GET /api/v3/organization?sort=name:asc 5 (0) 6 (0) 8 (+1) 10 (+2) 17 (+4) 41 (+13) 52 (+3) 56 (-1)
GET /api/v3/product 6 (+1) 7 (+2) 9 (+3) 12 (+5) 23 (+15) 40 (+31) 51 (+40) 58 (+18)
GET /api/v3/product?q=name~openshift 8 (0) 9 (+1) 11 (+1) 17 (+5) 41 (+12) 49 (+8) 59 (+8) 91 (+11)
GET /api/v3/product?sort=name:asc 9 (+2) 11 (+3) 14 (+5) 19 (+8) 46 (+29) 52 (+13) 59 (+12) 71 (+17)
GET /api/v3/purl 4 (+1) 4 (+1) 6 (+2) 8 (+3) 11 (+4) 22 (+13) 46 (+25) 51 (+5)
GET /api/v3/purl/base 4 (+1) 4 (0) 6 (+1) 8 (0) 20 (-14) 39 (+1) 52 (+3) 74 (+15)
GET /api/v3/purl/base?q=namespace=redhat 3 (-1) 4 (0) 6 (+1) 9 (+3) 21 (+11) 36 (+12) 49 (+12) 66 (+24)
GET /api/v3/purl/base?q=type=rpm 4 (+1) 4 (0) 6 (+1) 8 (+2) 16 (+7) 33 (+12) 48 (+9) 61 (+18)
GET /api/v3/purl/base?sort=name:asc 200 (+40) 220 (+50) 240 (+60) 270 (+80) 310 (+110) 410 (+190) 600 (+340) 700 (+412)
GET /api/v3/purl?offset=100&limit=10 3 (0) 4 (+1) 5 (+1) 7 (+3) 11 (+5) 20 (+13) 41 (+30) 48 (+28)
GET /api/v3/purl?q=curl 20 (-6,980) 23 (-6,977) 27 (-6,973) 41 (-6,959) 54 (-6,946) 64 (-6,936) 79 (-7,921) 96 (-15,644)
GET /api/v3/purl?q=license~GPLv3+ with exceptions Apache&sort=name:desc 2 (0) 3 (+1) 4 (+2) 5 (+2) 10 (+5) 35 (+26) 51 (+5)
GET /api/v3/purl?q=name=curl 6 (-31) 8 (-29) 9 (-29) 11 (-28) 16 (-26) 32 (-11) 47 (-1) 61 (-125)
GET /api/v3/purl?q=purl:namespace=redhat 4 (0) 5 (+1) 5 (0) 7 (+1) 10 (+1) 24 (+2) 45 (+6) 49 (+4)
GET /api/v3/purl?q=purl:ty=rpm 5 (0) 5 (0) 7 (+1) 9 (+2) 15 (+4) 40 (+6) 50 (+2) 56 (-2)
GET /api/v3/purl?sort=purl:name:asc 5 (-1) 7 (-1) 9 (0) 12 (+1) 19 (+1) 35 (-1) 47 (0) 57 (-2)
GET /api/v3/sbom 200 (+70) 240 (+110) 290 (+150) 340 (+190) 430 (+260) 500 (+320) 600 (+380) 800 (+128)
GET /api/v3/sbom-labels 29 (+5) 35 (+8) 50 (+13) 61 (+10) 71 (+8) 78 (+8) 89 (+12) 100 (+10)
GET /api/v3/sbom?offset=100&limit=10 220 (+100) 260 (+120) 290 (+120) 320 (+130) 390 (+180) 420 (+200) 500 (+250) 1,000 (+590)
GET /api/v3/sbom?q=label:type=product 6 (0) 7 (0) 9 (+1) 13 (+4) 40 (+26) 45 (+28) 53 (+24) 58 (-11)
GET /api/v3/sbom?q=license~GPL&sort=name:desc 2 (0) 3 (+1) 4 (+2) 6 (+2) 15 (+9) 39 (+24) 51 (+5) 160 (+61)
GET /api/v3/sbom?q=name~redhat 89 (-191) 110 (-190) 160 (-170) 410 (+60) 600 (+210) 800 (+360) 1,000 (+500) 1,000 (+419)
GET /api/v3/sbom?q=published>2024-01-01 290 (+140) 320 (+160) 360 (+190) 400 (+200) 480 (+260) 500 (+230) 600 (+290) 774 (+324)
GET /api/v3/sbom?sort=ingested:desc 200 (+30) 210 (+30) 260 (+80) 300 (+100) 380 (+160) 420 (+180) 599 (+299) 599 (+199)
GET /api/v3/vulnerability 6 (+1) 8 (+2) 10 (+4) 14 (+7) 33 (+24) 46 (+32) 60 (+22) 99 (+37)
GET /api/v3/vulnerability?offset=100&limit=10 6 (+1) 7 (+1) 8 (+2) 11 (+4) 20 (+10) 39 (+25) 61 (+28) 279 (+222)
GET /api/v3/vulnerability?q=base_score>=7.0 9 (+1) 11 (+2) 14 (+4) 20 (+7) 40 (+22) 52 (+27) 80 (+13) 118 (-102)
GET /api/v3/vulnerability?q=base_severity=high 11 (+1) 14 (+3) 19 (+5) 29 (+11) 49 (+20) 60 (+22) 190 (+119) 420 (+240)
GET /api/v3/vulnerability?q=cwes=CWE-79 12 (+2) 14 (+2) 19 (+5) 30 (+12) 48 (+21) 59 (+21) 120 (+62) 200 (+109)
GET /api/v3/vulnerability?sort=base_score:desc 800 (+100) 800 (0) 900 (+100) 1,000 (+200) 1,000 (+100) 2,000 (+1,000) 2,000 (+1,000) 3,000 (+2,000)
GET /api/v3/weakness 4 (0) 4 (0) 6 (0) 10 (+2) 34 (+5) 41 (+2) 50 (+6) 54 (+3)
GET /api/v3/weakness?q=description~injection 4 (+1) 5 (+1) 6 (+2) 8 (+3) 15 (+7) 29 (+19) 48 (+16) 55 (+13)
GET /api/v3/weakness?sort=id:asc 4 (+1) 4 (0) 5 (+1) 7 (+2) 14 (+7) 28 (+17) 44 (+13) 58 (+4)
GET count_sbom_by_package[pkg:oci/web-ter…=1.15-1770672845] 12 (+3) 14 (+3) 18 (+5) 24 (+6) 44 (+8) 51 (+9) 69 (+14) 74 (+10)
GET download_advisory[f1e5eb17-2f31-4…b46-c11f52398375] 11 (+2) 14 (+3) 18 (+5) 26 (+9) 44 (+12) 52 (+12) 71 (+20) 91 (+16)
GET download_sbom[sha256:a04260d9…a6046a828fcd17e5] 120 (+60) 130 (+62) 170 (+93) 190 (+95) 210 (+90) 270 (+110) 360 (+100) 500 (0)
GET get_advisory[f1e5eb17-2f31-4…b46-c11f52398375] 9 (+2) 11 (+2) 14 (+3) 20 (+7) 44 (+16) 49 (+13) 64 (+15) 79 (-37)
GET get_base_purl[pkg:golang/k8s.…d/golang/reflect] 33 (-22) 55 (-23) 70 (-27) 120 (0) 170 (+30) 190 (+20) 280 (+80) 487 (+267)
GET get_organization[53d3fae7-574a-4…66b-5a704e8b289a] 330 (+20) 360 (+30) 380 (+30) 410 (+40) 500 (+110) 600 (+190) 800 (+320) 1,000 (+403)
GET get_product[761f2bc9-f3a4-5…ee5-fd2aa3aef38b] 8 (+1) 10 (+1) 13 (+1) 19 (+3) 39 (+11) 49 (+12) 69 (+16) 83 (-27)
GET get_purl_details[00001592-edf0-5…ed9-396e8c9d149f] 600 (+100) 600 (0) 700 (+100) 700 (+100) 900 (+300) 1,000 (+300) 1,000 (+300) 1,000 (+200)
GET get_sbom[sha256:a04260d9…a6046a828fcd17e5] 140 (+70) 160 (+84) 180 (+97) 200 (+105) 230 (+110) 270 (+120) 350 (+160) 387 (+127)
GET get_sbom_license_export[urn:uuid:019cf0…76e-43a3bfd8a2f5] 13 (+5) 16 (+6) 24 (+10) 42 (+23) 52 (+16) 59 (+15) 77 (+13) 95 (-353)
GET get_sbom_license_ids[urn:uuid:019cf0…76e-43a3bfd8a2f5] 7 (+1) 9 (+2) 11 (+3) 16 (+5) 40 (+18) 47 (+13) 63 (+14) 74 (+18)
GET get_spdx_license[MIT] 1 (0) 1 (-1) 2 (-1) 3 (0) 4 (-2) 6 (-3) 10 (-4) 17 (0)
GET list_advisory_labels 13,000 (0) 13,000 (-1,000) 14,000 (0) 15,000 (0) 16,000 (-2,000) 21,000 (+3,000) 26,000 (+7,009) 26,976 (+7,985)
GET sbom_by_package[pkg:oci/web-ter…=1.15-1770672845] 82 (+38) 92 (+37) 100 (+35) 120 (+39) 160 (+60) 200 (+70) 320 (+120) 678 (+298)
POST get_recommendations[batch=10] 120 (+55) 150 (+72) 180 (+84) 210 (+60) 280 (+40) 380 (+90) 500 (+110) 961 (+461)
POST post_extract_sbom_purls 1 (-1) 1 (-1) 2 (-1) 3 (-1) 4 (-3) 9 (-15) 22 (-12) 34 (-13)
POST post_vulnerability_analyze[pkg:rpm/redhat/squid] 3 (+1) 3 (0) 5 (+2) 7 (+3) 14 (+8) 36 (+27) 50 (+21) 63 (+21)
POST post_vulnerability_analyze_v3 1,000 (0) 2,000 (+1,000) 2,000 (0) 2,000 (0) 2,000 (0) 3,000 (+1,000) 3,000 (+1,000) 3,597 (+1,597)
Aggregated 2 (0) 3 (+1) 5 (+2) 8 (+4) 36 (+27) 50 (+12) 390 (+220) 26,976 (+7,985)

Status Code Metrics

Method Name Status Codes
GET /.well-known/trustify 435 [200]
GET /api/v3/advisory 432 [200]
GET /api/v3/advisory?deprecated=Consider 435 [200]
GET /api/v3/advisory?offset=100&limit=10 432 [200]
GET /api/v3/advisory?q=CVE-2021- 433 [200]
GET /api/v3/advisory?q=identifier%3dCVE-2022-0981 432 [200]
GET /api/v3/advisory?q=modified>3 days ago 435 [200]
GET /api/v3/advisory?q=title~openssl 435 [200]
GET /api/v3/advisory?sort=modified:desc 435 [200]
GET /api/v3/group/sbom 435 [200]
GET /api/v3/group/sbom?parents=resolve 434 [200]
GET /api/v3/group/sbom?totals=true 434 [200]
GET /api/v3/importer 433 [200]
GET /api/v3/license 435 [200]
GET /api/v3/license/spdx/license 435 [200]
GET /api/v3/license/spdx/license?q=apache 31,498 [200]
GET /api/v3/license/spdx/license?q=gpl 31,498 [200]
GET /api/v3/license?q=ASL&sort=license:desc 31,499 [200]
GET /api/v3/license?q=license~Apache 31,498 [200]
GET /api/v3/license?q=license~GPL 31,498 [200]
GET /api/v3/organization 432 [200]
GET /api/v3/organization?sort=name:asc 434 [200]
GET /api/v3/product 433 [200]
GET /api/v3/product?q=name~openshift 434 [200]
GET /api/v3/product?sort=name:asc 434 [200]
GET /api/v3/purl 433 [200]
GET /api/v3/purl/base 435 [200]
GET /api/v3/purl/base?q=namespace=redhat 434 [200]
GET /api/v3/purl/base?q=type=rpm 434 [200]
GET /api/v3/purl/base?sort=name:asc 434 [200]
GET /api/v3/purl?offset=100&limit=10 433 [200]
GET /api/v3/purl?q=curl 433 [200]
GET /api/v3/purl?q=license~GPLv3+ with exceptions Apache&sort=name:desc
GET /api/v3/purl?q=name=curl 433 [200]
GET /api/v3/purl?q=purl:namespace=redhat 434 [200]
GET /api/v3/purl?q=purl:ty=rpm 434 [200]
GET /api/v3/purl?sort=purl:name:asc 434 [200]
GET /api/v3/sbom 866 [200]
GET /api/v3/sbom-labels 435 [200]
GET /api/v3/sbom?offset=100&limit=10 866 [200]
GET /api/v3/sbom?q=label:type=product 435 [200]
GET /api/v3/sbom?q=license~GPL&sort=name:desc 31,498 [200]
GET /api/v3/sbom?q=name~redhat 435 [200]
GET /api/v3/sbom?q=published>2024-01-01 435 [200]
GET /api/v3/sbom?sort=ingested:desc 435 [200]
GET /api/v3/vulnerability 433 [200]
GET /api/v3/vulnerability?offset=100&limit=10 433 [200]
GET /api/v3/vulnerability?q=base_score>=7.0 435 [200]
GET /api/v3/vulnerability?q=base_severity=high 435 [200]
GET /api/v3/vulnerability?q=cwes=CWE-79 435 [200]
GET /api/v3/vulnerability?sort=base_score:desc 435 [200]
GET /api/v3/weakness 435 [200]
GET /api/v3/weakness?q=description~injection 434 [200]
GET /api/v3/weakness?sort=id:asc 434 [200]
GET count_sbom_by_package[pkg:oci/web-ter…=1.15-1770672845] 432 [200]
GET download_advisory[f1e5eb17-2f31-4…b46-c11f52398375] 432 [404]
GET download_sbom[sha256:a04260d9…a6046a828fcd17e5] 432 [404]
GET get_advisory[f1e5eb17-2f31-4…b46-c11f52398375] 432 [200]
GET get_base_purl[pkg:golang/k8s.…d/golang/reflect] 432 [200]
GET get_organization[53d3fae7-574a-4…66b-5a704e8b289a] 432 [200]
GET get_product[761f2bc9-f3a4-5…ee5-fd2aa3aef38b] 432 [200]
GET get_purl_details[00001592-edf0-5…ed9-396e8c9d149f] 432 [200]
GET get_sbom[sha256:a04260d9…a6046a828fcd17e5] 434 [200]
GET get_sbom_license_export[urn:uuid:019cf0…76e-43a3bfd8a2f5] 432 [200]
GET get_sbom_license_ids[urn:uuid:019cf0…76e-43a3bfd8a2f5] 433 [200]
GET get_spdx_license[MIT] 432 [200]
GET list_advisory_labels 437 [200]
GET sbom_by_package[pkg:oci/web-ter…=1.15-1770672845] 434 [200]
POST get_recommendations[batch=10] 1,296 [200]
POST post_extract_sbom_purls 435 [200]
POST post_vulnerability_analyze[pkg:rpm/redhat/squid] 433 [200]
POST post_vulnerability_analyze_v3 435 [200]
Aggregated 864 [404], 249,544 [200]

Transaction Metrics

Transaction # Times Run # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
WebsiteUser
0.0 logon 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.1 website_index 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.2 website_openapi 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.3 website_sboms 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.4 website_packages 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.5 website_advisories 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.6 website_importers 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
RestAPIUser
1.0 logon 432 (+77) 0 (0) 14.39 (+1.08) 6 (0) 56 (+19) 0.24 (+0.04) 0.00 (+0.00)
1.1 /api/v3/organization 432 (+77) 0 (0) 10.06 (+3.94) 1 (0) 49 (-15) 0.24 (+0.04) 0.00 (+0.00)
1.2 /api/v3/advisory 432 (+77) 0 (0) 59.59 (+29.86) 6 (+1) 176 (+33) 0.24 (+0.04) 0.00 (+0.00)
1.3 /api/v3/advisory?offset=100&limit=10 432 (+77) 0 (0) 71.04 (+38.37) 9 (+1) 446 (+354) 0.24 (+0.04) 0.00 (+0.00)
1.4 /api/v3/advisory?q=identifier%3dCVE-2022-0981 432 (+77) 0 (0) 18.34 (+6.99) 2 (0) 80 (+31) 0.24 (+0.04) 0.00 (+0.00)
1.5 /api/v3/advisory?q=CVE-2021- 433 (+78) 0 (0) 490.18 (+324.09) 8 (+1) 4870 (+3288) 0.24 (+0.04) 0.00 (+0.00)
1.6 /api/v3/vulnerability 433 (+78) 0 (0) 11.81 (+5.30) 2 (0) 99 (+37) 0.24 (+0.04) 0.00 (+0.00)
1.7 /api/v3/vulnerability?offset=100&limit=10 433 (+78) 0 (0) 10.55 (+4.20) 1 (-1) 279 (+222) 0.24 (+0.04) 0.00 (+0.00)
1.8 /api/v3/importer 433 (+78) 0 (0) 12.09 (+1.45) 1 (0) 69 (+13) 0.24 (+0.04) 0.00 (+0.00)
1.9 /api/v3/purl 433 (+78) 0 (0) 6.55 (+2.44) 1 (0) 51 (+4) 0.24 (+0.04) 0.00 (+0.00)
1.10 /api/v3/purl?offset=100&limit=10 433 (+78) 0 (0) 5.84 (+2.57) 1 (0) 48 (+28) 0.24 (+0.04) 0.00 (+0.00)
1.11 /api/v3/purl?q=curl 433 (+77) 0 (0) 25.77 (-6137.25) 3 (-971) 96 (-15644) 0.24 (+0.04) 0.00 (+0.00)
1.12 /api/v3/purl?q=name=curl 433 (+77) 0 (0) 8.97 (-25.07) 1 (-8) 61 (-125) 0.24 (+0.04) 0.00 (+0.00)
1.13 /api/v3/product 433 (+77) 0 (0) 9.73 (+4.20) 2 (0) 58 (+18) 0.24 (+0.04) 0.00 (+0.00)
1.14 /api/v3/sbom 433 (+77) 0 (0) 247.03 (+115.99) 70 (-11) 831 (+512) 0.24 (+0.04) 0.00 (+0.00)
1.15 /api/v3/sbom 433 (+77) 0 (0) 229.65 (+95.13) 62 (+2) 652 (-21) 0.24 (+0.04) 0.00 (+0.00)
1.16 /api/v3/sbom?offset=100&limit=10 433 (+77) 0 (0) 274.12 (+100.26) 53 (-30) 1060 (+647) 0.24 (+0.04) 0.00 (+0.00)
1.17 /api/v3/sbom?offset=100&limit=10 433 (+82) 0 (0) 196.86 (+103.54) 41 (-4) 678 (+312) 0.24 (+0.05) 0.00 (+0.00)
1.18 list_advisory_labels 437 (+82) 0 (0) 13383.62 (-505.67) 5794 (+763) 26976 (+7985) 0.24 (+0.05) 0.00 (+0.00)
1.19 /api/v3/sbom-labels 435 (+80) 0 (0) 36.59 (+6.86) 5 (-1) 100 (+10) 0.24 (+0.04) 0.00 (+0.00)
1.20 /api/v3/purl/base 435 (+80) 0 (0) 7.69 (-0.45) 1 (0) 74 (+15) 0.24 (+0.04) 0.00 (+0.00)
1.21 /api/v3/license 435 (+80) 0 (0) 13.03 (-1.38) 2 (0) 65 (-27) 0.24 (+0.04) 0.00 (+0.00)
1.22 /api/v3/license/spdx/license 435 (+80) 0 (0) 1.47 (+0.12) 1 (0) 32 (+21) 0.24 (+0.04) 0.00 (+0.00)
1.23 /api/v3/weakness 435 (+80) 0 (0) 8.85 (+0.87) 1 (0) 54 (+2) 0.24 (+0.04) 0.00 (+0.00)
1.24 /api/v3/group/sbom 435 (+80) 0 (0) 5.59 (+1.04) 1 (0) 60 (+13) 0.24 (+0.04) 0.00 (+0.00)
1.25 post_vulnerability_analyze_v3 435 (+80) 0 (0) 1429.44 (+343.13) 315 (+97) 3597 (+1196) 0.24 (+0.04) 0.00 (+0.00)
1.26 /.well-known/trustify 435 (+80) 0 (0) 2.17 (-1.47) 2 (+1) 46 (+10) 0.24 (+0.04) 0.00 (+0.00)
1.27 post_extract_sbom_purls 435 (+80) 0 (0) 2.48 (-1.70) 1 (0) 34 (-13) 0.24 (+0.04) 0.00 (+0.00)
1.28 /api/v3/advisory?q=title~openssl 435 (+80) 0 (0) 53.33 (-288.88) 9 (-14) 167 (-918) 0.24 (+0.04) 0.00 (+0.00)
1.29 /api/v3/advisory?q=modified>3 days ago 435 (+80) 0 (0) 10.45 (+1.90) 2 (0) 70 (+19) 0.24 (+0.04) 0.00 (+0.00)
1.30 /api/v3/advisory?sort=modified:desc 435 (+80) 0 (0) 31.91 (-1.46) 5 (0) 155 (+49) 0.24 (+0.04) 0.00 (+0.00)
1.31 /api/v3/advisory?deprecated=Consider 435 (+80) 0 (0) 67.78 (+24.98) 6 (+2) 211 (+63) 0.24 (+0.04) 0.00 (+0.00)
1.32 /api/v3/sbom?q=name~redhat 435 (+80) 0 (0) 206.80 (-10.35) 10 (-2) 1294 (+713) 0.24 (+0.04) 0.00 (+0.00)
1.33 /api/v3/sbom?q=published>2024-01-01 435 (+80) 0 (0) 293.50 (+138.17) 60 (+1) 774 (+324) 0.24 (+0.04) 0.00 (+0.00)
1.34 /api/v3/sbom?sort=ingested:desc 435 (+80) 0 (0) 213.47 (+64.54) 38 (+10) 599 (+199) 0.24 (+0.04) 0.00 (+0.00)
1.35 /api/v3/sbom?q=label:type=product 435 (+80) 0 (0) 11.88 (+4.46) 1 (0) 58 (-11) 0.24 (+0.04) 0.00 (+0.00)
1.36 /api/v3/vulnerability?q=base_severity=high 435 (+80) 0 (0) 22.10 (+7.52) 2 (0) 423 (+241) 0.24 (+0.04) 0.00 (+0.00)
1.37 /api/v3/vulnerability?q=base_score>=7.0 435 (+80) 0 (0) 15.45 (+4.35) 2 (0) 118 (-105) 0.24 (+0.04) 0.00 (+0.00)
1.38 /api/v3/vulnerability?q=cwes=CWE-79 435 (+80) 0 (0) 20.49 (+6.48) 2 (0) 201 (+110) 0.24 (+0.04) 0.00 (+0.00)
1.39 /api/v3/vulnerability?sort=base_score:desc 435 (+80) 0 (0) 845.49 (+208.74) 220 (+79) 3322 (+2240) 0.24 (+0.04) 0.00 (+0.00)
1.40 /api/v3/purl?q=purl:ty=rpm 434 (+79) 0 (0) 8.15 (+0.71) 2 (0) 56 (-2) 0.24 (+0.04) 0.00 (+0.00)
1.41 /api/v3/purl?q=purl:namespace=redhat 434 (+79) 0 (0) 6.36 (+0.40) 2 (+1) 49 (+4) 0.24 (+0.04) 0.00 (+0.00)
1.42 /api/v3/purl?sort=purl:name:asc 434 (+79) 0 (0) 8.96 (-0.47) 2 (+1) 57 (-2) 0.24 (+0.04) 0.00 (+0.00)
1.43 /api/v3/purl/base?q=type=rpm 434 (+79) 0 (0) 7.26 (+1.70) 1 (0) 61 (+18) 0.24 (+0.04) 0.00 (+0.00)
1.44 /api/v3/purl/base?q=namespace=redhat 434 (+79) 0 (0) 7.81 (+2.05) 1 (0) 66 (+24) 0.24 (+0.04) 0.00 (+0.00)
1.45 /api/v3/purl/base?sort=name:asc 434 (+79) 0 (0) 219.47 (+77.77) 48 (+16) 739 (+451) 0.24 (+0.04) 0.00 (+0.00)
1.46 /api/v3/organization?sort=name:asc 434 (+79) 0 (0) 8.45 (+0.96) 1 (0) 56 (-1) 0.24 (+0.04) 0.00 (+0.00)
1.47 /api/v3/product?q=name~openshift 434 (+79) 0 (0) 13.59 (+2.35) 2 (0) 91 (+11) 0.24 (+0.04) 0.00 (+0.00)
1.48 /api/v3/product?sort=name:asc 434 (+79) 0 (0) 15.29 (+5.11) 2 (0) 71 (+17) 0.24 (+0.04) 0.00 (+0.00)
1.49 /api/v3/weakness?q=description~injection 434 (+79) 0 (0) 7.00 (+2.57) 1 (0) 55 (+13) 0.24 (+0.04) 0.00 (+0.00)
1.50 /api/v3/weakness?sort=id:asc 434 (+79) 0 (0) 6.62 (+2.03) 1 (0) 58 (+4) 0.24 (+0.04) 0.00 (+0.00)
1.51 /api/v3/group/sbom?totals=true 434 (+79) 0 (0) 5.02 (+1.72) 1 (0) 50 (+11) 0.24 (+0.04) 0.00 (+0.00)
1.52 /api/v3/group/sbom?parents=resolve 434 (+79) 0 (0) 5.68 (+2.10) 1 (0) 48 (+6) 0.24 (+0.04) 0.00 (+0.00)
1.53 get_sbom[sha256:a04260d9…a6046a828fcd17e5] 434 (+79) 0 (0) 145.17 (+70.82) 26 (+6) 387 (+123) 0.24 (+0.04) 0.00 (+0.00)
1.54 sbom_by_package[pkg:oci/web-ter…=1.15-1770672845] 434 (+79) 0 (0) 91.03 (+35.74) 18 (+9) 678 (+298) 0.24 (+0.04) 0.00 (+0.00)
1.55 get_sbom_license_ids[urn:uuid:019cf0…76e-43a3bfd8a2f5] 433 (+78) 0 (0) 12.96 (+3.64) 1 (0) 74 (+18) 0.24 (+0.04) 0.00 (+0.00)
1.56 post_vulnerability_analyze[pkg:rpm/redhat/squid] 433 (+78) 0 (0) 6.65 (+2.98) 1 (0) 63 (+21) 0.24 (+0.04) 0.00 (+0.00)
1.57 get_purl_details[00001592-edf0-5…ed9-396e8c9d149f] 432 (+77) 0 (0) 611.14 (+147.89) 198 (+114) 1485 (+682) 0.24 (+0.04) 0.00 (+0.00)
1.58 get_recommendations[batch=10] 432 (+77) 0 (0) 222.45 (+47.75) 22 (+3) 961 (+431) 0.24 (+0.04) 0.00 (+0.00)
1.59 get_recommendations[batch=10] 432 (+77) 0 (0) 118.25 (+59.34) 27 (+10) 364 (+187) 0.24 (+0.04) 0.00 (+0.00)
1.60 get_recommendations[batch=10] 432 (+77) 0 (0) 114.72 (+57.55) 23 (+5) 306 (+134) 0.24 (+0.04) 0.00 (+0.00)
1.61 download_advisory[f1e5eb17-2f31-4…b46-c11f52398375] 432 (+77) 0 (0) 17.41 (+4.33) 2 (0) 91 (+16) 0.24 (+0.04) 0.00 (+0.00)
1.62 get_advisory[f1e5eb17-2f31-4…b46-c11f52398375] 432 (+77) 0 (0) 14.84 (+3.90) 1 (0) 79 (-37) 0.24 (+0.04) 0.00 (+0.00)
1.63 download_sbom[sha256:a04260d9…a6046a828fcd17e5] 432 (+77) 0 (0) 132.12 (+61.96) 26 (+7) 524 (-4) 0.24 (+0.04) 0.00 (+0.00)
1.64 get_sbom_license_export[urn:uuid:019cf0…76e-43a3bfd8a2f5] 432 (+77) 0 (0) 21.20 (+5.13) 1 (0) 95 (-353) 0.24 (+0.04) 0.00 (+0.00)
1.65 count_sbom_by_package[pkg:oci/web-ter…=1.15-1770672845] 432 (+77) 0 (0) 17.82 (+4.04) 3 (+1) 74 (+10) 0.24 (+0.04) 0.00 (+0.00)
1.66 get_product[761f2bc9-f3a4-5…ee5-fd2aa3aef38b] 432 (+77) 0 (0) 14.05 (+2.54) 2 (+1) 83 (-27) 0.24 (+0.04) 0.00 (+0.00)
1.67 get_organization[53d3fae7-574a-4…66b-5a704e8b289a] 432 (+77) 0 (0) 358.38 (+79.88) 99 (+45) 1341 (+744) 0.24 (+0.04) 0.00 (+0.00)
1.68 get_base_purl[pkg:golang/k8s.…d/golang/reflect] 432 (+77) 0 (0) 64.39 (-0.35) 5 (+1) 487 (+267) 0.24 (+0.04) 0.00 (+0.00)
1.69 get_spdx_license[MIT] 432 (+77) 0 (0) 1.87 (-0.76) 1 (+1) 17 (0) 0.24 (+0.04) 0.00 (+0.00)
RestAPIUserSlow
2.0 logon 31498 (-13679) 0 (0) 11.13 (+1.92) 6 (+1) 58 (+2) 17.50 (-7.60) 0.00 (+0.00)
2.1 /api/v3/license?q=ASL&sort=license:desc 31499 (-13678) 0 (0) 14.61 (+6.02) 1 (0) 174 (-34) 17.50 (-7.60) 0.00 (+0.00)
2.2 /api/v3/sbom?q=license~GPL&sort=name:desc 31498 (-13679) 0 (0) 6.76 (+2.56) 1 (0) 163 (+64) 17.50 (-7.60) 0.00 (+0.00)
2.3 /api/v3/purl?q=license~GPLv3+ with exceptions Apache&sort=name:desc 31498 (-13679) 0 (0) 5.43 (+2.02) 1 (0) 101 (+22) 17.50 (-7.60)
2.4 /api/v3/license?q=license~Apache 31498 (-13679) 0 (0) 6.65 (+2.33) 1 (0) 85 (-274) 17.50 (-7.60) 0.00 (+0.00)
2.5 /api/v3/license?q=license~GPL 31498 (-13678) 0 (0) 6.88 (+2.45) 1 (0) 390 (+305) 17.50 (-7.60) 0.00 (+0.00)
2.6 /api/v3/license/spdx/license?q=apache 31498 (-13678) 0 (0) 1.11 (+0.09) 1 (0) 46 (-1) 17.50 (-7.60) 0.00 (+0.00)
2.7 /api/v3/license/spdx/license?q=gpl 31498 (-13679) 0 (0) 1.06 (+0.18) 1 (0) 61 (+10) 17.50 (-7.60) 0.00 (+0.00)
AnalysisUser
3.0 logon 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
3.1 /api/v3/analysis/status 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
3.2 /api/v3/analysis/latest/component/cpe%3A%2Fa%3Aredhat%3Aopenshift_builds%3A1.3%3A%3Ael9 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
3.3 get_analysis_component[sha256:a04260d9…a6046a828fcd17e5] 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
RestAPIUserDelete
4.0 logon 509 (-2) 0 (0) 10.97 (+0.43) 6 (0) 35 (-5) 0.28 (-0.00) 0.00 (+0.00)
RestSBOMLabelUser
5.0 logon 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
5.1 put_sbom_labels[urn:uuid:019cf0…76e-43a3bfd8a2f5] 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
5.2 patch_sbom_labels[urn:uuid:019cf0…76e-43a3bfd8a2f5] 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
RestAdvisoryLableUser
6.0 logon 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
Aggregated 282847 (-103930) 0 (0) 36.52 (+10.20) 1 (0) 26976 (+7985) 157.14 (-57.74) 0.00 (+0.00)

Scenario Metrics

Transaction # Users # Times Run Average (ms) Min (ms) Max (ms) Scenarios/s Iterations
WebsiteUser 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
RestAPIUser 5 (0) 432 (+77) 20718.76 (-4598.17) 13693 (-6240) 35498 (+6706) 0.24 (+0.04) 86.40 (+15.40)
RestAPIUserSlow 1 (0) 31498 (-13679) 56.65 (+17.31) 16 (+1) 426 (+18) 17.50 (-7.60) 31498.00 (-13679.00)
AnalysisUser 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
RestAPIUserDelete 1 (0) 509 (-2) 3536.49 (+13.52) 3012 (-4) 4022 (+5) 0.28 (-0.00) 509.00 (-2.00)
RestSBOMLabelUser 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
RestAdvisoryLableUser 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
Aggregated 7 (0) 32439 (-13604) 386.42 (+113.52) 16 (+1) 35498 (+6706) 18.02 (-7.56) 32093.40 (-13665.60)

Error Metrics

Method Name # Error
GET download_advisory[f1e5eb17-2f31-4…b46-c11f52398375] 432 (+77) 404 Not Found: download_advisory[f1e5eb17-2f31-4…b46-c11f52398375]
GET download_sbom[sha256:a04260d9…a6046a828fcd17e5] 432 (+77) 404 Not Found: download_sbom[sha256:a04260d9…a6046a828fcd17e5]

📄 Full Report (Go to "Artifacts" and download report)

@rh-jfuller

rh-jfuller commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

The scale test reports improvements for rest api endpoints but results are mixed eg. max time (95 percentile) increases but we also see a higher RPS which is positive - however the slow rest api performance is negatively impacted.

At face value the impact is >25% improvement (that is prob biased by the perf tests, improvement might be better then that).

I think this PR is definitely an improvement we want, though needs more analysis (I will run newer perf tests and look more at the code changes) ... lets pick it up next week - I do not think its a candidate yet for 0.5.z.

@rh-jfuller

Copy link
Copy Markdown
Contributor

/perf-test

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown

🛠️ Perf test has started! Follow the progress here: Workflow Run

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Perf Test Report (Locust)
Type Name Request Count Failure Count Average Response Time Min Response Time Max Response Time Average Content Size Requests/s Failures/s
GET /.well-known/trustify 4 0 1.6819542500456919 1.3405950001015299 2.521586000057141 41.0 0.013409310358591896 0.0
GET /api/v3/advisory?deprecated=Consider&total=true 6 6 1.3720354999501676 1.2095559998215322 1.8786840000757365 0.0 0.020113965537887846 0.020113965537887846
GET /api/v3/advisory?offset=100&limit=10&total=true 4 4 1.5097367499947723 1.2121080001179507 2.150255999822548 0.0 0.013409310358591896 0.013409310358591896
GET /api/v3/advisory?q=CVE-2021-&total=true 7 7 1.328166857157547 0.9668959999089566 1.859446000025855 0.0 0.02346629312753582 0.02346629312753582
GET /api/v3/advisory?q=identifier=CVE-2022-0981&total=true 2 2 1.6034269999636308 1.291027999968719 1.9158259999585425 0.0 0.006704655179295948 0.006704655179295948
GET /api/v3/advisory?q=modified>3 days ago&total=true 7 7 1.4481155713903198 1.2793329999567504 1.9476579998354282 0.0 0.02346629312753582 0.02346629312753582
GET /api/v3/advisory?q=title~openssl&total=true 6 6 1.4456068333477863 0.9613540000827925 1.98560500007261 0.0 0.020113965537887846 0.020113965537887846
GET /api/v3/advisory?sort=modified:desc&total=true 5 5 1.5137418000449543 1.2604460000602558 2.2885060000135127 0.0 0.01676163794823987 0.01676163794823987
GET /api/v3/advisory?total=true 4 4 1.2121490000254198 1.0667710000689112 1.4069090000248252 0.0 0.013409310358591896 0.013409310358591896
GET /api/v3/analysis/status 78 78 1.456410410247745 0.9130700000241632 2.7291659998809337 0.0 0.26148155199254197 0.26148155199254197
GET /api/v3/group/sbom?parents=resolve&total=true 2 2 1.2721969999347493 1.2511630000062723 1.2932309998632263 0.0 0.006704655179295948 0.006704655179295948
GET /api/v3/group/sbom?total=true 5 5 1.5405847999318212 1.247281999894767 1.9956829999046022 0.0 0.01676163794823987 0.01676163794823987
GET /api/v3/group/sbom?totals=true&total=true 2 2 1.3986985001110952 1.1803600000348524 1.617037000187338 0.0 0.006704655179295948 0.006704655179295948
GET /api/v3/importer?total=true 6 6 1.4639561666551042 1.3055429999440094 1.725429999851258 0.0 0.020113965537887846 0.020113965537887846
GET /api/v3/license/spdx/license?q=apache&total=true 28 28 1.4031887142696828 1.117260000000897 3.225757999871348 0.0 0.09386517251014329 0.09386517251014329
GET /api/v3/license/spdx/license?q=gpl&total=true 39 39 1.4039664872073514 1.015552000126263 2.272262000133196 0.0 0.13074077599627099 0.13074077599627099
GET /api/v3/license/spdx/license?total=true 1 1 1.2470130000110657 1.2470130000110657 1.2470130000110657 0.0 0.003352327589647974 0.003352327589647974
GET /api/v3/license?q=ASL&sort=license:desc&total=true 43 43 1.3484938837347389 1.0467469999184686 2.1248929999728716 0.0 0.1441500863548629 0.1441500863548629
GET /api/v3/license?q=license~Apache&total=true 49 49 1.4229779183561009 1.1121210000055726 4.954104000034931 0.0 0.16426405189275073 0.16426405189275073
GET /api/v3/license?q=license~GPL&total=true 44 44 1.3463787727387584 1.055452999935369 2.0400389998940227 0.0 0.14750241394451086 0.14750241394451086
GET /api/v3/license?total=true 4 4 1.410628749965781 1.1356850000083796 1.9364199999927223 0.0 0.013409310358591896 0.013409310358591896
GET /api/v3/organization?sort=name:asc&total=true 4 4 1.4383614999928795 1.2104300001283264 1.7659889999777079 0.0 0.013409310358591896 0.013409310358591896
GET /api/v3/organization?total=true 2 2 3.5832819999086496 1.4084969998293673 5.758066999987932 0.0 0.006704655179295948 0.006704655179295948
GET /api/v3/product?q=name~openshift&total=true 5 5 1.4060121999591502 1.185794999855716 1.8318299999009469 0.0 0.01676163794823987 0.01676163794823987
GET /api/v3/product?sort=name:asc&total=true 4 4 1.7454064999924412 1.3330049998785398 2.543629999991026 0.0 0.013409310358591896 0.013409310358591896
GET /api/v3/product?total=true 3 3 1.9442319999901276 1.2061639999956242 2.757262000159244 0.0 0.010056982768943923 0.010056982768943923
GET /api/v3/purl/base?q=namespace=redhat&total=true 5 5 1.5015544000107184 1.3093620000290684 1.7519529999390215 0.0 0.01676163794823987 0.01676163794823987
GET /api/v3/purl/base?q=type=rpm&total=true 2 2 1.276357499932601 1.1462079999091657 1.4065069999560365 0.0 0.006704655179295948 0.006704655179295948
GET /api/v3/purl/base?sort=name:asc&total=true 2 2 1.6514555001094777 1.3199180000356137 1.9829930001833418 0.0 0.006704655179295948 0.006704655179295948
GET /api/v3/purl/base?total=true 4 4 1.5986790000397377 1.2563850000333332 1.9035239999993792 0.0 0.013409310358591896 0.013409310358591896
GET /api/v3/purl?offset=100&limit=10&total=true 2 2 1.6760785000542455 1.4349170000969025 1.9172400000115886 0.0 0.006704655179295948 0.006704655179295948
GET /api/v3/purl?q=curl&total=true 3 3 1.4623310000085137 1.3546889999815903 1.5494840001792909 0.0 0.010056982768943923 0.010056982768943923
GET /api/v3/purl?q=license~GPLv3+...&sort=name:desc&total=true 49 49 1.3663080612230036 1.055625999924814 1.969064999912007 0.0 0.16426405189275073 0.16426405189275073
GET /api/v3/purl?q=name=curl&total=true 4 4 1.326964500037775 1.1969890001637395 1.4138900000943977 0.0 0.013409310358591896 0.013409310358591896
GET /api/v3/purl?q=purl:namespace=redhat&total=true 6 6 1.3347746666264964 1.1954949998198572 1.8346809999911784 0.0 0.020113965537887846 0.020113965537887846
GET /api/v3/purl?q=purl:ty=rpm&total=true 1 1 1.2673979999817675 1.2673979999817675 1.2673979999817675 0.0 0.003352327589647974 0.003352327589647974
GET /api/v3/purl?sort=purl:name:asc&total=true 3 3 1.3732463332113791 0.960643999860622 1.8517199998768774 0.0 0.010056982768943923 0.010056982768943923
GET /api/v3/purl?total=true 2 2 1.7492154998990372 1.4615179998145322 2.0369129999835422 0.0 0.006704655179295948 0.006704655179295948
GET /api/v3/sbom-labels?total=true 3 3 1.2956373333660547 1.2115469999116613 1.3879180000913038 0.0 0.010056982768943923 0.010056982768943923
GET /api/v3/sbom?offset=100&limit=10&total=true 14 14 1.4937437856912896 1.2076579998847592 2.146589000176391 0.0 0.04693258625507164 0.04693258625507164
GET /api/v3/sbom?q=label:type=product&total=true 5 5 1.508849999981976 1.244270999904984 1.9856369999615708 0.0 0.01676163794823987 0.01676163794823987
GET /api/v3/sbom?q=license~GPL&sort=name:desc&total=true 52 52 1.3795358461440907 1.1397679998026433 2.4851670000316517 0.0 0.17432103466169466 0.17432103466169466
GET /api/v3/sbom?q=name~redhat&total=true 4 4 1.5264095000020461 1.2326010000833776 2.115542999945319 0.0 0.013409310358591896 0.013409310358591896
GET /api/v3/sbom?q=published>2024-01-01&total=true 4 4 1.9347582500586213 1.268993000167029 3.763838000168107 0.0 0.013409310358591896 0.013409310358591896
GET /api/v3/sbom?sort=ingested:desc&total=true 5 5 1.3317400000232738 1.1690740000176447 1.6515510001227085 0.0 0.01676163794823987 0.01676163794823987
GET /api/v3/sbom?total=true 4 4 1.6608120000114468 1.2819769999623531 2.0852509999258473 0.0 0.013409310358591896 0.013409310358591896
GET /api/v3/vulnerability?offset=100&limit=10&total=true 4 4 1.4061627500154827 1.2263790001725283 1.583633999871381 0.0 0.013409310358591896 0.013409310358591896
GET /api/v3/vulnerability?q=base_score>=7.0&total=true 2 2 1.983698000003642 1.3368850000006205 2.6305110000066634 0.0 0.006704655179295948 0.006704655179295948
GET /api/v3/vulnerability?q=base_severity=high&total=true 5 5 1.7027906000294024 1.2696460000825027 2.6068070001201704 0.0 0.01676163794823987 0.01676163794823987
GET /api/v3/vulnerability?q=cwes=CWE-79&total=true 5 5 1.4773681999486143 1.1416820000249572 1.8856399999549467 0.0 0.01676163794823987 0.01676163794823987
GET /api/v3/vulnerability?sort=base_score:desc&total=true 3 3 1.3254869999551981 1.2248959999396902 1.5192089999800373 0.0 0.010056982768943923 0.010056982768943923
GET /api/v3/vulnerability?total=true 1 1 1.8401360000552813 1.8401360000552813 1.8401360000552813 0.0 0.003352327589647974 0.003352327589647974
GET /api/v3/weakness?sort=id:asc&total=true 5 5 1.3876297999559029 1.2119040000015957 1.8748690001757495 0.0 0.01676163794823987 0.01676163794823987
GET /api/v3/weakness?total=true 6 6 1.5745648332767814 1.2083099998108082 2.3153559998263518 0.0 0.020113965537887846 0.020113965537887846
GET analysis_by_cpe 90 90 1.5149782111090342 1.006333000077575 7.2465469997951 0.0 0.3017094830683177 0.3017094830683177
GET find_random_advisory 213 213 1.42140459626264 0.9334430001217697 16.494980000061332 0.0 0.7140457765950186 0.7140457765950186
GET list_advisory_labels 83 83 1.3129718795152072 0.9469000001445238 2.0461899998736044 0.0 0.27824318994078184 0.27824318994078184
POST post_extract_sbom_purls 6 6 1.559173166583605 1.321079000035752 1.9849579998663103 0.0 0.020113965537887846 0.020113965537887846
POST post_vulnerability_analyze_v3 4 4 1.7485197499809146 1.3131840000824013 2.1740659999522904 0.0 0.013409310358591896 0.013409310358591896
GET website_advisories 35 0 1.4108576857324806 1.1649250000118627 2.323939000007158 1550.0 0.1173314656376791 0.0
GET website_importers 25 0 1.4128331200208777 1.2087790000805398 2.239970000118774 1550.0 0.08380818974119936 0.0
GET website_index 26 0 1.3893891538583165 1.07179399992674 2.1207350000622682 1550.0 0.08716051733084733 0.0
GET website_openapi 27 0 2.182419185205449 1.8269689999215188 2.560871000014231 734.0 0.0905128449204953 0.0
GET website_packages 19 0 1.4803336315899767 1.0765089998585609 2.602710999781266 1550.0 0.06369422420331151 0.0
GET website_sboms 18 0 1.4659496666682672 1.2191850000817794 2.358025999910751 1550.0 0.060341896613663536 0.0
Aggregated 1115 961 1.4484978672676396 0.9130700000241632 16.494980000061332 188.90762331838565 3.7378452624574914 3.221586813651703

📄 Full Report (Go to "Artifacts" and download report)

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

Labels

backport release/0.5.z Backport (0.5.z)

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants