Template Version Lifecycle
Tektona archives and deletes template versions that nobody uses. Here is what happens, and how to keep the versions you need.
A template version is one immutable build of a template. Every build makes a new one, so a template collects versions.
Tektona clears the ones nobody uses. Two rules do this, and both are on for every organization and project:
- The archive rule archives a version that no sandbox has used for 30 days. Archiving refuses a create from the version. You can undo it.
- The delete rule permanently deletes that version 7 days later. You cannot undo it.
Tag a version to keep it
A tag is the exemption you control. A tagged version is never archived and never deleted. Read Keep a version.
Tektona also keeps the 3 newest versions of every template from the delete rule. That floor is the platform's, not yours, and it moves as you build.
Keep a version
Put a tag on it. The version is then exempt from both rules, and it stays exempt while the tag stays.
In the console, open the template and go to the Versions tab. Open Edit tags from the version's row, or from the version's own page. Add a tag, move one here from another version, or take one off.
A tag name is yours to choose. A tag is a name, not a lifecycle state, so a tag you use for releases and a tag you use only to keep a version work the same way.
One template can carry at most 500 tags. At this limit, you can move or remove an existing tag. A build that requests a new tag fails and publishes no version.
You can tag an archived version. The version stays archived, and a sandbox create through that tag fails until you activate the version.
Removing the last tag puts the version back under both rules. Its own clocks then decide what happens.
To pin a version from a script, write the tag through the API:
curl -X PUT \
"https://api-dev.tektona.ai/v1/orgs/acme/projects/backend/templates/go-dev/tags/keep" \
-H "Authorization: Bearer $TEKTONA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"version_id": "01K5V0Q2R7M8N9P0Q1R2S3T4U5"}'Bring an archived version back
Archiving is reversible, and the control sits where the archiving happened.
Open the template and go to the Versions tab. An archived version's row offers Activate, and so does the version's own page. Activating restores the version exactly as it was: a create from it works again, and any tag naming it resolves again.
Activating also clears the delete rule's clock. A version archived a second time starts that window again from the second archive.
A template you archived has its own Activate on the template's page, which returns every version below it to whatever state each one held.
Archiving a template does not stop the rules. It restarts them. Read An archived template.
A deleted version does not come back
There is no undo for a delete. Rebuild the template to get a working version again — the new version is a new build, with a new id, and any tag you need must be put on it. This is why the archived window exists: it is the time you have to notice.
See what is coming
Every version says what the rules will do to it. Read it on the Versions tab, where each row carries a lifecycle label, and on the version's own page, which adds a line on what to do about it.
| Label | What it means |
|---|---|
Archives in 12d | The archive rule takes this version in 12 days. |
Deletes on the next sweep | Every window has run out. The next run takes it. |
Kept by a tag | A tag exempts it from both rules. |
One of the newest | The delete rule never takes it. It is one of the 3 newest versions of this template. |
Not scheduled | No rule will take it as things stand. |
Not scheduled is not a guarantee
Not scheduled means no rule will take the version right now, and that a tag is
not what is keeping it. A sandbox may still record it, or the rules may be off
for that scope. Either can change without you doing anything. Tag the version if
you need it kept for certain.
The same answer is on the API. A version read, and each version in a listing, carries two fields:
{
"id": "01K5V0Q2R7M8N9P0Q1R2S3T4U5",
"state": "active",
"tags": [],
"pending_rule": "archive",
"pending_rule_at": "2026-10-14T09:12:44Z"
}pending_ruleisarchiveordelete.pending_rule_atis the date that rule acts, at the earliest. A date in the past means the next run takes the version.
Both fields are absent when no rule will take the version. That absence covers
the Kept by a tag case and the Not scheduled case together. The version's
own tags tells the two apart: a name in it is what keeps the version, and an
empty list means something else does.
Can you still create from it
A version carries two more fields, and they answer a different question: not what a rule will do to it, but whether a sandbox create through it works now.
{
"id": "01K5V0Q2R7M8N9P0Q1R2S3T4U5",
"state": "active",
"creatable": false,
"create_refused_by": "template"
}creatableis whether a create through this version is allowed.create_refused_byistemplateorversion, and it names the level that refuses. It is absent when a create is allowed.
Read create_refused_by before you act. A create resolves the template first,
so an archived template refuses every version below it. Those versions keep
reading "state": "active", because archiving a template writes nothing on a
version. create_refused_by: "template" is the only field that says so, and
activating the version alone changes nothing.
tektona template version get, tektona template tag get and
tektona template version ls all print this answer, and the console shows it
beside the state badge.
Archive and delete
The two outcomes are not two grades of the same thing. One is reversible and one is not.
| Archived | Deleted | |
|---|---|---|
| Reversible | Yes, activate the version | No |
| Create a sandbox from it | No | No |
| Sandboxes already running from it | Unaffected | Unaffected |
| Its stored image | Kept | Released |
Archiving refuses a create from a version, and does nothing else. Activating the version brings it back exactly as it was.
A running sandbox never breaks. It runs, restarts, resumes and forks from the version and the image it already holds, whatever happens to the version record.
A tag survives an archive. The tag keeps naming the version. A sandbox create through that tag fails while the version is archived, and works again when you activate the version.
Archiving frees no storage
An archived version keeps its bytes, and you keep paying for them. Only a delete releases them. A shorter archive window stops a create from a version sooner and changes no storage bill. The delete window is the one that does.
Even a delete does not free the bytes at that moment. Tektona removes the stored image on a later pass, once no version and no sandbox still needs it. Two versions can share one image, and that image goes only when the last of them goes.
What each rule counts
The archive rule counts days of non-use, not days since the build. A version is in use while any sandbox holds it. The clock starts when the last sandbox that used it finishes its teardown. So a version somebody launched a sandbox from a year ago is not idle while that sandbox still exists.
Using a version in a sandbox starts its clock again. Tagging it stops the clock.
The delete rule counts days since the archive. That count starts again if you activate the version and it is archived a second time.
Neither rule reaches back over history. Each window starts when that rule is turned on for the scope, so a rule you arm today takes nothing today.
An archived template
Archiving a template blocks every create below it, so all of its versions go idle at once. The rules do not stop there. They start again.
Both windows count from the moment you archived the template, not from each version's own last use. So a template you archive today keeps everything for 30 days, then archives its versions, then waits another 7 days before it deletes any of them. Activating the template clears that moment and each version's own clock decides again.
This is what makes an archived template's storage fall. Archive is the verb to reach for instead of delete, and a template that held every byte for as long as it sat archived made it the wrong one.
An archived template keeps a usable shelf
The delete rule never takes the 3 newest versions of a template. So a template
you archive and come back to a year later still has versions to activate, rather
than an empty shelf. tektona template get reports what the template holds in
storage while it is archived.
What the rules never take
- A tagged version. This is your exemption, and it covers both rules.
- A version a sandbox still holds, in any state, paused included.
- The 3 newest versions of a template. The delete rule never takes one. The archive rule still does, because archiving is reversible and frees nothing.
- A version you archived yourself. The delete rule takes only what the archive rule archived. A hand archive means "keep this, out of the create menu", and it starts no countdown.
- The
tektona/*catalogue. Those templates belong to no organization, so no rule owner exists for them.
Clear the unused versions now
The rules run on their own clock. To clear a template today, run:
tektona template version prune go-devIt removes every version of that template that nothing uses. A version is unused
when no tag points at it and no sandbox records it. It lists what it removes and
asks first; --yes skips the question. The console offers the same action on
the template's Versions tab.
The two protections are absolute here, exactly as they are in the rules. A tag is your opt-out, so move or delete the tag first if you want the version gone. A sandbox that records the version keeps it, and a paused sandbox counts, one whose teardown has not finished counts, and so does every fork. The report says how many versions it kept for each reason.
A version's own state is not a test. An unused active version goes the same way an unused archived one does, so read the list before you answer.
Change the rules
Open Settings → Template Lifecycle, on an organization or on a project. There are four values:
| Value | Field | Default | Range |
|---|---|---|---|
| Archive rule | archive_enabled | On | On or off |
| Archive after | archive_after_days_unused | 30 days unused | 1 to 60 days |
| Delete rule | delete_enabled | On | On or off |
| Delete after | delete_after_days_archived | 7 days archived | 1 to 30 days |
The page states the two windows as one chain, because that is what a version lives through: 30 days unused, then 7 days archived, so 37 days from a version's last use to gone.
A project's own value applies to its templates. A project that sets none takes its organization's value. An organization that sets none takes the platform default above. Resolution is per value, so a project can set the archive window alone and keep inheriting the other three. Each value on the page says whether it is set here or inherited, and from which scope. Reset to inherited clears one value and returns it to the scope above.
Reading needs read access to the scope. Writing needs the admin role.
The same values are on the API:
GET /v1/orgs/{org}/settings/template-lifecycle
PUT /v1/orgs/{org}/settings/template-lifecycle
GET /v1/orgs/{org}/projects/{project}/settings/template-lifecycle
PUT /v1/orgs/{org}/projects/{project}/settings/template-lifecycleA PUT replaces the whole scope. A value you leave out of the body goes back to
inheriting, so send every value you want to keep.
Try a change before you save it
The settings page runs a dry run as you type, before you save anything. It reports, for each rule:
- how many versions the rule takes on its next run,
- how many more or fewer that is than your saved values take,
- how much storage the change eventually reclaims,
- a sample of the versions, each with the reason the rule takes it or leaves it.
Nothing is written, so you can change a number and read the effect as often as you want.
Read the two storage figures carefully. The archive rule reports zero, because archiving frees nothing. The delete rule's figure is what Tektona reclaims once its storage pass runs, which is a later moment. An image that two versions share is counted once, and only when the rule takes both of them.
A scope can hold more versions than one dry run reads. The page says so, and every number is then a floor rather than a total.
The dry run is also on the API, at
PUT /v1/orgs/{org}/projects/{project}/settings/template-lifecycle/preview and
at the matching organization path. The body is the values you propose, in the
fields named in the table above.