Skip to content

Core lesson

Highly Available RDS App

Evolve a single-database web application so it survives database and Availability Zone failures, reconnects safely, and can recover from bad data.

15 min read

After this, you will understand

How a relational application combines managed failover, backup recovery, and reconnect behavior—and why read scaling is a different requirement.

Article guideprerequisites, mental models, and concepts

Article overview

intermediateCloudCertificationReliability

Three useful mental models

In plain terms

Use a private RDS Multi-AZ deployment for automatic failover, automated backups for recovery, and application retries so the service can reconnect after the writer changes.

Decision pressure

Learners use a read replica as the automatic failover answer, treat a standby as a backup, or forget that active database connections can break during failover.

Exam-ready model

Separate four requirements: Multi-AZ for availability, read replicas for read scale, backups for recovery, and application connection handling for the failover transition.

Think before reading

If Multi-AZ copies a mistaken DELETE to the standby, which RDS feature can return the database to a point before that mistake?

Automated backups and point-in-time recovery create a new database restored to a chosen time within the retention window.

Connected learning

These lessons add useful context to the current core lesson.
  1. 1RDS Multi-AZ vs Read ReplicasAWS Reference
  2. 2Static Site With CloudFront And S3AWS Scenario

Concepts Covered

  • Private RDS placement
  • Database subnet groups
  • Multi-AZ DB instance deployments
  • Synchronous standby replication
  • Automatic database failover
  • RDS endpoint behavior
  • Automated backups and point-in-time recovery
  • Read replicas and replication lag
  • Connection pools, reconnects, and safe retries
  • AWS Solutions Architect Associate exam (SAA-C03) availability and recovery signals

1. Situation

Start with a familiar highly available application tier:

flowchart LR
  User["User"] --> ALB["Application Load Balancer"]
  ALB --> AppA["Application<br/>AZ A"]
  ALB --> AppB["Application<br/>AZ B"]
  AppA --> DB["One RDS DB instance<br/>AZ A"]
  AppB --> DB

The load balancer can route around a failed application instance. The Auto Scaling group can replace unhealthy compute. But every request still depends on one database instance in one Availability Zone.

If that database becomes unavailable, the healthy application servers have nowhere to read or write business data. The web tier is highly available on paper, yet the application is down.

The business now gives four requirements:

  1. Continue after a database instance or Availability Zone failure.
  2. Recover from an accidental deletion or bad deployment.
  3. Scale read traffic if reporting and product queries grow.
  4. Keep the application usable while database connections move to a replacement writer.

Those requirements sound related because they all involve copies of data. They are not the same engineering problem.

This study uses the classic RDS Multi-AZ DB instance deployment as its main model: one primary DB instance and one synchronous standby in another Availability Zone.

2. Naive Design

Naive option 1: one database in one Availability Zone

application -> single-AZ RDS DB instance

This is simple and may be appropriate for development or a workload that can tolerate database downtime. It is not highly available.

If the instance or its Availability Zone has a problem, the application waits for recovery or a manual restore. Adding more application servers does not remove this database failure boundary.

Naive option 2: add a read replica and call it failover

flowchart LR
  App["Application"] -->|"reads and writes"| Primary["Primary DB instance"]
  Primary -.->|"asynchronous replication"| Replica["Read replica"]
  Reports["Read-only reporting"] --> Replica

A read replica is useful, but it normally has its own endpoint and receives changes asynchronously. In a classic RDS DB instance design, promoting it to a standalone writer and redirecting application traffic are separate recovery actions.

That is not the same experience as managed Multi-AZ failover.

Naive option 3: enable Multi-AZ and remove backups

The standby receives the database's current state. If the application drops a table, overwrites a balance, or runs a destructive migration, that bad change can reach the standby too.

A standby is a current replacement, not historical recovery.

Naive option 4: assume connections never break

Even managed failover involves a transition. Existing database sessions may fail. In-flight transactions can be interrupted. A connection pool may keep stale connections.

The database can recover before the application recovers if the application does not reconnect correctly.

3. What Breaks

Follow three failure stories.

Failure story 1: the primary instance stops responding

At 10:00, the application sends traffic to its usual RDS endpoint. At 10:01, the primary instance becomes unavailable.

In a Single-AZ design, there is no already-maintained standby ready for RDS to promote. Database downtime becomes an infrastructure recovery problem.

The architecture needs a synchronized standby and managed failover.

Failure story 2: an operator deletes valid data

At 14:00, a migration mistakenly deletes rows. The database remains healthy and continues accepting queries. Multi-AZ replication faithfully copies the new state.

Nothing has failed at the infrastructure level, so there is nothing to fail over from. The architecture needs a copy from before 14:00.

Failure story 3: the standby is promoted but users still see errors

RDS changes the database behind the application-facing endpoint. Old TCP sessions do not magically move to the new writer. Some transactions fail midway, and application instances continue trying stale connections from their pools.

The architecture needs bounded retries, fresh DNS resolution, connection-pool recovery, and safe handling of uncertain write outcomes.

These stories lead to a useful rule:

availability protects the service from infrastructure failure
recovery protects the data from unwanted change
application resilience protects users during the transition

4. AWS Architecture

Build the database architecture one responsibility at a time.

Step 1: place RDS in private database subnets

Create a DB subnet group containing database subnets in at least two Availability Zones. The subnet group tells RDS where database resources may be placed.

Do not make the database publicly accessible for a normal application architecture. Application instances connect privately from the application tier.

flowchart LR
  subgraph VPC["Application VPC"]
    subgraph AppTier["Private application subnets"]
      AppA["App<br/>AZ A"]
      AppB["App<br/>AZ B"]
    end

    subgraph DBTier["Private database subnets"]
      DBA["DB subnet<br/>AZ A"]
      DBB["DB subnet<br/>AZ B"]
    end
  end

  AppA --> DBA
  AppB --> DBA
  DBA -.-|"DB subnet group"| DBB

The subnet group provides placement options. It does not by itself create a standby or enable failover.

Step 2: enable a Multi-AZ DB instance deployment

For the central scenario, configure RDS with one primary DB instance and one synchronous standby in another Availability Zone.

flowchart LR
  App["Application"] --> Endpoint["RDS endpoint<br/>stable application-facing name"]
  Endpoint --> Primary["Primary DB instance<br/>AZ A"]
  Primary ==>|"synchronous replication"| Standby["Standby DB instance<br/>AZ B"]
  Standby -.->|"not used for application reads"| Note["Failover capacity"]

The primary serves database traffic. The standby is maintained for high availability. In this deployment type, the application cannot send reporting queries to the standby.

If RDS detects a supported failure condition, it can promote the standby and update the DNS record behind the same RDS endpoint name.

Step 3: add automated backups for recovery

Enable automated backups with a retention period that matches the acceptable recovery window. Automated backups support point-in-time recovery, or PITR, within that window.

PITR creates a new DB instance at the selected time. It does not rewind the damaged production database in place.

flowchart LR
  Production["Production RDS<br/>bad change at 14:00"] --> Backups["Automated backups<br/>and transaction logs"]
  Backups -->|"restore to 13:55"| Restored["New restored DB instance"]
  Restored --> Validate["Validate data<br/>then switch or reconcile"]

Use a manual snapshot before a risky migration when a named pre-change recovery point is useful. Test restore procedures; an untested backup is only a promise.

Step 4: make the application failover-aware

The application connects to the RDS endpoint through a bounded connection pool. It must discard broken connections and establish new ones after failover.

Use retries with backoff for transient connection failures, but retry database writes carefully. If the database committed a transaction and the response was lost, blindly repeating the operation can duplicate business work.

Use idempotency keys, unique constraints, transaction identifiers, or operation-specific reconciliation where repeated writes could be harmful.

RDS Proxy is an optional managed connection layer for supported engines and workloads. It can pool connections and make some failovers more transparent, but it does not replace correct transactions, retries, or database recovery planning.

Step 5: add read capacity only when reads are the bottleneck

If metrics show that read-heavy queries are exhausting the writer, create read replicas and route suitable read-only traffic to their endpoints.

flowchart LR
  App["Application"] -->|"writes and current reads"| Writer["Multi-AZ writer endpoint"]
  Writer -.->|"asynchronous replication"| ReadReplica["Read replica<br/>separate endpoint"]
  Reports["Reports and stale-tolerant reads"] --> ReadReplica

Replication lag means a read replica may not immediately contain the latest committed write. Do not route a read-after-write workflow to a replica unless the product can tolerate stale data.

5. Request Or Data Flow

Learn three lifecycles instead of one long request path.

Lifecycle 1: normal request

  1. A user request reaches an application instance through the load balancer.
  2. The application obtains database credentials from a secure store such as Secrets Manager.
  3. The application connects to the RDS endpoint.
  4. DNS directs that connection to the current primary DB instance.
  5. The primary commits the transaction while the Multi-AZ deployment maintains its standby according to the deployment's replication behavior.
  6. The application returns the result to the user.

Lifecycle 2: database failover

flowchart TD
  Failure["Primary becomes unavailable"] --> Detect["RDS detects a failover condition"]
  Detect --> Promote["RDS promotes standby"]
  Promote --> DNS["RDS endpoint DNS points to new primary"]
  DNS --> Broken["Old application connections may fail"]
  Broken --> Reconnect["Application resolves and reconnects"]
  Reconnect --> Retry["Retry safe operations with backoff"]

The RDS service handles the database-side promotion. The application handles the client-side interruption.

Long transactions may roll back. Requests in flight may return errors. Monitoring should distinguish a brief failover window from a persistent database or application fault.

Lifecycle 3: bad-data recovery

  1. Operators identify the last known good time.
  2. RDS restores to that point as a new DB instance.
  3. The team validates the restored data and application compatibility.
  4. The team chooses a recovery method: switch the application, export selected data, or reconcile changes made after the restore point.
  5. DNS, secrets, connection strings, and security groups are updated deliberately if the application moves to the restored instance.

Failover is automatic infrastructure recovery. Point-in-time restore is a data-recovery workflow that requires validation and cutover planning.

6. Security Controls

Protect the network boundary

Keep RDS in private database subnets and set public accessibility to false for the normal architecture.

Use security-group referencing:

application security group
  -> allowed on the database port
  -> database security group

The database security group should not allow its port from 0.0.0.0/0, an office IP range used only for convenience, or the whole VPC when the application tier can be named more precisely.

Protect the credentials and database identity

Store database credentials in AWS Secrets Manager or another approved secret store. Rotate them according to engine and application requirements.

IAM policies govern who may create, modify, snapshot, restore, or delete RDS resources through AWS APIs. Database users and roles govern what the application may do inside the relational engine. These are separate permission systems.

Protect data and administrative actions

Use encryption at rest with AWS KMS where required and TLS for application-to-database connections. KMS permissions matter when copying, sharing, or restoring encrypted snapshots.

Protect destructive control-plane actions such as deleting a DB instance, changing backup retention, disabling deletion protection, or modifying network exposure.

Enable the engine logs, CloudWatch metrics, events, audit capabilities, and performance tooling that match the database and compliance needs.

7. Resilience Controls

A highly available relational application needs all of these layers:

FailurePrimary controlWhat still needs work
DB instance or supported AZ failureMulti-AZ automatic failoverApplication reconnect and retry behavior
Accidental delete or bad migrationAutomated backups, PITR, snapshotsRestore validation and data cutover
Read overloadRead replicas, query tuning, cachingReplica lag and read routing
Connection stormPooling or RDS ProxyPool limits, backpressure, and monitoring
Entire Region unavailableCross-Region recovery designReplication, routing, RTO, and RPO planning

Multi-AZ is a same-Region availability control. It is not automatically a multi-Region disaster-recovery architecture.

Monitor database events and signals such as availability, connections, CPU, free memory, storage, I/O latency, replica lag, deadlocks, and slow queries. The correct metric set depends on the engine and workload.

Test failover deliberately in a non-production environment and through controlled production exercises. Measure how long the application—not only the database—takes to recover.

Test restore separately. A successful failover test proves that the standby can take over; it does not prove that the team can recover a table deleted yesterday.

8. Performance Controls

Start with the database work itself:

  1. Find slow and frequent queries.
  2. Review indexes and execution plans.
  3. Remove unnecessary database round trips.
  4. Bound connection pools across all application instances.
  5. Choose instance, storage, and IOPS capacity from measurements.

Adding application instances can increase database pressure. Ten app instances with pools of 100 connections can attempt 1,000 database connections. Horizontal compute scaling does not automatically scale a relational writer.

Use read replicas when read traffic is the bottleneck and those reads can tolerate asynchronous replication lag. Reporting, analytics, and some product browsing often fit better than immediate read-after-write workflows.

Use Amazon ElastiCache for repeated hot reads when staleness and invalidation are understood. A cache reduces database pressure; it is not the durable source of truth.

For this study's Multi-AZ DB instance deployment, the standby is failover capacity, not read capacity. If the requirement needs readable standbys, inspect RDS Multi-AZ DB clusters or Aurora rather than applying the classic instance model blindly.

9. Cost Controls

Each reliability or scaling feature buys a different outcome:

ChoiceWhat you pay forWhat you gain
Multi-AZ DB instance deploymentStandby capacity and replicated storage behaviorManaged same-Region failover
Read replicaAdditional database instance and storageMore read capacity and a separate read endpoint
Longer backup retention and snapshotsBackup storage beyond included allowancesMore recovery history
RDS ProxyManaged proxy capacityConnection reuse and improved connection resilience
Larger instance or provisioned IOPSMore database capacityHigher compute, memory, or storage performance

Do not disable Multi-AZ merely because Single-AZ is cheaper when the requirement explicitly demands high availability.

Do not add read replicas before identifying read pressure. A replica that receives no appropriate traffic adds cost without relieving the writer.

Right-size from metrics, but remember that database cost is not only instance size. Poor indexes, unbounded connections, excessive storage, long snapshot retention, and cross-Region copies can all drive cost.

Aurora may offer a better architecture for some MySQL- or PostgreSQL-compatible workloads, but it is not automatically cheaper or necessary. Start with compatibility, availability, scaling, and operational requirements before choosing the engine family.

10. Exam Variants

Translate the wording into the failure the architecture must survive.

Requirement signalLikely answerWhy
Automatically fail over after an RDS instance or AZ problemRDS Multi-AZIt maintains standby capacity and provides managed failover.
Scale read-heavy trafficRead replicasThey provide separate read-only capacity and endpoints.
Recover to a time before an accidental deletionAutomated backups and PITRHistorical recovery is different from current-state replication.
Keep the relational database off the internetPrivate DB subnets and security groupsOnly the application tier should reach the database port.
Many short-lived connections overwhelm the databaseRDS Proxy or disciplined poolingConnection reuse protects database capacity.
Need a named recovery point before a risky migrationManual DB snapshotThe snapshot provides a deliberate pre-change checkpoint.
Need relational disaster recovery in another RegionCross-Region backup or replica strategyMulti-AZ remains within one Region.
Need readable standbys with managed Multi-AZ availabilityRDS Multi-AZ DB cluster, where supportedThis is a different deployment type from the single-standby DB instance model.

Watch for requirements that need more than one answer

Suppose an exam question says:

A production MySQL database must fail over automatically after an Availability Zone failure and must recover to a specific time after an accidental deletion.

The question describes two failures:

infrastructure failure -> Multi-AZ
bad data -> automated backups and PITR

Neither feature replaces the other.

11. Common Traps

TrapBetter reasoning
"A read replica is the normal automatic failover target."Classic DB instance read replicas are mainly for read scaling; promotion and traffic redirection are separate actions.
"The Multi-AZ standby serves reports."A Multi-AZ DB instance standby does not serve application reads.
"No RDS standby can serve reads."RDS Multi-AZ DB clusters have readable standbys. Identify the deployment type.
"Multi-AZ means multi-Region."Availability Zones are separate locations within one AWS Region.
"Multi-AZ replaces backups."A bad change can replicate. Historical recovery still needs backups or snapshots.
"PITR rolls the production database backward in place."RDS creates a new restored DB instance. Plan validation and cutover.
"The RDS endpoint guarantees uninterrupted sessions."The name remains the application entry point, but existing connections can break during failover.
"Retry every failed write immediately."The original transaction may have committed. Retry only with operation-aware safety and idempotency.
"More application instances always improve capacity."They can create a connection storm and overload the database.
"A private database needs no security group design."Private routing reduces exposure; security groups still decide who can reach the database port.

Final Mental Model: One-Minute Review

Final Architecture Map

Highly available RDS architecture distinguishing the stable endpoint, primary database, synchronous Multi-AZ standby, asynchronous read replica, and point-in-time restore path.

The color and line styles separate three copy purposes: availability, read scaling, and historical recovery.

TermExact jobRemember it as
RDS endpointGives the application a stable database name even when the writer behind it changesThe database's published phone number
Primary DB instanceServes the application's normal reads and writesThe active records clerk
Multi-AZ standbyMaintains a synchronous current copy for managed failover in another AZThe prepared relief clerk
Automated backups and PITRRestore historical data into a new DB instance after a bad changeThe database time machine
Read replicaReceives an asynchronous copy for additional read capacityThe reporting clerk
Reconnect and safe retry logicHelps the application recover when failover breaks existing connectionsRedialing carefully after the clerk changes
flowchart LR
  App["Application"] --> Endpoint["RDS endpoint<br/>stable name"]
  Endpoint --> Primary["Primary DB<br/>reads and writes"]
  Primary ==>|"Synchronous copy"| Standby["Multi-AZ standby<br/>failover capacity"]
  Primary -.->|"Asynchronous copy"| Replica["Read replica<br/>read scaling"]
  Primary -.->|"Backups and transaction logs"| Backups
  Backups["Automated backups<br/>and transaction logs"] -->|"Point-in-time restore"| Restored["New restored DB instance"]

Every copy has a different purpose: the standby protects availability, the read replica adds read capacity, and backups protect historical recoverability. The application still needs to reconnect and retry safely during failover.

Use Amazon RDS for engines, subnet groups, storage, backups, security, and the overall managed database model.

Use RDS Multi-AZ vs Read Replicas when availability and read scaling still feel interchangeable.

Use RDS And Aurora Recovery Choices for snapshots, point-in-time recovery, backup replication, and disaster-recovery comparisons.

Use Amazon Aurora when the workload needs Aurora's cluster storage, reader endpoints, replica promotion, or global database options.

Use AWS Secrets Manager for database credential storage and rotation patterns.

Official AWS references:

Finished reading?

Your reading history is saved in this browser so you can continue later.

Recommended Next

Static Site With CloudFront And S3AWS Architecture Scenarios14 min read

This applies the foundation mental models to a real architecture decision instead of a service inventory.

Optional exploration

These links add context, but they do not replace the recommended next lesson.

Arcflow Plus is coming — review drills, research breakdowns, more AI. Get one email at launch.