Open-Source Wikis

/

GitLab

/

Systems

/

Object storage

gitlab-org/gitlab

Object storage

S3-compatible storage for any blob-shaped data — uploads, artifacts, packages, LFS, container images, dependency proxy.

Source

Concern Location
Settings config/object_store_settings.rb, config/gitlab.yml.example
CarrierWave bridge app/uploaders/, lib/object_storage/
Direct uploads lib/object_storage/direct_upload.rb
Workhorse upload helpers workhorse/internal/upload/, workhorse/internal/objectstore/
Migration helpers lib/object_storage/migration/

Storage targets

Concern Backing service Files
Uploads (avatars, attachments) object storage / local disk app/uploaders/file_uploader.rb, etc.
LFS objects object storage app/uploaders/lfs_object_uploader.rb
CI artifacts object storage app/uploaders/ci/job_artifact_uploader.rb, ci/pipeline_artifact_uploader.rb
Container registry blobs container registry storage external service
Packages object storage app/uploaders/packages/*
Dependency proxy object storage app/uploaders/dependency_proxy/*
Backups object storage gems/gitlab-backup-cli
ML artifacts object storage app/uploaders/ml/*
Pages content object storage app/uploaders/pages_deployment_uploader.rb
Audit events archive object storage EE

CarrierWave + Fog

GitLab uses CarrierWave with the Fog adapter for AWS, GCS, Azure, OpenStack, and S3-compatible providers. Mounted uploaders wrap a model attribute:

class Project < ApplicationRecord
  mount_uploader :avatar, AvatarUploader
end

The uploader knows where the file lives (local disk vs object storage), generates URLs, and handles direct upload.

Direct uploads via Workhorse

Most upload paths use the "Workhorse direct upload" pattern:

  1. Browser POSTs to a Rails endpoint.
  2. Rails responds with a presigned object-storage URL via Gitlab-Workhorse-Send-Data: signed-url.
  3. Workhorse PUTs the body to object storage.
  4. Workhorse calls Rails back with metadata for the finalize step.

This avoids streaming the entire upload through Puma. Implementation in workhorse/internal/upload/ and lib/object_storage/direct_upload.rb.

Migration

When operators flip on object storage, files need to migrate from local disk:

  • Object_storage::Migration::* workers walk uploaders.
  • The configuration object_store_enabled: true plus a "live" mode lets the migration happen with the app running.

Object pool / file deduplication

For very large duplicate blobs (LFS in forks), GitLab uses an object pool managed by Gitaly (ObjectPoolService). LFS blobs are deduplicated by SHA-256 across the storage namespace.

Lifecycle and cleanup

  • RepositoryArchiveCleanUpService and friends sweep stale archive files.
  • ImportExportCleanUpService removes stale import exports.
  • RemoveExpiredJobArtifactsWorker deletes CI artifacts past retention.

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

Object storage – GitLab wiki | Factory