Skip to content

Updateinfo.xml Timeouts #77

@rockythorn

Description

@rockythorn

updateinfo.xml times out for Rocky Linux 8 AppStream (x86_64, aarch64)

The v2 updateinfo endpoint returns HTTP 500 for Rocky Linux 8 AppStream on both x86_64 and
aarch64. This breaks compose tooling (apollo_tree.py) when generating updateinfo for RL8.

Reproduction

GET /api/v3/updateinfo/rocky-linux/8/AppStream/updateinfo.xml?arch=x86_64
GET /api/v3/updateinfo/rocky-linux/8/AppStream/updateinfo.xml?arch=aarch64

Both return HTTP 500 after ~29 seconds, consistent with hitting the 30-second server worker timeout.

Observed response times

Repo Arch Status Size Time
RL8 AppStream x86_64 500 0 B 28.9s
RL8 AppStream aarch64 500 0 B 29.4s
RL8 BaseOS x86_64 200 6.7 MB 8.4s
RL8 PowerTools x86_64 200 919 KB 5.9s
RL9 AppStream x86_64 200 10.9 MB 16.1s
RL9 AppStream aarch64 200 9.8 MB 13.8s

RL9 AppStream succeeds; RL8 does not. The difference is that RL8 has 11 minor versions
(8.0–8.10) vs RL9's ~5, which significantly increases query and processing load.

Root cause

The primary cause is an unbounded prefetch_related("advisory__packages") in
get_updateinfo_v2 (api_updateinfo.py). This loads all packages for every matching
advisory — across every repo, architecture, and mirror — and then filters them in Python.

For RL8 AppStream without a minor_version filter, the query matches ~3000 advisories across
11 minor versions (~33k advisory_affected_products rows). The prefetch then loads all packages
for each unique advisory, estimated at ~300k rows, of which only ~20k are actually used.

The advisory__packages__repo_name filter in the WHERE clause only restricts which advisories
are returned — it does not filter the prefetch.

Two missing indexes make things worse:

  • No index on advisory_packages(advisory_id, repo_name, supported_product_id)
  • No composite index on advisory_affected_products(supported_product_id, major_version, arch)

Fix

1. Filter the prefetch (highest impact — pushes filtering to SQL):

from tortoise.queryset import Prefetch

Prefetch(
    "advisory__packages",
    queryset=AdvisoryPackage.filter(
        repo_name=repo,
        supported_product_id=supported_product.id,
    )
)

2. Add a composite index on advisory_packages:

CREATE INDEX advisory_packages_advisory_repo_product_idx
    ON public.advisory_packages
    USING btree (advisory_id, repo_name, supported_product_id);

3. Add a composite index on advisory_affected_products:

CREATE INDEX advisory_affected_products_spid_major_arch_idx
    ON public.advisory_affected_products
    USING btree (supported_product_id, major_version, arch);

Fix 1 alone should resolve the timeout. Fixes 2 and 3 provide additional speedup at the DB level.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions