A backup job is deleted after a workload is decommissioned, and the capacity chart does not move. The restore points that job produced are still present, still locked, and still counted against the repository. Nothing in the backup console shows them any more, because the console lists jobs and this data no longer belongs to one. The space comes back when the lock expires, not when the decision to stop protecting the workload was made.
The obvious response is to delete the backups along with the job. On an immutable repository that either fails outright or succeeds only in the backup software's own catalog, which is a different thing from the objects being removed. Object Lock is enforced by the storage, not by the application that wrote the data, and in compliance mode it applies to every caller including the account that created the object.
That separation is the point of immutability, and it is also why capacity planning on a locked repository behaves unlike planning for anything else. Space is released on a clock set weeks or months earlier, by a decision made while the data still had a reason to exist.
Why the lock outlives the reason for the data
Retention on an object repository is applied per object version at the moment of writing. When the backup software uploads a block, a retain-until date is set on that version, derived from the job's retention plus whatever immutability window the repository is configured for. From then the date belongs to the object. The job is a cataloging construct inside the backup application, and the storage has never heard of it.
So deleting a job is a catalog operation. It removes the restore points from the interface, stops future runs, and on a mutable repository it would also issue deletes the storage would honor. Against a locked bucket those deletes are refused, or they create markers that hide the versions while the bytes underneath remain allocated. Behavior differs between the two lock modes, so it is worth confirming which mode a repository was actually created with rather than which one was intended.
Backup software layers its own retention on top, and the two figures do not always agree. A job keeping restore points briefly, writing into a repository with a longer immutability window, produces data the application considers expired and the storage considers protected. What governs the return of capacity is the point at which the lock itself expires, and that date is recorded on the object rather than in the console.
What the storage keeps when nothing references it
Object storage has no concept of an orphan. Every version written and not successfully deleted is a live object, counted the same as data an active job depends on nightly. Versioning, which Object Lock requires, means deletions add versions rather than replacing them, so one key can hold several generations, each with its own retain-until date.
When the backup application deletes an object in a versioned bucket, the storage adds a marker that makes the key appear absent to a normal listing while the previous version remains intact. A capacity report built from current objects will undercount, and one that sums all versions will match the real footprint. The difference between those two numbers approximates the data that has been logically removed and is still physically present.
Incomplete uploads belong in the same category. An interrupted run leaves parts that were never assembled into an object. They consume capacity, do not appear in an object listing, and nothing removes them unless a lifecycle rule aborts them.
Finding locked data that no job owns
The search starts from the storage side, because the console cannot see what it no longer catalogs. A listing of object versions and their retain-until dates, grouped by prefix, usually maps onto jobs and repositories, and the prefixes that do not map are the candidates.
| Signal | What it usually means | What to check |
|---|---|---|
| Used capacity flat after a job was deleted | The objects are still under a lock, and the deletes were refused or turned into markers | Retain-until dates on the oldest versions in that prefix |
| Backup application reports less data than the storage | Application retention has expired while storage immutability has not | Repository immutability window against the job retention that produced the data |
| Bucket size grows while nightly backup volume is steady | Noncurrent versions accumulating behind markers, or abandoned upload parts | Whether a lifecycle rule aborts incomplete uploads or expires noncurrent versions |
| Space released in one step rather than gradually | A block of restore points reached the same retain-until date together | The spread of retain-until dates, so the next step is predicted |
| A prefix nobody can name still holds locked data | A decommissioned workload, a migrated tenant, or a test repository never removed | Creation date, last write time, and which credentials still hold write access |
None of it can be acted on immediately, which is the uncomfortable part. Identifying locked orphaned data does not free it. What it buys is a date, and a date is enough to plan against.
The one class of finding that can be acted on is the unlocked residue: incomplete upload parts, noncurrent versions never subject to a lock, and test buckets where immutability was never enabled. Those respond to a lifecycle rule, a small change with a permanent effect on the growth curve.
What to assume in a budget
The planning rule follows from the mechanism. If the longest immutability window in force is W, a decision to stop protecting a workload reduces consumed capacity no sooner than W after that workload's final write. Until then the capacity is committed. The notation is illustrative, but it is the shape a forecast has to take.
Two consequences follow. Capacity released by a consolidation or a decommissioning project belongs in the model at the end of the longest lock, not at the end of the project. And during a migration both copies exist for the duration of W, so the peak requirement is the sum rather than the larger of the two. That peak is a routine reason for headroom sized as a fixed proportion to turn out insufficient at the wrong moment.
Where ARTESCA fits
ARTESCA is object storage software used as a backup target, deployed on infrastructure the customer runs, at capacities from roughly 50 TB up into the petabyte range. It provides immutable backup storage through S3 Object Lock and serves Veeam and other backup software through the S3-compatible API. Retention set in a console becomes a retain-until date on objects, and that date determines when capacity is reclaimable.
Because enforcement sits at the storage layer, removing a job in the backup application does not release the underlying objects, and the storage view rather than the console view is the accurate source for consumed capacity. Listing object versions and their retain-until dates through the S3 API is the way to find data whose owning job no longer exists.
Lifecycle configuration is available through the same API, which makes the unlocked residue addressable. Aborting incomplete uploads and expiring noncurrent versions that were never locked is ordinary bucket configuration, separate from anything Object Lock governs.
What to write down and when to check it
Once a quarter, compare the total size of all object versions with the total size of current objects, and record both. The trend in the difference measures how much logically deleted data still occupies the platform, and it costs one listing operation to produce.
At the same interval, list the prefixes holding locked data and confirm each still corresponds to a job that exists. Any that does not gets a line in a small register: what it was, when its last write happened, the latest retain-until date in it, and therefore the month its capacity returns. That register turns a future alert into a scheduled event.
Whenever a workload is decommissioned, the note should record the repository, the prefix, the immutability window in force and the resulting release date, before the job is deleted and that information becomes hard to recover. Reviewing lifecycle rules belongs in the same pass, since that is the only part of the problem configuration can solve rather than outlive.
