Package Registry: skip find-or-create for Maven checksum (.sha1/.md5) uploads
Summary
During mvn deploy, Maven uploads a .sha1 and .md5 checksum file after every artifact (.jar, .pom, maven-metadata.xml). On the finalize endpoint (PUT /projects/:id/packages/maven/*path/:file_name), these checksum uploads currently run the full Packages::Maven::FindOrCreatePackageService path — the same work as a real artifact upload — even though checksums are stored as columns on the package file and never need find-or-create.
For a release deploy this is roughly two-thirds of the PUTs per module (~6 of ~9), each doing avoidable work on a hot, latency-sensitive endpoint.
What the checksum PUTs do today
For .sha1 / .md5, the finalize endpoint runs FindOrCreatePackageService, which performs:
- a
Packages::Maven::PackageFinderlookup (JOIN onpackages_maven_metadata.path); - duplicate detection (
Namespace::PackageSetting.duplicates_allowed?, a cascading namespace-ancestry lookup, plus loading allpackage_filesfor snapshots); create_build_infos!(find-or-create);- on create, a package-protection-rule check plus INSERTs.
Then:
md5→ the result is discarded and an empty body is returned (all preceding work wasted);sha1→ only the stored file's sha1 is needed, to compare against the uploaded checksum.
The whole block is also pinned to the primary database.
Proposed change
Fast-path checksum uploads on the finalize endpoint:
md5→ return an empty body immediately (no DB work, no primary pinning);sha1→ look up the package and package file and verify the stored hash, skipping find-or-create entirely.
The real-artifact path is unchanged, and the happy path (artifact uploaded before its checksums, as Maven and Gradle always do) is behaviorally identical.
Gated behind the maven_checksum_upload_fast_path feature flag (gitlab_com_derisk, default off) to de-risk the change on this hot endpoint.
Scope
This is one of several independent server-side improvements identified for Maven deploy PUT latency. Adopting use_final_store_path for the authorize step (to remove the synchronous object-storage HEAD + COPY + DELETE on real-file finalize) is a separate, larger change tracked on its own.