# Low Level Design: Content Archival Service

Source: https://www.techinterview.org/post/3233471005/lld-content-archival/
Updated: 2026-04-17 · techinterview.org

## Content Archival Service: Storage Tiers

The archival service manages long-term content retention across four S3 storage tiers with different cost and retrieval characteristics.

### Tier Definitions


```
Hot     S3 Standard              <1ms retrieval   high cost    active content
Warm    S3 Standard-IA           ms retrieval     medium cost  infrequent access
Cold    S3 Glacier Instant       ms retrieval     low cost     rare access
Archive S3 Glacier Deep Archive  12h retrieval    lowest cost  compliance storage
```


## Core Schema

### ArchiveRecord Table


```
id             BIGSERIAL PRIMARY KEY
content_id     BIGINT NOT NULL
content_type   TEXT NOT NULL          -- 'financial', 'medical', 'chat', etc.
content_hash   CHAR(64) NOT NULL      -- SHA256 hex
storage_tier   TEXT NOT NULL          -- hot/warm/cold/archive
s3_key         TEXT NOT NULL
size_bytes     BIGINT
archived_at    TIMESTAMPTZ DEFAULT now()
retention_until TIMESTAMPTZ
legal_hold     BOOL DEFAULT false
deleted_at     TIMESTAMPTZ            -- soft delete marker
```


### RetrievalRequest Table


```
id                BIGSERIAL PRIMARY KEY
archive_record_id BIGINT NOT NULL REFERENCES archive_records(id)
requester         TEXT NOT NULL
status            TEXT DEFAULT 'pending'  -- pending/available/expired
requested_at      TIMESTAMPTZ DEFAULT now()
available_at      TIMESTAMPTZ             -- when restore completes
expires_at        TIMESTAMPTZ             -- availability window end
```


## Retention Policies

Retention duration is configurable per content type. The `retention_until` timestamp is computed at archive time.


```
Retention rules (examples):
  financial  → 7 years
  medical    → 10 years
  chat       → 3 years
  legal      → 10 years (often with legal_hold=true)

-- At archive time:
retention_until = archived_at + INTERVAL per content_type rule
```


## Lifecycle Tier Transitions

S3 Lifecycle policies automate tier transitions based on object age, eliminating manual migration jobs for the majority of content.


```
S3 Lifecycle rules on archive bucket:
  Day 0        → S3 Standard (hot)
  Day 30       → S3 Standard-IA (warm)
  Day 90       → S3 Glacier Instant Retrieval (cold)
  Day 365      → S3 Glacier Deep Archive (archive)

Application updates storage_tier in ArchiveRecord via S3 lifecycle
event notifications (EventBridge → Lambda → UPDATE archive_records).
```


## Integrity Verification

A nightly job re-computes the SHA256 hash of each archived object and compares it to the stored `content_hash`. Mismatches trigger an alert and open an incident for investigation.


```
Nightly integrity job (pseudo-code):
FOR EACH record IN archive_records WHERE storage_tier IN ('hot','warm')
    stream = s3.get_object(record.s3_key)
    actual_hash = sha256(stream)
    IF actual_hash != record.content_hash:
        alert(severity='critical', record_id=record.id,
              expected=record.content_hash, actual=actual_hash)

-- Cold/archive tier: sample 1% nightly; full scan monthly (cost control)
```


## Legal Hold

When `legal_hold=true`, the record is excluded from all deletion processes regardless of `retention_until`. Legal hold is set and cleared only through an authorized legal operations workflow with audit logging.


```
-- Deletion eligibility check:
SELECT * FROM archive_records
WHERE retention_until < now()
  AND legal_hold = false
  AND deleted_at IS NULL;

-- Legal hold prevents deletion even after retention expires.
-- Clearing hold requires explicit authorized action:
UPDATE archive_records SET legal_hold=false WHERE id=$1;
-- Audit log entry required for every legal_hold state change.
```


## Retrieval SLA by Tier


```
Hot   (S3 Standard)         → immediate, synchronous response
Warm  (S3-IA)               → immediate, synchronous response
Cold  (Glacier Instant)     → ~1 minute, synchronous response
Archive (Glacier Deep)      → 12 hours, async restore + notify
```


### Deep Archive Retrieval Flow


```
1. Client requests retrieval → INSERT INTO retrieval_requests (status='pending')
2. Trigger S3 Glacier restore: s3.restore_object(key, Days=2)
3. S3 fires RestoreCompleted event (EventBridge) after ~12h
4. Lambda handles event:
   UPDATE retrieval_requests SET status='available', available_at=now(),
       expires_at=now()+INTERVAL '48 hours' WHERE archive_record_id=...
5. Notify requester (email/webhook)
6. Client downloads restored object within 48h window
```


## Search Before Retrieval

Requesters search archive metadata before initiating a retrieval to avoid unnecessary restore costs on deep archive objects.


```
-- Metadata search (no S3 cost):
SELECT id, content_type, content_hash, storage_tier, size_bytes,
       archived_at, retention_until, legal_hold
FROM archive_records
WHERE content_type=$1
  AND archived_at BETWEEN $2 AND $3
  AND deleted_at IS NULL;
-- Full-text on indexed metadata fields; no object retrieval until confirmed.
```


## Deletion After Retention

A scheduled job identifies eligible records and hard-deletes both the S3 object and the database record, with a tombstone entry written to an audit log before deletion.


```
Deletion job (runs nightly):
1. SELECT records WHERE retention_until < now()
       AND legal_hold=false AND deleted_at IS NULL
2. FOR EACH record:
   a. Write tombstone to audit_log (id, content_hash, deleted_at, reason)
   b. s3.delete_object(record.s3_key)
   c. UPDATE archive_records SET deleted_at=now() WHERE id=record.id
```


See also: [Scale AI Interview Guide 2026: Data Infrastructure, RLHF Pipelines, and ML Engineering](https://www.techinterview.org/post/3233460275/scale-ai-interview-guide-2026-data-infrastructure-rlhf-pipelines-and-ml-engineering/)

See also: [Netflix Interview Guide 2026: Streaming Architecture, Recommendation Systems, and Engineering Excellence](https://www.techinterview.org/post/3233460274/netflix-interview-guide-2026-streaming-architecture-recommendation-systems-and-engineering-excellence/)

See also: [Atlassian Interview Guide](https://www.techinterview.org/post/3233459919/atlassian-interview/)
