Harbor Garbage Collection: Architecture, Capabilities, and API Usage
Harbor's garbage collection is a job-driven subsystem that removes unreferenced blobs and tags through manual or scheduled runs, with dry-run support, configurable workers, and time-window protection.
Harbor's garbage collection (GC) subsystem in the goharbor/harbor repository provides a comprehensive solution for reclaiming storage by removing untagged images and unreferenced layers. Implemented as a first-class job service within the controller/gc package, it exposes granular control via the v2.0 system API while maintaining data safety through configurable time-window protections and concurrent execution limits.
Core Architecture of Harbor Garbage Collection
The GC subsystem follows a layered architecture separating business logic from execution mechanics.
GC Controller and Policy Model
At the heart of the system lies the GC controller (src/controller/gc/controller.go), which implements business logic for starting, stopping, and scheduling collections. The controller relies on the Policy model defined in src/controller/gc/model.go, which encapsulates:
- Deletion flags:
delete_untaggedanddelete_tagcontrol whether untagged layers or specific tags should be removed - Dry-run mode: Simulates deletion without removing data
- Worker concurrency: Validates 1-10 parallel workers via
validateWorkers - Time-window: Prevents deletion of recently uploaded blobs
Job Service Integration
Actual GC execution is delegated to Harbor's Jobservice as a job of type job.GarbageCollectionVendorType. When triggered, the controller creates an execution via c.exeMgr.Create followed by a task through c.taskMgr.Create (lines 86-99 in src/controller/gc/controller.go). This separation allows the controller to manage metadata while the Jobservice handles resource-intensive blob removal.
Configuration and Time-Window Protection
Safety is enforced through a configurable time-window that prevents garbage collection of blobs uploaded within recent hours. The default window of 2 hours is defined in src/common/const.go as DefaultGCTimeWindowHours, exposed via config.GetGCTimeWindow() in src/lib/config/systemconfig.go. This ensures recently pushed artifacts remain available during concurrent operations.
Harbor Garbage Collection Capabilities
Harbor provides multiple operational modes and safety mechanisms for storage reclamation.
Manual and Scheduled Execution
Manual GC triggers immediate collection via controller.Start, accessible through the /system/gc API endpoint. For automation, Scheduled GC uses Harbor's generic scheduler (pkg/scheduler) through controller.CreateSchedule, supporting cron expressions for hourly, daily, or custom intervals.
Deletion Policies
The system supports two primary deletion targets:
- Untagged images: Removes layer blobs no longer referenced by any tag when
delete_untaggedis enabled - Specific tags: Allows bulk tag removal via the
delete_tagflag for large-scale cleanup operations
Safety Features
Dry-run mode executes garbage collection logic without deleting backend storage, enabling administrators to audit what would be removed. Combined with the time-window protection (default 2 hours), these features prevent accidental data loss during active development workflows.
Concurrency and Monitoring
Administrators control resource utilization through the workers parameter (1-10), validated by validateWorkers in the API handler. Real-time monitoring is available through execution history APIs (GetGCHistory, GetGC), while GetGCLog retrieves detailed task logs for troubleshooting.
Code Flow for Harbor Garbage Collection
A manual garbage collection run follows this execution path:
- API Request: HTTP POST to
/system/gc/scheduleinvokesgcAPI.CreateGCSchedulewithScheduleManualtype - Policy Construction:
gcAPI.kickbuilds a Policy structure, injecting runtime parameters includingredis_url_regandtime_windowfrom system configuration - Execution Creation:
controller.Startgenerates a Jobservice execution viac.exeMgr.Createand linked task viac.taskMgr.Create - Job Execution: Jobservice runs the GC worker respecting policy flags (dry-run, workers, deletion settings)
- Status Tracking: Execution metadata and logs are stored in task tables, queryable via
GetGCandGetGCLog
API Usage Examples
Interact with Harbor garbage collection through the v2.0 REST API.
Triggering Manual Garbage Collection
Execute immediate collection with custom workers and untagged deletion:
curl -u admin:HarborSecret \
-X POST \
-H "Content-Type: application/json" \
-d '{
"schedule": {
"type": "Manual",
"cron": ""
},
"parameters": {
"delete_untagged": true,
"delete_tag": false,
"dry_run": false,
"workers": 4
}
}' \
https://harbor.example.com/api/v2.0/system/gc/schedule
This invokes gcAPI.kick → controller.Start as implemented in src/server/v2.0/handler/gc.go.
Scheduling Recurring Garbage Collection
Create a daily scheduled job using cron syntax:
curl -u admin:HarborSecret \
-X POST \
-H "Content-Type: application/json" \
-d '{
"schedule": {
"type": "Daily",
"cron": "0 0 * * *"
},
"parameters": {
"delete_untagged": true,
"workers": 5
}
}' \
https://harbor.example.com/api/v2.0/system/gc/schedule
The ScheduleDaily path in the kick function creates a persistent schedule via controller.CreateSchedule.
Monitoring and Managing Executions
Retrieve execution history:
curl -u admin:HarborSecret \
"https://harbor.example.com/api/v2.0/system/gc/history?page=1&page_size=20"
This calls gcAPI.GetGCHistory, which gathers data through controller.ListExecutions.
Stop a running job:
curl -u admin:HarborSecret \
-X POST \
https://harbor.example.com/api/v2.0/system/gc/123/stop
The gcAPI.StopGC handler forwards to controller.Stop to abort the Jobservice execution.
Fetch task logs:
curl -u admin:HarborSecret \
https://harbor.example.com/api/v2.0/system/gc/123/log
gcAPI.GetGCLog returns raw log bytes from controller.GetTaskLog for debugging failed collections.
Summary
- Harbor garbage collection operates as a job-driven subsystem within
src/controller/gc, delegating actual work to the Jobservice while maintaining execution metadata separately - The Policy model supports granular controls including dry-run mode, untagged/tag deletion, and configurable worker concurrency (1-10)
- A time-window protection mechanism (default 2 hours) prevents removal of recently uploaded blobs via
config.GetGCTimeWindow()insrc/lib/config/systemconfig.go - Administrators can trigger collections manually via
controller.Startor create scheduled runs using the generic scheduler throughcontroller.CreateSchedule - Full lifecycle management is available through the v2.0 API, including execution history queries, real-time stopping via
controller.Stop, and log retrieval throughGetGCLog
Frequently Asked Questions
What is the default time window for Harbor garbage collection?
Harbor implements a 2-hour time window by default, defined as DefaultGCTimeWindowHours in src/common/const.go. This safety mechanism, exposed through config.GetGCTimeWindow() in src/lib/config/systemconfig.go, ensures blobs uploaded within the last two hours are excluded from deletion during garbage collection runs.
Can I run Harbor garbage collection without deleting data?
Yes, Harbor supports dry-run mode through the dry_run parameter in the GC Policy. When enabled, the system executes all garbage collection logic and reports what would be deleted without actually removing any blobs from storage, enabling safe auditing of reclaimable space.
How many parallel workers can Harbor garbage collection use?
Harbor garbage collection supports 1 to 10 parallel workers, validated by the validateWorkers function in src/server/v2.0/handler/gc.go. This concurrency control allows administrators to balance collection speed against system resource utilization by setting the workers parameter in the API request.
Where are Harbor garbage collection logs stored?
Garbage collection logs are stored within Harbor's task management system and retrieved via controller.GetTaskLog. Administrators access these through the /api/v2.0/system/gc/{execution_id}/log endpoint, which returns raw log bytes from the underlying task manager for troubleshooting specific GC executions.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →