Skip to content

perf(api): list only the releases a server can pick in apps.json - #1969

Merged
oleksandr-nc merged 1 commit into
masterfrom
perf/1951/apps-json-newest-releases
Nov 6, 2026
Merged

oleksandr-nc merged 1 commit into
masterfrom
perf/1951/apps-json-newest-releases

Conversation

@oleksandr-nc

Copy link
Copy Markdown
Collaborator

Related #1951

A Nextcloud server keeps only one release per app from apps.json.
It drops the releases that don't fit its platform, PHP version or update channel, and takes the highest version left.
So when two releases have the same rawPlatformVersionSpec, rawPhpVersionSpec, isNightly and pre-release state, the lower one can never be picked.

This PR leaves those releases out of apps.json.
With the current catalogue it keeps 5,913 of 18,267 releases.
The list goes from 16.1 MB to 5.8 MB with gzip, and Django needs about 5 s instead of 9-10 s to generate it (measured locally).

Versions are compared with a port of PHP's version_compare(), as it works since PHP 8.4.22 and 8.5.7 (php/php-src#21689).
Releases that compare equal to the highest one are all kept, because the server's choice between them depends on sort order.
If a version in a set ends with something other than a letter or digit, the whole set is kept, because older PHP compares such versions inconsistently.
There is no such version in the catalogue today.

platform/<version>/apps.json and appapi_apps.json don't change.
App pages and downloads on the website still show every release.
Tools that look up one exact version should use platform/<version>/apps.json.
For example, a backport like mail 1.5.5, uploaded after 1.6.0 with the same requirements, is no longer in apps.json.

The ETag of apps.json is based on upload and delete times, not on the content.
So copies made from the origin switch to the smaller list with the next release upload or deletion.

🤖 AI (if applicable)

  • The content of this PR was partly or fully generated using AI

Related #1951

apps.json lists all releases of every app, about 18,000 on production,
but a Nextcloud server keeps one per app. It filters the releases on
their raw platform and PHP version specs, the nightly flag and whether
the version contains "-", then takes the highest version left according
to PHP's version_compare(). Of the releases that agree on those four
values, only the highest can ever be picked, so leaving out the others
changes nothing a server does.

On production's catalogue that keeps 5,913 of 18,267 releases. The list
falls from 16.1 MB to 5.8 MB with gzip, and on the local copy of
production a build through Apache takes about 5 s instead of 9 to 10 s.

The rule is a list serializer used only by apps.json, with a port of
version_compare() as of PHP 8.4.22 and 8.5.7 for the comparison. Releases
that compare equal to the newest of their set are all kept, because which
of them a server picks depends on its sort order. A set with a version
that ends in a character other than a letter or digit is kept whole:
older PHP orders such versions inconsistently, and none exists in the
catalogue today. platform/<version>/apps.json and appapi_apps.json are
unchanged, and the API docs describe the rule.

Signed-off-by: Oleksander Piskun <oleksandr2088@icloud.com>

@lukasdotcom lukasdotcom left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks nice. Not sure if this is actually faster or even worth it to implement, but it could be worth it to split the versions stuff into two queries one that just gets version, raw_platform_version_spec, raw_php_version_spec, and is_nightly. Based on this find what versions you need everything for. It would save pulling the signature field which ai calculated to be about 77% of the data based of our current apps.json.

@oleksandr-nc

Copy link
Copy Markdown
Collaborator Author

Thanks, good idea! Loading only id, version, the two raw specs and is_nightly first, then everything else only for the releases we keep, makes the build about twice as fast and halves the memory.

I'd like to keep this PR small, so we can do it in a follow-up after the main work is done.

@oleksandr-nc
oleksandr-nc marked this pull request as ready for review November 6, 2026 19:28
@bigcat88
bigcat88 enabled auto-merge (squash) November 6, 2026 20:33
@oleksandr-nc
oleksandr-nc merged commit 35bbed0 into master Nov 6, 2026
9 checks passed
@oleksandr-nc
oleksandr-nc deleted the perf/1951/apps-json-newest-releases branch November 6, 2026 20:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants