CloudBrum
CloudBrum · Cloud decision-support platform
AWS Databases

Amazon RDSLast reviewedReading time~12 minLevelBeginner to advanced

Amazon Web Services · Databases · Managed relational database

A database server that AWS looks after. You pick an engine such as PostgreSQL or MySQL, a size and a storage type, and RDS handles the machine, the patching, the backups and the failover. You still design the schema, tune the queries and decide who can connect. The two choices that shape your bill and your outage risk are Multi-AZ and how long you keep backups, so settle those on day one.

On this page (17 sections)

    Mind map: Amazon RDS at a glance

    Amazon RDS mind map Amazon RDS at a glance: Engines: PostgreSQL, MySQL, MariaDB, Db2, SQL Server, Oracle; Availability: Multi-AZ instance, Multi-AZ DB cluster, Automatic failover; Scale: Read replicas, Storage autoscaling, RDS Proxy; Backup: Automated, 1 to 35 days, Point-in-time restore, Manual snapshots; Security: VPC and security groups, KMS encryption, IAM auth, Secrets; Operations: Parameter groups, Maintenance windows, Blue/Green deployments; Monitoring: CloudWatch metrics, Enhanced Monitoring, Database Insights; Pricing: Instance hours, Storage and IOPS, Extended Support. Amazon RDS at a glance A managed relational database on AWS: the main building blocks and decisions CloudBrum Cloud decision-support platform CloudBrum PostgreSQL, MySQL MariaDB, Db2 SQL Server, Oracle Engines Multi-AZ instance Multi-AZ DB cluster Automatic failover Availability Read replicas Storage autoscaling RDS Proxy Scale Automated, 1 to 35 days Point-in-time restore Manual snapshots Backup VPC and security groups KMS encryption IAM auth, Secrets Security Parameter groups Maintenance windows Blue/Green deployments Operations CloudWatch metrics Enhanced Monitoring Database Insights Monitoring Instance hours Storage and IOPS Extended Support Pricing Amazon RDS17-point analysis CloudBrum· 17-point cloud service analysis cloudbrum.com
    CloudBrum Amazon RDS at a glance · 17-point analysis Engines PostgreSQL, MySQL MariaDB, Db2 SQL Server, Oracle Availability Multi-AZ instance Multi-AZ DB cluster Automatic failover Scale Read replicas Storage autoscaling RDS Proxy Backup Automated, 1 to 35 days Point-in-time restore Manual snapshots Security VPC and security groups KMS encryption IAM auth, Secrets Operations Parameter groups Maintenance windows Blue/Green deployments Monitoring CloudWatch metrics Enhanced Monitoring Database Insights Pricing Instance hours Storage and IOPS Extended Support CloudBrum · cloudbrum.com

    Free to share. The downloaded image includes the CloudBrum link.

    Key features (summary)

    • Six engines, one way to run themPostgreSQL, MySQL, MariaDB, Oracle, SQL Server and Db2 all run on RDS. The console and the API look the same whatever you choose, so a team can move between engines without learning a new control panel.
    • Multi-AZ for failoverA Multi-AZ DB instance keeps a synchronous standby in another Availability Zone and switches to it if the primary fails. A Multi-AZ DB cluster (MySQL and PostgreSQL) has two readable standbys, and usually fails over faster.
    • Read replicasCopy data to replicas that serve read-only queries, in the same Region or another one. A replica can be promoted to a standalone database, which makes it useful for scaling reads and for disaster recovery.
    • Backups and point-in-time restoreAutomated backups and transaction logs let you restore to nearly any second in the retention period (1 to 35 days). Manual snapshots stay until you delete them.
    • Storage that growsgp3 or Provisioned IOPS volumes, with optional autoscaling up to a limit you set. Storage can grow without downtime, but it can’t shrink.
    • Encryption and IAM sign-inEncrypt storage with a KMS key, force TLS for connections, let RDS keep the admin password in Secrets Manager, and sign in with short-lived IAM tokens instead of stored passwords on MySQL, MariaDB and PostgreSQL.
    • Blue/Green deploymentsBuild a staging copy of the live database, upgrade or change it there, and switch over when it’s ready. It’s the safer way to do major version upgrades.
    • Monitoring built inCloudWatch metrics come for free, Enhanced Monitoring adds operating system detail, and AWS is folding Performance Insights into CloudWatch Database Insights for query-level analysis.

    Basic concepts

    DB instance
    One database server: an engine, an instance class and storage. Everything you pay for hangs off this.
    Instance class
    The size of the machine, written like db.m7g.large. Prefixes tell you the family: t is burstable, m is general purpose, r is memory optimised, and a g means AWS Graviton.
    Multi-AZ DB instance
    A primary plus one standby in another Availability Zone. The standby takes no queries. Failover swaps the DNS name to it.
    Multi-AZ DB cluster
    A writer plus two readable standbys in three zones, for MySQL and PostgreSQL. You get reader and writer endpoints.
    Read replica
    An asynchronous copy for read traffic. It lags a little behind the source, and can be promoted.
    Subnet group
    The set of subnets (in at least two Availability Zones) where RDS is allowed to place your instance.
    Parameter group
    A named set of engine settings, such as max_connections or rds.force_ssl. Some changes apply only after a reboot.
    Automated backup
    A daily snapshot plus continuous transaction logs, kept for the retention period you set (1 to 35 days, and 0 turns them off).
    Snapshot
    A manual backup that stays until you delete it. You can copy it to another Region or share it with another account.
    Point-in-time restore
    Creates a new instance from the backups, at a time you choose. It never overwrites the original.
    Maintenance window
    A weekly slot when RDS may apply patches or changes that need a restart.
    RDS Proxy
    A managed connection pool in front of the database. It keeps connections open, which helps apps with many short-lived connections, such as Lambda.
    Blue/Green deployment
    A synchronised staging copy (green) of your production database (blue) that you can change, test and then switch to.
    Endpoint
    The DNS name your application connects to. After a failover it points at the new primary, so don’t use IP addresses.

    How to create & configure it

    Create a PostgreSQL database in the AWS console

    1. Pick the Region and plan the networkChoose a Region near your users (Mumbai or Hyderabad for India). Make sure the VPC has private subnets in at least two Availability Zones, and create a DB subnet group from them.
    2. Choose Standard createOpen RDS, then Create database, and use Standard create so you see every setting. The easy-create option picks defaults you may not want, including how the database is reached.
    3. Choose the engine and the versionPick PostgreSQL (or MySQL) and a recent major version that’s still in standard support. Older versions cost extra after support ends. Use the Production template when you want Multi-AZ preselected.
    4. Set the availabilityFor anything real, choose a Multi-AZ DB instance, or a Multi-AZ DB cluster if you want readable standbys. Single-AZ is fine for development, and it halves the instance cost.
    5. Let RDS manage the admin passwordChoose Managed in AWS Secrets Manager. You’ll fetch the password from there when you need it, and RDS can rotate it.
    6. Pick the size and the storageStart with a general purpose m or a burstable t class, gp3 storage, and storage autoscaling with a maximum you can live with. Resize later from the measurements.
    7. Keep it privateChoose your VPC and the subnet group, set Public access to No, and attach a security group that allows port 5432 only from your application’s security group.
    8. Set backups and protectionChoose a backup retention of 7 to 35 days, a backup window outside your busy hours, encryption with the default or a KMS key, and turn on Deletion protection.
    9. Connect and checkConnect from an app server in the VPC with TLS on, create an application user with only the rights it needs, and look at the CloudWatch graphs. Then test a restore before you rely on the backups.

    Tip: once the console flow makes sense, write the same settings as code (CloudFormation, the CDK or Terraform, see the code references). The settings that matter most, like Multi-AZ, encryption and public access, are easy to get wrong by clicking.

    Common issues after configuration

    SymptomLikely causeWhat to check / fix
    Connection times outThe security group, subnet routing or the public access setting blocks youCheck the security group allows your source on the database port, that the client can route to the subnet, and whether the instance is meant to be public. A timeout is nearly always network, not credentials.
    no pg_hba.conf entry ... no encryption (PostgreSQL)The server requires TLS and the client connected without itNewer PostgreSQL versions on RDS force SSL by default. Connect with sslmode=verify-full and the RDS certificate bundle.
    FATAL: password authentication failedWrong user or password, or an IAM token that has expiredIf you use IAM tokens, remember they last 15 minutes, so generate one just before connecting. If the admin password is in Secrets Manager, fetch the current value.
    too many connections / remaining connection slots are reservedMore clients than max_connections allows, which depends on instance memoryUse RDS Proxy or a pooler, shorten idle connection lifetimes in the app, and scale up only after you’ve checked how many connections are really needed.
    Application errors for a minute during failoverThe standby is taking over and clients still hold old connectionsRetry with backoff, connect by DNS name, keep DNS caching short (the JVM default is a common trap), and test a forced failover before launch.
    Storage full, database read-only or downThe disk filled up and autoscaling is off or has reached its maximumTurn on storage autoscaling with a sensible ceiling, find what grew (logs, bloat, temporary files), and raise the alarm on free storage space.
    CPU credits ran out on a db.t instanceBurstable instances slow down when they use more than their baseline for longCheck the CPU credit balance metric. Move to an m or r class if the load is steady, or turn on unlimited mode where the engine supports it, and watch the cost.
    Replica lag keeps growingHeavy writes on the source or a replica too small to keep upCheck ReplicaLag in CloudWatch, give the replica the same size as the source, and look for long-running queries or transactions on it.
    A parameter change did nothingThe parameter is static, so the instance shows pending-rebootReboot in a quiet period. Dynamic parameters apply immediately, static ones wait for a restart.
    A restore doesn’t replace the original databaseRestores always create a new instanceRestore, check the data, then point the application at the new endpoint, or rename the instances. Don’t plan on overwriting in place.
    Unexpected "Extended Support" chargesAn old engine version is past the end of standard supportUpgrade the major version before the date AWS publishes, using a Blue/Green deployment to test it first.

    Use cases: when and where to use it

    Good fit

    • Web and mobile app back ends that need transactions, joins and a familiar SQL engine
    • Moving an existing PostgreSQL, MySQL, SQL Server or Oracle database to the cloud with few code changes
    • Line-of-business systems where nobody wants to patch database servers
    • Reporting and dashboards that read from a replica instead of the live database
    • Multi-tenant SaaS products that need one reliable relational store
    • Test and staging databases that you can snapshot, copy and delete

    Consider something else

    • A relational database that scales writes across Regions with no managing of instance sizes → Amazon Aurora, which is a separate service
    • Key-value or document workloads with huge scale → Amazon DynamoDB or DocumentDB
    • Heavy analytics over billions of rows → Amazon Redshift or Athena on Amazon S3, not an OLTP database
    • Full control of the operating system or an unsupported engine → run the database yourself on Amazon EC2
    • The same job on other clouds → compare Azure SQL Database, Azure Database for PostgreSQL, Azure Database for MySQL and Cloud SQL

    Pros: why consider it?

    Why teams choose it

    • No patching, backup scripts or failover scripts to write
    • Multi-AZ failover and point-in-time restore come with a few settings
    • Six engines, so existing applications often move unchanged
    • Plugs into IAM, KMS, VPC, CloudWatch and Secrets Manager
    • Read replicas and storage autoscaling for growth without rebuilding
    • Blue/Green deployments make big upgrades less frightening

    Trade-offs to weigh

    • No operating system access, and the master user isn’t a true superuser
    • Multi-AZ roughly doubles the instance and storage cost
    • Some extensions, settings and file-level tricks aren’t available
    • Failover isn’t instant, so applications still need retry logic
    • Old engine versions get expensive once standard support ends
    • Storage can grow but never shrink, so a runaway table costs you permanently until you migrate

    Common threats, vulnerabilities & risks

    RiskSeverityWhy it mattersMitigation
    A database reachable from the internetHighPublic access with a wide security group invites scans and brute-force attempts.Keep instances in private subnets with public access off, and allow the port only from application security groups.
    No tested restoreHighBackups that have never been restored are a hope, not a plan.Restore to a new instance on a schedule, check the data, and time it against your recovery target.
    Single-AZ production databaseHighAn Availability Zone problem or a hardware failure becomes an outage that lasts until restore.Use Multi-AZ for production, and test a failover.
    Shared admin credentials in application configMediumThe master user can do anything, and passwords in config files leak.Let RDS manage the master password in Secrets Manager, create least-privilege app users, and use IAM authentication where the engine supports it.
    Unencrypted storage or plain-text connectionsMediumEncryption can’t be switched on for an existing instance in place, and unencrypted traffic can be read on the network.Encrypt at creation with KMS, force TLS, and verify the server certificate in clients.
    Deleting the instance by accidentMediumWithout a final snapshot and deletion protection, one click removes data and backups together.Turn on deletion protection, keep a final snapshot, and copy important snapshots to another account.
    Running out of connections or storageMediumBoth stop the application suddenly, and storage can’t be reclaimed.Use RDS Proxy, autoscaling with a ceiling, and alarms on connections and free space.
    Ageing engine versionsLow–MedUnsupported versions miss security fixes and then cost extra.Track end-of-support dates and upgrade through Blue/Green deployments.
    Cost growth from idle replicas and snapshotsLow–MedForgotten replicas, manual snapshots and oversized instances bill every day.Tag everything, review monthly, and delete what no one owns.

    Performance optimisation

    • Pick the instance class from measurements: CPU, memory and the buffer cache hit ratio. Memory-heavy databases usually want an r class, and small steady ones do well on m.
    • Choose gp3 storage and set IOPS and throughput on their own when you need more, or Provisioned IOPS (io2) for demanding, latency-sensitive workloads.
    • Use RDS Proxy or a pooler when thousands of short-lived connections hit the database, for example from Lambda functions.
    • Send reads to replicas and keep writes on the primary, and watch replica lag so you don’t serve stale data by surprise.
    • Find slow queries with Database Insights or pg_stat_statements, add the right indexes, and check query plans before throwing hardware at the problem.
    • Keep transactions short and avoid long-running idle transactions, which hold locks and prevent cleanup.
    • Set parameter groups deliberately (connections, memory, logging) instead of living with defaults, and apply them in a test first.
    • Run the application in the same Region and Availability Zone as the primary where you can, since every cross-zone call adds latency and a small charge.

    Reduce monthly cost

    FinOps is the habit of managing cloud spend together with engineering. These are the FinOps checks that matter most for Amazon RDS.

    • Use Single-AZ for development and test, and keep Multi-AZ for production. It’s the biggest single lever on the instance bill.
    • Right-size from the CloudWatch graphs. A database that idles at 10% CPU can drop a size.
    • Use Graviton instance classes (g in the name), which are usually cheaper for the same performance, if your engine and extensions support them.
    • Buy Reserved Instances for databases you know will run for a year or more. Note that they don’t cover Extended Support charges.
    • Stop non-production instances you aren’t using. A stopped instance isn’t billed for instance hours, but RDS starts it again after seven days, and storage keeps billing.
    • Set a backup retention that matches your recovery needs. Automated backup storage up to the size of the database is free, and beyond that you pay.
    • Delete old manual snapshots and unused read replicas, and copy snapshots across Regions only for data that needs it.
    • Upgrade engines before standard support ends. Extended Support is billed per vCPU-hour on top of the normal price.
    • Choose gp3 over older gp2 so you can buy IOPS separately from size, and don’t over-provision storage you’ll never fill.
    • Tag instances by team and project, and set a budget alert for RDS.

    The figures and free-tier terms on this page come from AWS's public pages as we read them. Region, engine, licence option and the date all move them, so confirm the live numbers before you plan around them (see Pricing).

    Security optimisation

    • Place instances in private subnets with Public access off, and allow the database port only from the security groups of the applications that need it.
    • Encrypt storage with KMS when you create the instance, since you can’t just switch it on later, and encrypt snapshots too.
    • Require TLS (rds.force_ssl on PostgreSQL, require_secure_transport on MySQL) and verify the server certificate with the current RDS CA bundle.
    • Let RDS manage the master password in Secrets Manager, and keep the master user out of application code.
    • Use IAM database authentication on engines that support it, so connections use 15-minute tokens instead of stored passwords.
    • Give each application its own database user with only the privileges it needs, and revoke public rights on schemas you care about.
    • Turn on deletion protection and keep final snapshots, and copy important snapshots to a separate account.
    • Export database logs to CloudWatch Logs, record API activity in CloudTrail, and alert on failed logins and parameter changes.
    • Use AWS Config and Security Hub rules to catch public instances, unencrypted storage and missing backups.
    • Limit who can modify, delete or share instances and snapshots with IAM policies and, in a larger setup, service control policies.

    Governance & compliance

    Guardrails

    • Tagging rules for instances and snapshots (owner, environment, data class, cost centre) checked at creation
    • A service control policy that denies creating public instances or unencrypted storage
    • A shared template for databases, with Multi-AZ, backups, TLS and logging already set
    • An approved list of engines, versions and instance classes, with a date for each version’s retirement

    Continuous checks (AWS Config)

    • “rds-instance-public-access-check”
    • “rds-storage-encrypted”
    • “rds-multi-az-support”
    • “rds-instance-deletion-protection-enabled”
    • “db-instance-backup-enabled” and “rds-automatic-minor-version-upgrade-enabled”

    AWS CloudTrail shows who created, changed or deleted instances, AWS Config keeps configuration history and the rules above, AWS Backup can add central backup policies and cross-account copies, and AWS Artifact holds compliance reports. The split is the usual one: AWS runs the hardware, the engine patching and the failover machinery, while you answer for the data, the schema, user access, network exposure and your recovery testing.

    Reduce carbon footprint

    • Right-size the instance. An oversized database burns electricity all day for headroom it never uses.
    • Use Graviton-based classes where your engine supports them. They do more work per watt.
    • Stop or delete development databases at the end of the day or the project, rather than leaving them idle.
    • Keep fewer copies: remove forgotten replicas and old snapshots that nobody will restore.
    • Cache and index well, so queries read less data and the same hardware does more.
    • Choose a Region with a cleaner grid for workloads that aren’t tied to a place, as far as data rules allow.
    • The AWS Customer Carbon Footprint Tool estimates emissions for an account. Check what it includes for RDS before you quote a figure from it.

    Pricing

    Purchase options

    Instance hours Per hour

    You pay for the instance class every hour it’s running, and the rate depends on the engine and, for SQL Server and Oracle, the licence option. Multi-AZ roughly doubles it.

    Storage and I/O Per GB-month

    Storage is charged by size and type, and gp3 and Provisioned IOPS add charges for IOPS and throughput above the included amount.

    Backups and snapshots Per GB-month

    Automated backup space up to your database size is free. Extra backup storage and manual snapshots are charged.

    Extras Varies

    Data transfer out and between Regions, RDS Proxy per vCPU, Enhanced Monitoring, Database Insights Advanced mode and Extended Support for old engine versions.

    What you actually pay for

    • Instance hours by class, engine and licence, doubled for Multi-AZ
    • Storage by type and size, with IOPS and throughput beyond the baseline
    • Backup storage above the free allowance, plus manual snapshots and cross-Region copies
    • Data sent out to the internet or copied to another Region
    • RDS Proxy, Enhanced Monitoring, Database Insights and Extended Support when you use them

    Rates vary by Region, engine and instance class. AWS says new accounts that choose its Free plan get credits that can be used on RDS, while older accounts have a 12-month allowance of small Single-AZ instances, so check which applies to you. See the official Amazon RDS pricing page and the AWS Pricing Calculator for current figures, and the Amazon RDS free tier page for what a new account receives.

    Important code references

    A private PostgreSQL database for an orders application: Multi-AZ, encrypted, 14 days of backups, no public address, the admin password kept in Secrets Manager and IAM sign-in turned on. The CLI and Terraform tabs build it, add a read replica and show a point-in-time restore. The Python and C# tabs connect with a 15-minute IAM token over verified TLS and place an order in a transaction. Replace the subnet group, security group, user and Region with your own. A Multi-AZ instance bills from the moment it starts, so delete the test database when you’re done.

    # Placeholders: replace the subnet group and the security group with ones in your own VPC.
    REGION=ap-south-1
    SG=sg-0123456789abcdef0
    
    # A private, Multi-AZ, encrypted PostgreSQL instance. RDS creates and stores the admin password in Secrets Manager.
    aws rds create-db-instance --region $REGION \
      --db-instance-identifier orders-db \
      --engine postgres --engine-version 16 \
      --db-instance-class db.m7g.large \
      --storage-type gp3 --allocated-storage 100 --max-allocated-storage 500 \
      --storage-encrypted \
      --multi-az \
      --db-subnet-group-name orders-private \
      --vpc-security-group-ids $SG \
      --no-publicly-accessible \
      --master-username orders_admin --manage-master-user-password \
      --enable-iam-database-authentication \
      --backup-retention-period 14 --preferred-backup-window 21:00-21:30 \
      --copy-tags-to-snapshot --deletion-protection \
      --tags Key=owner,Value=orders-team
    
    aws rds wait db-instance-available --region $REGION --db-instance-identifier orders-db
    
    # A read replica for reporting queries
    aws rds create-db-instance-read-replica --region $REGION \
      --db-instance-identifier orders-db-replica \
      --source-db-instance-identifier orders-db \
      --db-instance-class db.m7g.large \
      --no-publicly-accessible
    
    # Practise the restore: a new instance from the backups, at the latest restorable moment
    aws rds restore-db-instance-to-point-in-time --region $REGION \
      --source-db-instance-identifier orders-db \
      --target-db-instance-identifier orders-db-restore-test \
      --use-latest-restorable-time \
      --no-publicly-accessible --no-deletion-protection
    
    # Clean up the test copy (the original has deletion protection on)
    aws rds delete-db-instance --region $REGION --db-instance-identifier orders-db-restore-test --skip-final-snapshot
    # Assumes the AWS provider version 5 or later, an existing VPC with private subnets, and the application's security group
    variable "private_subnet_ids" { type = list(string) }
    variable "vpc_id"             { type = string }
    variable "app_sg_id"          { type = string }
    
    resource "aws_db_subnet_group" "orders" {
      name       = "orders-private"
      subnet_ids = var.private_subnet_ids
    }
    
    resource "aws_security_group" "db" {
      name   = "orders-db"
      vpc_id = var.vpc_id
    
      # PostgreSQL, only from the application's security group
      ingress {
        from_port       = 5432
        to_port         = 5432
        protocol        = "tcp"
        security_groups = [var.app_sg_id]
      }
    }
    
    resource "aws_db_parameter_group" "orders" {
      name   = "orders-postgres16"
      family = "postgres16"
    
      parameter {
        name  = "rds.force_ssl"
        value = "1"
      }
      parameter {
        name  = "log_min_duration_statement"
        value = "500"   # log queries slower than half a second
      }
    }
    
    resource "aws_db_instance" "orders" {
      identifier     = "orders-db"
      engine         = "postgres"
      engine_version = "16"
      instance_class = "db.m7g.large"
    
      storage_type          = "gp3"
      allocated_storage     = 100
      max_allocated_storage = 500
      storage_encrypted     = true
    
      multi_az               = true
      db_subnet_group_name   = aws_db_subnet_group.orders.name
      vpc_security_group_ids = [aws_security_group.db.id]
      publicly_accessible    = false
      parameter_group_name   = aws_db_parameter_group.orders.name
    
      username                            = "orders_admin"
      manage_master_user_password         = true     # RDS keeps it in Secrets Manager
      iam_database_authentication_enabled = true
    
      backup_retention_period   = 14
      backup_window             = "21:00-21:30"
      copy_tags_to_snapshot     = true
      deletion_protection       = true
      skip_final_snapshot       = false
      final_snapshot_identifier = "orders-db-final"
    
      auto_minor_version_upgrade      = true
      enabled_cloudwatch_logs_exports = ["postgresql"]
    
      tags = { owner = "orders-team" }
    }
    
    # A read replica for reporting
    resource "aws_db_instance" "orders_replica" {
      identifier          = "orders-db-replica"
      replicate_source_db = aws_db_instance.orders.identifier
      instance_class      = "db.m7g.large"
      publicly_accessible = false
      storage_encrypted   = true
      skip_final_snapshot = true
    }
    # pip install boto3 "psycopg[binary]"
    # Download the RDS certificate bundle once:  https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
    import time
    
    import boto3
    import psycopg
    
    HOST = "orders-db.abcdefghij.ap-south-1.rds.amazonaws.com"
    REGION = "ap-south-1"
    DB_USER = "app_user"       # created in the database with:  CREATE USER app_user; GRANT rds_iam TO app_user;
    DB_NAME = "orders"
    
    
    def connect():
        """Open a verified TLS connection using a 15-minute IAM token as the password."""
        token = boto3.client("rds", region_name=REGION).generate_db_auth_token(
            DBHostname=HOST, Port=5432, DBUsername=DB_USER, Region=REGION)
        return psycopg.connect(
            host=HOST, port=5432, dbname=DB_NAME, user=DB_USER, password=token,
            sslmode="verify-full", sslrootcert="global-bundle.pem", connect_timeout=5)
    
    
    def place_order(conn, customer_id, total_cents):
        """Insert one order inside a transaction and return its id."""
        with conn.transaction():
            row = conn.execute(
                "INSERT INTO orders (customer_id, total_cents) VALUES (%s, %s) RETURNING id",
                (customer_id, total_cents)).fetchone()
        return row[0]
    
    
    def with_retry(action, attempts=3):
        """Retry on connection failures, which is what a Multi-AZ failover looks like to the app."""
        for attempt in range(1, attempts + 1):
            try:
                with connect() as conn:
                    return action(conn)
            except psycopg.OperationalError:
                if attempt == attempts:
                    raise
                time.sleep(2 * attempt)
    
    
    if __name__ == "__main__":
        new_id = with_retry(lambda c: place_order(c, 42, 129900))
        print(f"Created order {new_id}")
    // Program.cs: sign in with an IAM token over verified TLS and insert an order in a transaction
    // NuGet packages: Npgsql, AWSSDK.RDS
    using Amazon;
    using Amazon.RDS.Util;
    using Npgsql;
    
    const string host = "orders-db.abcdefghij.ap-south-1.rds.amazonaws.com";
    const string user = "app_user";   // CREATE USER app_user; GRANT rds_iam TO app_user;
    
    // A token lasts 15 minutes, so create one just before opening the connection
    var token = RDSAuthTokenGenerator.GenerateAuthToken(RegionEndpoint.APSouth1, host, 5432, user);
    
    var builder = new NpgsqlConnectionStringBuilder
    {
        Host = host,
        Port = 5432,
        Database = "orders",
        Username = user,
        Password = token,
        SslMode = SslMode.VerifyFull,
        RootCertificate = "global-bundle.pem",   // the RDS certificate bundle
        Timeout = 5
    };
    
    using var conn = new NpgsqlConnection(builder.ConnectionString);
    conn.Open();
    
    using var tx = conn.BeginTransaction();
    try
    {
        using var cmd = new NpgsqlCommand("INSERT INTO orders (customer_id, total_cents) VALUES (@c, @t) RETURNING id", conn, tx);
        cmd.Parameters.AddWithValue("c", 42L);
        cmd.Parameters.AddWithValue("t", 129900);
        var id = (long)cmd.ExecuteScalar()!;
        tx.Commit();
        Console.WriteLine($"Created order {id}");
    }
    catch
    {
        tx.Rollback();   // leave nothing half-written
        throw;
    }

    Best videos to explore

    Short walkthrough videos for this service are being prepared. They will appear here and load only when you press play. Until then, follow CloudBrum on YouTube for new videos.

    Introduction to Amazon RDSVideo coming soon · Beginner
    Multi-AZ, read replicas and backups in RDSVideo coming soon · Intermediate
    Securing an RDS databaseVideo coming soon · Intermediate
    RDS upgrades with Blue/Green deploymentsVideo coming soon · Advanced

    Interview questions

    BasicWhat is Amazon RDS?

    It’s AWS’s managed relational database service. You choose an engine (PostgreSQL, MySQL, MariaDB, Oracle, SQL Server or Db2), a machine size and storage, and RDS runs the server, applies patches, takes backups and handles failover. You keep responsibility for the schema, queries, users and network access.

    BasicWhat is the difference between Multi-AZ and a read replica?

    Multi-AZ is for availability: a standby copy in another zone takes over if the primary fails, and in the instance form it serves no queries. A read replica is for scale and recovery: an asynchronous copy that answers read-only queries and can be promoted. Many production systems use both.

    BasicHow long are RDS automated backups kept?

    You choose a retention period from 1 to 35 days (0 turns them off). Together with transaction logs they allow point-in-time restore. Manual snapshots are kept until you delete them.

    IntermediateHow do you restore an RDS database to a moment before someone deleted a table?

    Use point-in-time restore to create a new instance at a time just before the mistake, check that the table is there, and then either copy the data back into the live database or switch the application to the new endpoint. Restores never overwrite the original, so the live instance keeps running while you check.

    IntermediateYour Lambda functions are exhausting the database’s connections. What do you do?

    Put RDS Proxy in front of the database so connections are pooled and reused, keep the functions’ connection use low, and check the max_connections parameter, which depends on instance memory. Scaling up the instance only buys time if the number of connections keeps growing.

    IntermediateHow do you keep an RDS instance private and still let the app connect?

    Place it in private subnets, turn public access off, and open the database port in its security group only to the application’s security group. Connect over TLS, use IAM authentication or Secrets Manager credentials, and reach it from other networks through VPN, Direct Connect or a bastion.

    AdvancedHow would you upgrade a busy production database from one major PostgreSQL version to the next?

    Create a Blue/Green deployment so RDS builds a synchronised copy, upgrade the green side, and test the application against it. When it passes, switch over, which usually takes about a minute, and keep the old blue side for a while as a way back. Rehearse on a copy first, and check extension compatibility and the parameter group for the new version.

    AdvancedDesign the recovery for a database where the Region itself could fail.

    Keep a cross-Region read replica, or copy snapshots to the second Region on a schedule, plus the parameter groups, subnet groups and secrets there. Write down the RPO and RTO, practise promoting the replica, and make the application’s endpoint configuration changeable without a rebuild. Cross-Region replicas are asynchronous, so some recent writes can be lost.

    AdvancedThe database CPU is at 90% after a release. How do you find the cause?

    Look at Database Insights or Performance Insights for the top SQL by load and wait events, compare with the previous deploy, and check pg_stat_statements or the slow query log. Typical causes are a missing index, a changed query plan, an N+1 pattern from an ORM or a burst of connections. Fix the query or the index first, and scale up only if the load is genuine.

    AdvancedWhy might a Multi-AZ failover cause a longer outage than the documentation suggests?

    Clients that cache DNS or hold old connections keep talking to the failed primary. Long DNS TTLs in the application runtime, connection pools that don’t discard broken connections, and long-running transactions all stretch the gap. Use the endpoint name, short caching, retries with backoff, and test with a forced failover before it matters.

    Similar or alternative services on other clouds

    CapabilityAWSAzureGoogle Cloud
    ServiceAmazon RDSAzure Database for PostgreSQL, for MySQL and SQL DatabaseCloud SQL
    EnginesPostgreSQL, MySQL, MariaDB, Oracle, SQL Server, Db2Separate services per engine: PostgreSQL, MySQL, SQL ServerPostgreSQL, MySQL, SQL Server
    A standby in another zoneMulti-AZ instance or Multi-AZ DB clusterZone-redundant high availabilityRegional availability (HA)
    Read scalingRead replicas, in-Region or cross-RegionRead replicas, up to fiveRead replicas
    Keeping backups1 to 35 days automated, plus manual snapshots7 to 35 days with point-in-time restoreRetained backup count (up to 365) plus a log window for point-in-time recovery
    Passwordless sign-inIAM database authenticationMicrosoft Entra authenticationIAM database authentication and the Auth Proxy
    PoolingRDS ProxyBuilt-in PgBouncer (PostgreSQL)Managed connection pooling, or your own pooler
    Safer upgradesBlue/Green deploymentsIn-place upgrades and restore-to-new-serverIn-place upgrades and clones

    If you need scale beyond a single writer, or want storage that scales on its own, look at Amazon Aurora, Azure SQL Hyperscale or AlloyDB, which are separate services. For key-value workloads a NoSQL database is the better fit, and for analytics a warehouse. Application servers that talk to RDS usually run on Amazon EC2 or AWS Lambda.

    Did you find this article helpful?

    Your answer helps us improve this page for the next reader.

    Sources and further reading

    CloudBrum wrote this page in its own words, using the provider’s public documentation listed below as the reference. Features, limits, names and prices change, so confirm anything that matters on the provider’s own pages before you decide.