Open table of contents
S3 Object Lock asks for a retention duration: 30 days, 90 days, a year. A longer duration can preserve more recovery options, but it also extends the period during which data cannot be deleted and storage must be funded. In Compliance mode, ordinary operations cannot delete a protected version or shorten its retention, even when performed by the account root user. [1]
The first decision is therefore not a number of days. It is how far back a healthy recovery point may be, and how long every dependency needed to restore it must remain protected. Derive a lower bound from recovery timing, then determine whether cost and deletion obligations permit adopting it.
This design note follows What S3 Object Lock Protects. The previous article covers implementation, permissions and restoration; this one explains the decision behind days = N. Values are illustrative assumptions.
1. Separate four clocks
Do not use “retention” interchangeably for the immutable period, backup storage lifetime and business-record obligations. Archive storage adds a fourth clock: the storage class’s minimum billable duration.
| Clock | Starting point and meaning | What happens at the boundary |
|---|---|---|
| Fixed Object Lock | Version creation plus default duration, or an explicit retain-until date | Retention protection ends, subject to other holds and conditions |
| Storage and Lifecycle | Current-version creation, becoming noncurrent, or another configured basis | An action becomes eligible; deletion is not immediate |
| Business or contractual deadline | Contract end, record creation, receipt of a deletion request, etc. | Defines the required preservation or deletion outcome |
| Storage-class minimum | The applicable storage/billing start for that class | Determines remaining-duration charges on early removal or transition |
Governance allows exceptions when the required permissions and explicit bypass request are present. “Nobody can delete during retention” is therefore not a statement about every mode. AWS also documents account deletion as an exception for Compliance; Object Lock does not protect the account’s continued existence or every administrative boundary. [1][2]
The example uses fixed retention. Distinguish a time-bound retention period from Legal Hold, which remains until explicitly removed, and define who may set or remove each control. [1]
2. Derive a lower bound from the age of a healthy recovery point
If compromise starts on Day 0 and is detected on Day 21, a Day 20 backup is not necessarily safe. The requirement is a healthy recovery point selected through investigation and validation. Initial compromise and data corruption may occur at different times; credentials, application software and configuration may require different rollback decisions.
An industry average dwell time or internal P95 is not a maximum detection delay. Separate historical evidence, undetected activity and missing logs, and record the design-bound assumption and residual risk you accept.
For independent full backups, start with a conservative serial model:
R >= G + D + I + X + M
G = gap to the completed healthy backup before compromise
D = assumed maximum delay from compromise to detection
I = investigation and recovery-point selection
X = retrieval, clean recovery and business validation
M = margin for uncertainty
Illustrative lower bound: 1 + 21 + 7 + 3 + 14 = 46 days
Configured candidate: 50 days (4 additional days of rounding)
G is the gap to a completed healthy backup before compromise. Include failed jobs, delay and consistent snapshot timing rather than using the schedule alone. Object Lock’s clock is tied to version creation/upload, so reconcile actual capture times with each version’s creation timestamp.
Scroll horizontally to view the complete diagram.
Read the diagram as text
Add the pre-compromise backup gap G, detection D, investigation I, recovery validation X and uncertainty M. The example totals 1 + 21 + 7 + 3 + 14 = 46 days and rounds to 50. These are assumptions, not measurements.
With G=1, D=21, I=7, X=3, M=14 days, the candidate lower bound is 46 days. We use 50 days as an illustrative configured value and record the four days of rounding headroom. The simpler 21+7+3+14=45 misses the gap to the pre-compromise backup. If investigation and recovery preparation overlap, refine the model using the actual critical path; the sum is not a precise forecast.
X includes clean-environment preparation, identity recovery, archive retrieval, transfer, database restoration and business validation. Protection that expires when investigation finishes can leave recovery dependencies exposed while restoration is still running.
3. Distinguish RPO, point density and dependency retention
Hourly backups can provide fine recovery-point density, but do not establish a one-hour RPO without successful, consistent captures. Cyber recovery to a pre-compromise state can also involve much more business-data loss or reconciliation than the RPO for an ordinary outage.
Hourly backups over 45 days schedule 1,080 points; daily backups schedule 45. Scheduled points are not the same as healthy, restorable points. Count them with manifests and validation evidence.
Incremental backup requires more than retaining each new increment. If a Day 0 full supports Day 1–6 increments, and every object gets 50 days from its own creation, the full becomes deletable on Day 50 while increments remain locked. Those increments may no longer be recoverable. Reused deduplication chunks create the same problem.
Scroll horizontally to view the complete diagram.
Read the diagram as text
Protect the full, increments, WAL, catalog and manifest through their required use date. Fifty days from each upload can expire the full before its dependents. Keys and access remain separate dependencies.
The necessary constraint is stronger than “lock every object for the same number of days”:
For every recovery point p and every dependency v in deps(p):
protect_until(v) >= required_use_until(p)
Check: full + increments + WAL + catalog + manifest + shared chunks
Also preserve: decryption capability + reader access + restore tools
Enumerate fulls, increments, WAL, indexes, catalogs and manifests, and protect them through the shared required deadline. Verify that the backup product’s retention integration and garbage collection understand this dependency set. The oldest full may require longer protection than newer points. Decryption keys, reader permissions and recovery software must remain usable too; Object Lock does not prevent KMS key deletion. [8]
Hourly seven-day, daily 50-day and weekly 180-day classes are possible, but an object tag does not apply retention by itself. The backup process must use bucket defaults or explicit version settings and verify the resulting metadata. Explicit settings override the bucket default. [1]
4. Identify deletion conflicts before configuration
Requiring the same version to remain undeletable under Compliance for 90 days and to be physically deleted within 30 days is incompatible under ordinary operations. This is a requirements conflict, not a missing configuration option.
Specify the deletion deadline’s starting point: 30 days after contract termination is different from 30 days after data collection. Agree with privacy, contractual and records-management owners on residual backup storage, use restrictions and deletion reapplication after a restore. Do not assume backups have a universal exemption from deletion obligations.
| Data role | Retention questions | Reason to separate it |
|---|---|---|
| Recovery backup | Healthy-point search window, dependencies and business restoration | Its purpose is restoration |
| Authoritative record archive | Preservation obligations, integrity, search and production of records | It serves a system-of-record role |
| Incident evidence | Specific versions, custody and release conditions | Investigation determines ongoing need |
| Temporary exports or deletion-sensitive data | Whether storage is necessary and when deletion is due | Long locks may be unsuitable |
Packaging multiple people’s data into one object can make selective deletion difficult. Packaging affects deletion granularity as well as cost. Consider preserving a separate deletion ledger and reapplying it during restoration so previously deleted data is not republished.
Destroying a key is not automatically equivalent to deleting an object. Its legal sufficiency requires separate review, and destroying a shared key can eliminate unrelated recovery points. Do not treat it as a routine workaround for deletion conflicts.
5. Assign owners for Governance, Compliance and holds
Governance is a candidate when testing operations and durations while preserving narrowly controlled exceptions. Bypass requires s3:BypassGovernanceRetention and an explicit request, alongside permission for the underlying operation. The console includes the bypass header by default, so inspect the operator’s permissions when exercising deletion through the UI. [1][2]
Before adopting Compliance, complete reviews of data scope, restoration, cost, deletion obligations, Lifecycle and separation of authority, and accept that the duration cannot be shortened. Do not choose long Compliance retention and only then consider deletion exceptions. Expanding Governance bypass authority also changes the threat model if an attacker can acquire that authority.
Legal Hold protects a version indefinitely and independently of fixed retention. It can preserve incident evidence, but needs an owner, release authority and a review date. Removing it does not remove an active retention period. [1]
At incident detection, verify that candidate points and their full backups and manifests can be preserved before they become vulnerable to deletion. Legal Hold cannot recover an already deleted version. Do not use an untested emergency-preservation procedure as a reason to shorten routine protection unconditionally.
6. Estimate cost from stored bytes, not lock duration
A first approximation multiplies newly stored physical bytes per day by their actual storage lifetime. Measure fulls, increments, compressed objects, versions and metadata rather than logical data changes alone.
V = newly stored physical GiB per day
L = actual storage lifetime in days
P = price per GiB-month, normalized from the selected price source
Steady-state payload GiB ~= V * L
Single-class monthly payload cost ~= V * L * P
(approximation when stored payload is billable throughout L)
Add: requests + transitions + retrieval + minimum-duration charges
+ object metadata + temporary restored copies + replication
+ transfer + KMS + inventory / analysis
Let R be the lock duration and L the storage lifetime. If L remains 90 days, reducing the lock from 45 to 30 days does not immediately reduce storage cost without changing the storage/deletion policy. Changing the bucket default also does not shorten existing Compliance versions.
For a constant 200 GiB/day stored in one class, consider the following steady-state estimates. The period is storage lifetime L, not necessarily lock duration.
| Storage lifetime L | Approximate stored volume | TiB equivalent |
|---|---|---|
| 30 days | 6,000 GiB | 5.86 TiB |
| 45 days | 9,000 GiB | 8.79 TiB |
| 50 days | 10,000 GiB | 9.77 TiB |
| 90 days | 18,000 GiB | 17.58 TiB |
| 180 days | 36,000 GiB | 35.16 TiB |
One TiB is 1,024 GiB. For example, 150 GiB × 45 days is 6,750 GiB, approximately 6.59 TiB, not 6.75 TiB. When supplying prices, reconcile the quotation’s GB units with the model’s GiB units. [9]
A daily 1 TiB full across 45 generations stores 45 TiB. One initial 1 TiB full plus 44 daily 50 GiB increments contains 3,224 GiB, but that is the payload of one finite chain. Steady-state operation adds new fulls, overlapping chains, extended shared-chunk lifetimes, indexes and replicas.
Distinguish inventory bytes from billable bytes as well. Lifecycle eligibility and physical removal can occur at different times; AWS documents billing cessation for expired objects awaiting processing. A current-version delete marker alone does not establish that billing for the surviving data version has ended. Reconcile billing conditions per version and class. [6]
Measure daily new bytes, version counts, object-size distribution, bytes by class and peaks during full-backup rotation. Monthly storage uses average retained volume; capacity and budget headroom also need peak and growth estimates. Record the region, date and pricing tier instead of treating this article as a current AWS price quote.
7. Choose storage classes against RTO and billing minimums
Object Lock protection persists across storage classes, and Lifecycle transitions remain available. Lower-cost storage does not by itself establish recovery within the required time. [2]
| Class | Minimum storage duration | Retrieval characteristic | Cost and constraint review |
|---|---|---|---|
| Standard | None | Immediate access | Storage and request charges |
| Standard-IA | 30 days | Immediate access | 128 KB minimum billable size, retrieval fees, Lifecycle transition timing |
| Glacier Instant Retrieval | 90 days | Immediate access | 128 KB minimum billable size and retrieval fees |
| Glacier Flexible Retrieval | 90 days | Restore required before access | Retrieval option, requests, metadata and temporary restored copy |
| Glacier Deep Archive | 180 days | Restore required before access | Longer retrieval delay and similar additional charges |
AWS describes ordinary Standard Retrieval as typically 3–5 hours for Flexible Retrieval and within 12 hours for Deep Archive; Deep Archive Bulk typically completes within 48 hours. These are not business-recovery guarantees. Object size, total volume, retrieval method and limits affect timing, followed by transfer, unpacking, database restoration and validation. An only recovery point in Deep Archive does not fit a two-hour RTO on this basis. [3][4]
Evaluate the minimum duration as residence in the selected class. A 50-day lock does not preclude a 90-day-minimum class if storage continues longer. Conversely, a design that deletes data 43 days after transition must include the remaining-duration charge. Even with that charge, whether it is economical depends on actual rates and access volume. [5][9]
Small objects also matter. Current Lifecycle defaults do not transition objects below 128 KB; configurations predating September 2024 can retain earlier behavior until modified. Flexible Retrieval and Deep Archive add per-object metadata billed as 8 KB at Standard rates and 32 KB at archive rates. Include object count, request pricing and minimum billable size. [5]
Compression, increments and aggregation can reduce cost, but trade off restore granularity, parallelism, corruption impact and selective deletion. Inspect backup format and storage policy before reducing the recovery window.
8. Read Lifecycle on a per-version timeline
Retention expiry does not automatically delete data. In a versioning-enabled bucket, expiration { days = 60 } also does not mean physically deleting the data version at 60 days. It ordinarily creates a delete marker and makes the prior current version noncurrent. [6]
Configure NoncurrentVersionExpiration separately. Its clock starts when the version becomes noncurrent, not when it was created; S3 uses the successor version’s creation time. Day calculations round to the next midnight UTC, and execution is asynchronous. [6][7]
Scroll horizontally to view the complete diagram.
Read the diagram as text
For a unique key, the example locks 50 days, expires the current version at 60 days and expires noncurrent versions after seven days. Deletion is nominally after 67 days, with rounding and asynchronous delay. Overwritten keys become noncurrent earlier.
Suppose a unique key is written once, locked for 50 days, given current expiration at 60 days and noncurrent expiration after seven days. The data deletion eligibility point is approximately after 60 + 7 days. Rounding and processing delays mean this is not a guarantee of physical deletion on Day 67. At 200 GiB/day, a nominal 67-day payload lifetime already means about 13,400 GiB, versus 10,000 GiB for the 50-day lock alone.
If the same key is overwritten on Day 1, however, the old version’s noncurrent clock starts then. It can satisfy the seven-day condition while still locked and become a deletion candidate after the lock expires, assuming no other holds or blockers. “60 days current plus seven noncurrent” therefore does not guarantee every version survives at least 67 days either.
Legal Hold, replication state, filters and any configured newer-version-count requirement also affect deletion. Lifecycle does not guarantee a strict physical-deletion deadline. Where legal or contractual deadlines exist, design headroom, monitoring and escalation before the deadline. [6]
9. Connect a decision record to OpenTofu
Prepare the review record before translating its values into configuration. Do not write unearned approvals such as reviewed: true.
# Illustrative decision, not an approval record.
id: RET-RECOVERY-001
status: PROPOSED
execution_status: NOT_RUN
data_scope: independent-full-backups-under-unique-keys
mode: GOVERNANCE
model_days: { gap: 1, detection: 21, investigation: 7, recovery: 3, margin: 14 }
calculated_minimum_days: 46
candidate_lock_days: 50
storage_class: STANDARD
lifecycle:
current_expiration_days: 60
noncurrent_expiration_days: 7
physical_deletion_deadline_guaranteed: false
reviews:
recovery: null
cost: null
deletion_obligations: null
approval: null
The following is a configuration fragment for an existing recovery bucket, compared with the public AWS Provider 6.45.0 schema. Refer to the preceding implementation article for a versioning/Object-Lock-enabled bucket, separated permissions, encryption and audit. This fragment is not a complete secure backup environment. [10]
# RET-RECOVERY-001. Existing bucket must already have Versioning
# and Object Lock enabled. NOT_RUN; merge the complete Lifecycle rule set.
locals {
gap_days = 1
detection_days = 21
investigation_days = 7
recovery_days = 3
margin_days = 14
minimum_required_days = (
local.gap_days + local.detection_days + local.investigation_days
+ local.recovery_days + local.margin_days
)
retention_days = ceil(local.minimum_required_days / 5) * 5
}
resource "aws_s3_bucket_object_lock_configuration" "recovery" {
bucket = var.bucket_name
rule {
default_retention {
mode = "GOVERNANCE"
days = local.retention_days
}
}
}
resource "aws_s3_bucket_lifecycle_configuration" "recovery" {
bucket = var.bucket_name
rule {
id = "recovery-versions"
status = "Enabled"
filter { prefix = "backups/" }
# Current expiration normally creates a delete marker.
expiration { days = 60 }
# Count from becoming noncurrent, not from upload.
noncurrent_version_expiration { noncurrent_days = 7 }
}
rule {
id = "remove-empty-delete-markers"
status = "Enabled"
filter { prefix = "backups/" }
expiration { expired_object_delete_marker = true }
}
}
The example assumes Governance, Standard storage and independently restorable backups under unique keys. It connects the calculation to the default and shows both current and noncurrent Lifecycle actions. The bucket default applies to new versions throughout the bucket, while this Lifecycle example only targets backups/. Define storage policy for other prefixes separately. For an existing bucket, manage its entire Lifecycle rule set as one configuration; do not add a competing resource that overwrites unrelated rules.
Download the decision record, calculation tables, configuration fragment and review materials. OpenTofu init, validate, plan and apply have not been run. The dependency lock file is .terraform.lock.hcl; none is supplied because initialization was not performed. Review the actual runtime, provider resolution, state and permissions separately. [11]
Changing a bucket default does not retroactively rewrite every version’s deadline. Reducing the default from 50 to 30 days cannot shorten existing Compliance retention. If extensions are necessary, inventory versions and dependencies and create an explicit change plan. [1]
10. Scope guardrails to APIs and exceptions
The s3:object-lock-remaining-retention-days condition key can constrain minimum and maximum remaining retention for PutObjectRetention. AWS documents a maximum period of 100 years; that is not a recommendation. [2]
To deny requests below 46 days or above 90 days, use separate statements for the bounds. Putting both comparisons into one Condition combines them with AND, accidentally requiring “below 46 and above 90” simultaneously. These are remaining days at request time, not the version’s age.
This guard alone does not establish coverage of every configuration path. Review bucket-default changes, explicit retention on PUT, Copy, replication, requests without the key, Legal Hold, Governance bypass and authority to change the policy. A strict upper bound can also block a necessary incident-preservation extension.
A request to extend retention may also exceed the allowed remaining-day limit. If emergency extensions are required, define the authorized principal and approval conditions. [2]
11. Verify both preservation and eventual deletion
Recovery exercises should measure safe-point selection, dependency retrieval, transfer, restoration and business validation. A rejected deletion during retention does not establish recovery capability.
| Exercise | Expected evidence | Current status |
|---|---|---|
| Version-specific DELETE while locked | Object Lock denial for a principal with delete permission but no bypass | NOT_RUN |
| DELETE without a version ID | Distinguish a delete marker from deletion of the original version | NOT_RUN |
| Full and incremental restoration | All dependency deadlines, hashes and business consistency | NOT_RUN |
| Expired retention with no hold | Authorized deletion succeeds; track Lifecycle separately | NOT_RUN |
| Legal Hold on and then released | Separate effects of the hold and remaining retention | NOT_RUN |
| Archive recovery | Retrieval request through business resumption, with time and cost | NOT_RUN |
| Default changed | Different metadata for existing and new versions | NOT_RUN |
| Restore containing previously deleted data | Reapply deletion records and prevent republication | NOT_RUN |
Use an isolated environment with a short, reviewed duration, control objects, known callers, stop conditions, costs and cleanup. A 403 alone can be an IAM denial rather than Object Lock evidence. Combine these cases with the preceding article’s design to distinguish causes.
Configure S3 Inventory for all versions and include version ID, size, storage class, retain-until date, retention mode, and Legal Hold. The first report can take up to 48 hours; daily or weekly reports are not immediate state. Reconcile urgent decisions with version-specific metadata reads. [12]
Report versions expiring within seven days, expired-but-stored versions, holds without an owner and full backups whose protection ends before dependent increments. Expired retention alone is not a deletion instruction: compare storage policy and Lifecycle eligibility. Monitor key and recovery-reader availability separately.
12. Treat a duration change as a recovery architecture change
Scroll horizontally to view the complete diagram.
Read the diagram as text
Derive required deadlines from timing and dependencies, then compare stored volume, storage class and deletion obligations. Resolve conflicts through data classification or architecture and feed authorized exercise evidence into the next review.
Security reviews detection assumptions, Operations supplies measured recovery timing, Finance reviews storage and retrieval costs, Privacy/Legal defines deletion and records obligations, and the business accepts data loss and outage tradeoffs. Record actual people and approvals; example team names do not establish approval.
If recovery work X increases from three to six days, the lower bound rises from 46 to 49 days. It still fits the illustrative 50-day choice, but rounding headroom falls from four days to one and requires review. Similarly, an improvement in average detection time alone does not justify reducing the adopted upper-bound assumption.
Longer retention does not prove that stored data is healthy or that restoration will succeed. The outcome to evaluate is whether, under the defined threat model and timing assumptions, a healthy point and its dependencies remain usable and business operation can be restored within the required deadline.
Retention is the result of deriving the protection window and checking that cost and deletion requirements can coexist. Keep the assumptions, dependencies, deletion contract and next evidence-based review beside days = 50.
References
Values are illustrative calculations, not price quotations, legal determinations or evidence of adoption and validation in a live environment.
- S3 Object Lock: retention, modes and holds
- Object Lock considerations, Lifecycle and retention limits
- S3 storage classes
- Archive retrieval options and timing
- Lifecycle transitions and minimum-duration costs
- Lifecycle expiration and versioning
- Lifecycle actions and UTC date calculation
- AWS KMS key deletion
- Amazon S3 pricing
- AWS Provider 6.45.0: Object Lock configuration · Lifecycle schema
- OpenTofu dependency lock file
- S3 Inventory and optional Object Lock fields