perf: optimize CreateFile/UpdateFile API — 3x latency, 4x QPS - #8
Open
wu-yangjie wants to merge 1 commit into
Open
perf: optimize CreateFile/UpdateFile API — 3x latency, 4x QPS#8wu-yangjie wants to merge 1 commit into
wu-yangjie wants to merge 1 commit into
Conversation
wu-yangjie
force-pushed
the
base/v1.25.4-perf-updatefile-benchmark
branch
2 times, most recently
from
March 20, 2026 10:04
ad5e55a to
cfe8214
Compare
wu-yangjie
force-pushed
the
base/v1.25.4-perf-updatefile-benchmark
branch
from
March 20, 2026 10:55
cffb36d to
3f8672d
Compare
acmerfight
force-pushed
the
base/v1.25.4-perf-updatefile-benchmark
branch
from
March 23, 2026 08:57
44baba9 to
279a409
Compare
7 tasks
acmerfight
force-pushed
the
base/v1.25.4-perf-updatefile-benchmark
branch
2 times, most recently
from
March 23, 2026 09:35
7a9154d to
6da3902
Compare
acmerfight
marked this pull request as draft
March 23, 2026 10:10
acmerfight
force-pushed
the
base/v1.25.4-perf-updatefile-benchmark
branch
2 times, most recently
from
March 24, 2026 02:39
23be6bb to
6587250
Compare
Replace clone+push with direct bare-repo operations for non-empty repos
(when LFS is disabled). Falls back to original path when LFS is enabled.
Changes:
- modules/repository/push.go: Add PostPushUpdates func var (avoids import cycle)
- services/repository/push.go: Register PostPushUpdates (SyncBranchesToDB +
UpdatePullsRefs + PushUpdates queue)
- services/repository/files/temp_repo.go: Add NewDirectRepoRef (bare repo +
temp index), UpdateRef (atomic ref update), extraEnv for GIT_INDEX_FILE
- services/repository/files/update.go: Direct path for non-empty repos,
buildFilesResponseDirect (in-memory response, no git re-read),
save blobSHA/contentBytes in modifyFile
Measured on PostgreSQL + channel queue (POST /repos/{owner}/{repo}/contents/{filepath}):
Before: latency 690ms, QPS@8 3.56
After: latency 200ms, QPS@8 17.10
All 18 Gitea file API tests pass with LFS fallback.
acmerfight
force-pushed
the
base/v1.25.4-perf-updatefile-benchmark
branch
from
March 24, 2026 04:01
6587250 to
bc01058
Compare
wu-yangjie
marked this pull request as ready for review
March 24, 2026 07:58
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Optimize
POST /repos/{owner}/{repo}/contents/{filepath}(CreateFile/UpdateFile/DeleteFile API) by replacing the clone+push git workflow with direct bare-repo operations.Changes (4 files)
modules/repository/push.go— AddPostPushUpdatesfunction variable for cross-package side effect handling (avoids import cycle).services/repository/push.go— RegisterPostPushUpdatesat queue init: callsSyncBranchesToDB+UpdatePullsRefs+PushUpdates.services/repository/files/temp_repo.go— AddNewDirectRepoRef()(operate on bare repo with temp index, no clone),UpdateRef()(atomic ref update, no push),extraEnvsupport forGIT_INDEX_FILE.services/repository/files/update.go— For non-empty repos: useNewDirectRepoRef+UpdateRefinstead of clone+push. AddbuildFilesResponseDirect()to construct API response from in-memory data instead of re-reading git. Save blob SHA and content duringmodifyFilefor response building.What was slow and why
Each API call previously: cloned the repo to a temp dir → did git plumbing → pushed back (triggering 3 hook subprocesses). Measured breakdown:
Performance (real HTTP API, PostgreSQL + channel queue, 2000-file repo)
Prerequisites
LFS_START_SERVER = falseinapp.ini(user confirmed no LFS usage)Test results
18/18 Gitea file API tests pass (with LFS fallback):
TestAPICreateFile, TestAPIUpdateFile, TestAPIDeleteFile, TestAPIChangeFiles,
TestChangeRepoFilesForCreate/Update/UpdateWithFileMove/UpdateWithFileRename/
WithoutBranchNames/ForDelete/ForDeleteWithoutBranchNames/Errors,
TestEmptyRepo/AddFile/UploadFile/AddFileByAPI