Skip to main content
INS // Insights

AWS Backup and DR Architecture for SOC 2 Continuity

Updated August 2026 · 7 min read

SOC 2's Availability trust services criterion is optional — companies can scope it out and many do, especially early. The problem is that most mid-market SaaS companies end up needing to demonstrate availability controls anyway, because a customer security questionnaire asks for a documented RPO/RTO and evidence of a tested restore, even when the SOC 2 report itself doesn't cover Availability. At that point, "we take nightly RDS snapshots" is not an answer that satisfies anyone reviewing it.

What "Backup Strategy" Actually Means to an Auditor or Security Reviewer

A backup exists the moment a snapshot completes. A disaster recovery capability exists only once someone has restored from that snapshot, measured how long it took, and documented the result. The gap between those two things is where most companies actually are — snapshots running on schedule, zero evidence anyone has ever restored from one.

AWS Backup centralizes this across services (EBS, RDS, DynamoDB, EFS, and more) under one policy engine, which solves the scheduling and retention problem cleanly. It does not solve the proof problem — that requires an explicit, scheduled restore test with the result logged somewhere durable.

# terraform: AWS Backup plan with cross-region copy and lifecycle
resource "aws_backup_plan" "production" {
  name = "production-daily"

  rule {
    rule_name         = "daily-backups"
    target_vault_name = aws_backup_vault.production.name
    schedule          = "cron(0 6 * * ? *)"

    lifecycle {
      delete_after = 35
    }

    copy_action {
      destination_vault_arn = aws_backup_vault.dr_region.arn
      lifecycle {
        delete_after = 90
      }
    }
  }
}

resource "aws_backup_selection" "production_resources" {
  name         = "production-tagged-resources"
  plan_id      = aws_backup_plan.production.id
  iam_role_arn = aws_iam_role.backup.arn

  selection_tag {
    type  = "STRINGEQUALS"
    key   = "backup-tier"
    value = "production"
  }
}

The copy_action block matters more than the schedule itself for continuity purposes — a backup that lives only in the source region isn't a disaster recovery asset for a regional AWS event, it's a recovery asset for accidental deletion within the same region. Cross-region copy is what actually satisfies a "what happens if us-east-1 has a bad day" question.

RPO and RTO Are Commitments, Not Descriptions

Recovery Point Objective (maximum acceptable data loss, measured in time) and Recovery Time Objective (maximum acceptable downtime) are the two numbers a security questionnaire or SOC 2 Availability criterion evaluation will ask for directly. The mistake is treating them as descriptive — "our RPO is whatever our backup frequency happens to be" — instead of as engineering targets that the backup and restore architecture is explicitly designed to hit.

A daily snapshot schedule implies an RPO of up to 24 hours. If that's not acceptable for the business, the fix isn't a policy document claiming a lower number — it's continuous backup (RDS supports point-in-time recovery down to 5-minute granularity) or a different replication architecture entirely (multi-AZ synchronous replication for near-zero RPO on the primary failure case, separate from the backup-restore path for regional disaster scenarios).

Testing the Restore Is the Part Everyone Skips

# scheduled_restore_test.py — runs monthly, restores latest RDS snapshot to isolated instance, validates, tears down
import boto3
import time

rds = boto3.client("rds")

def run_restore_test(source_db_identifier: str):
    snapshots = rds.describe_db_snapshots(
        DBInstanceIdentifier=source_db_identifier, SnapshotType="automated"
    )["DBSnapshots"]
    latest = max(snapshots, key=lambda s: s["SnapshotCreateTime"])

    test_identifier = f"restore-test-{int(time.time())}"
    start = time.time()

    rds.restore_db_instance_from_db_snapshot(
        DBInstanceIdentifier=test_identifier,
        DBSnapshotIdentifier=latest["DBSnapshotIdentifier"],
        DBInstanceClass="db.t3.medium",
        PubliclyAccessible=False,
    )
    waiter = rds.get_waiter("db_instance_available")
    waiter.wait(DBInstanceIdentifier=test_identifier)

    elapsed_minutes = (time.time() - start) / 60
    # Run application-level validation queries here before teardown
    # Log elapsed_minutes as the measured RTO evidence, then delete the test instance
    rds.delete_db_instance(DBInstanceIdentifier=test_identifier, SkipFinalSnapshot=True)
    return {"snapshot_id": latest["DBSnapshotIdentifier"], "restore_minutes": elapsed_minutes}

Running this monthly, logging the measured restore time against the target RTO, and keeping the log as durable evidence converts "we have backups" into an answer that survives a security review — a demonstrated, timestamped, repeatable restore with a measured recovery time, not a policy statement.

Frequently Asked Questions

Do we need to scope SOC 2 Availability if we already have backups?

Scoping is a business decision, not a technical one — many companies keep Availability out of scope while still maintaining strong backup/DR practices for customer questionnaires and operational risk. If a significant share of prospects ask for Availability-scoped reports specifically, bringing it into scope with evidence you're already generating is usually a smaller lift than expected.

What RPO/RTO targets are typical for a mid-market SaaS company?

There's no universal standard — targets should reflect actual business tolerance for data loss and downtime, not an arbitrary industry number. A common starting point for non-financial, non-healthcare SaaS is an RPO under 24 hours and an RTO under 4 hours for the primary production database, tightened for specific customer contractual commitments where they exist.

How often should restore tests run?

Monthly is a reasonable cadence for most mid-market environments — frequent enough to catch drift in the restore process (IAM permission changes, schema incompatibilities, snapshot corruption) before an actual incident, without becoming an operational burden that gets deprioritized.

Does AWS Backup replace a full disaster recovery plan?

No — AWS Backup handles the backup, retention, and cross-region copy mechanics. A disaster recovery plan also needs a defined failover procedure, DNS/traffic redirection strategy, a communication plan, and named ownership for executing the plan under pressure. The backup infrastructure is a component, not the whole plan.

What's the single most common gap in backup architecture during a review?

Backups exist and run on schedule, but nobody has ever restored from one and measured the result. The second most common gap is backups staying in the source region with no cross-region copy, which quietly fails the "what if the region has an outage" scenario every DR plan claims to cover.


Rutagon builds AWS Backup and DR architecture — cross-region replication, scheduled restore testing, and the evidence trail SOC 2 Availability and customer security reviews actually ask for.

Discuss your project → rutagon.com/contact | 907-841-8407 | contact@rutagon.com

Related reading: SOC 2-Ready AWS Architecture for Startups · AWS Control Tower Guardrails for SOC 2 Compliance · AWS Cloud Infrastructure Capability

External reference: AWS Backup Developer Guide