Open-Source Wikis

/

GitLab

/

Systems

/

Gitaly client

gitlab-org/gitlab

Gitaly client

Every Git read/write goes through Gitaly. This page covers the client side that lives in this repo; for Gitaly's internals see gitlab-org/gitaly.

Purpose

Gitaly is a gRPC service that owns Git repository storage. The Rails monolith does not touch .git directories directly; instead it makes typed gRPC calls.

Source

Concern Location
Top-level facade lib/gitaly_client.rb (~32K LoC)
Per-RPC service classes lib/gitaly_client/
Repository wrapper lib/gitlab/git/repository.rb
Wiki wrapper lib/gitlab/git/wiki.rb
Generated proto bindings lib/gitaly/ (and via gitaly gem)
Workhorse-side client workhorse/internal/gitaly/

Patterns

The Rails code rarely calls Gitaly directly; it calls Gitlab::Git::*:

project.repository.commit('main')           # uses Gitaly
project.repository.commits('main', limit: 20)
project.repository.tree('main')
project.repository.find_by_path('main', 'README.md')

Gitlab::Git::Repository wraps Gitlab::GitalyClient::*Service classes. Each RPC method has a Ruby helper.

Token and routing

Every Gitaly call requires:

  • storage_name — which Gitaly node ("default", "secondary", etc.).
  • relative_path — the on-disk path inside that storage.
  • gl_repository — encoded identifier ("project-123", "wiki-123", "personal_snippet-7").
  • gl_project_path — for logging.
  • auth_token — a JWT signed with the shared secret in config/gitlab.yml.

Gitlab::GitalyClient builds the metadata header and reuses gRPC connections per storage.

Connection management

  • A single gRPC client per storage process-wide.
  • Connections are reused across requests; each request gets its own RPC.
  • lib/gitlab/gitaly_client/with_feature_flag_actors.rb propagates feature-flag context to Gitaly.

Concurrency and timeouts

Gitlab::GitalyClient enforces per-call deadlines:

  • Fast (~3 s) — metadata, single-commit lookups.
  • Medium — commit list, blame.
  • Slow — clone, push, archive (no deadline).

SafeRequestStore tracks per-request Gitaly call counts; the perf bar surfaces them, and the N+1 detector flags excessive calls.

Common services used by the Rails app

Service class RPCs
CommitService commit lookup, commit message, parents
RefService branches, tags, default branch
BlobService file content
RepositoryService clone, push, archive
OperationService merge, cherry-pick, revert
RemoteService mirror push/fetch
DiffService structured diffs
ConflictsService merge conflict resolution
WikiService wiki repo operations
ObjectPoolService shared object pools (forks)

Workhorse and Gitaly

Workhorse also talks to Gitaly directly for git-over-HTTP transfers:

sequenceDiagram
    Browser->>Workhorse: git fetch
    Workhorse->>Rails: /authorize
    Rails-->>Workhorse: gitaly addr + token + repo
    Workhorse->>Gitaly: SmartHTTP service
    Gitaly-->>Workhorse: streamed packfile
    Workhorse-->>Browser: streamed packfile

This avoids streaming the entire packfile through Puma.

Tests

  • Most code paths use real Gitaly running under GDK.
  • Spec helpers in spec/support/helpers/gitaly_helpers.rb.
  • For unit tests, stub_gitaly_client_call and friends provide cheap stubs.

Failure modes

Symptom Cause
Gitlab::Git::CommandError Underlying git command failed (often legitimate user error)
GRPC::Unavailable Gitaly process down or network glitch
GRPC::DeadlineExceeded Operation slower than the per-call deadline
Gitlab::Git::ResourceExhausted Gitaly's concurrency limit hit
Gitlab::GitalyClient::TooManyInvocationsError N+1 detector fired
  • Workhorse — the other big Gitaly client.
  • Database — repos are referenced from projects.repository_storage.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Gitaly client – GitLab wiki | Factory