Table of Contents
Manage Artifacts in Jenkins
Summary: This wiki page shows how to handle retention on artifacts and buils in Jenkins.
Date: 28 May 2026
When working with pipelines you need to maintain proper housekeeping. Cleaning up builds and artifacts is essentials in keeping your build systems healthy and Jenkins is no exception to this rule. In the examples below we'll see how to manage artifacts and builds in Jenkins in two different ways, bothe for the “Declarative Pipeline syntax” as well as for the “Scripted Pipeline syntax”.
Declarative Pipeline Syntax
When using the declarative pipeline syntax the retention settings are part of a top-level block at the start of the pipeline, inside of the pipeline { … } block. So let's say you have a pipeline with a few stages, some parameters and a trigger. Adding the retention option is then only a matter of adding a options block to the pipeline, as seen in this example:
pipeline { triggers { // Run pipeline Mon-Fri at 2:30am from main branch cron(env.BRANCH_NAME == 'main' ? '30 2 * * 1-5' : '') } options { buildDiscarder(logRotator( artifactDaysToKeepStr: '14', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '50' )) } parameters { string( name: 'TEST_ENVIRONMENT', defaultValue: 'tst', description: 'Choose test environment' ) } environment { TZ = 'Europe/Amsterdam' // Set timezone } stages { stage('Check OS') { steps { sh 'cat /etc/os-release || echo "No /etc/os-release found"' sh 'uname -a' } } stage('Checkout') { steps { // Checkout Git repository checkout scm } } } }
Scripted Pipeline Syntax
When using the Scripted Pipeline Syntax the retention setting are not part of the pipeline block, but instead are part of a top level properties block. So to give an example for a simple pipeline with just one stage, you can see that the LogRotator class is outside of the pipeline itself and in it's own top-level properties block:
podTemplate(label: 'shift-coordination-pod', cloud: 'kubernetes', serviceAccount: 'shift', yaml: """ apiVersion: v1 kind: Pod """, volumes: []) { node('shift-coordination-pod') { if (env.BRANCH_NAME ==~ /feature\/.*/) { echo "Skipping build for feature branch" return // return to stop subsequent stages from firing. } stage('Checkout source') { scm_result = checkout scm COMMITHASH = scm_result.get('GIT_COMMIT') } } } properties([[ $class: 'BuildDiscarderProperty', strategy: [ $class: 'LogRotator', artifactDaysToKeepStr: '14', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '50'] ] ]);
Verify in the User Interface
If you want to check the setting using the Jenkins User Interface, you can go to the job. From there, go to 'View Configuration'. Verify the “Discard old builds” under General, and expand the advanced setting for the artifact cleanup settings.
Determine Settings
Jenkins will always keep the number of builds and artifacts as you have configured. This is best explained with an example. Let's say you have 100 builds, all created in the last 10 days, with exactly 10 builds per day. With the following settings, no builds would be deleted because the “daysToKeepStr” is set to 14 days:
options { buildDiscarder(logRotator( artifactDaysToKeepStr: '14', artifactNumToKeepStr: '', daysToKeepStr: '14', numToKeepStr: '50' )) }
However, if you would change the settings like these:
options { buildDiscarder(logRotator( artifactDaysToKeepStr: '14', artifactNumToKeepStr: '', daysToKeepStr: '4', numToKeepStr: '50' )) }
it would delete the 50 most oldest builds, because now the “numToKeepStr” will prevent the deletion of the builds of the 5th day.
When determining the setting you need you should consider not only the system limitations and user requirements, but also any regulatory requirements that should exist. Always adhere to the most restrictive requirements, and have Jenkins handle the rest.
