Back to blogs

Cost-Effective Audit Logging for Amazon RDS: A Practical AWS Architecture

Amazon RDS | AWS | MySQL | CloudWatch | S3 | Athena | Grafana | Cost Optimization

Database auditing is one of those things that often gets added to an AWS environment after a security or compliance requirement appears.

At first, the solution looks simple:

Enable RDS audit logs → send them to CloudWatch → keep them forever.

Technically, this works.

Financially, however, it can become expensive very quickly—especially when you start logging every SQL query, including millions of SELECT, INSERT, UPDATE, and application-generated queries every day.

A better approach is to design RDS auditing around what you actually need to audit, rather than logging everything.

This article explains how to build a cost-effective audit logging architecture for Amazon RDS for MySQL, while still maintaining useful security, operational, and compliance visibility.

The core idea is:

Generate only the audit events you need, keep short-term logs in CloudWatch when real-time investigation is required, and use Amazon S3 for inexpensive long-term retention.

1. Why RDS Audit Logging Can Become Expensive

Consider a production application running on Amazon RDS for MySQL.

Every day, the application might execute:

  • Thousands of authentication events
  • Millions of SELECT queries
  • Hundreds of thousands of INSERT operations
  • Hundreds of thousands of UPDATE operations
  • Database schema changes
  • Background jobs
  • Health checks
  • ORM-generated queries
  • Monitoring queries
  • Replication-related activity

If we enable unrestricted SQL auditing, the database can generate a huge amount of log data.

That creates three separate costs:

  1. Database performance overhead
  2. Log ingestion cost
  3. Log storage and retention cost

The important point is that these costs are not necessarily required.

For many environments, you don't need to know every SELECT statement that an application executes.

You may only need to know:

  • Who connected?
  • Did authentication fail?
  • Who changed the database schema?
  • Who executed DROP TABLE?
  • Who modified privileges?
  • Which application or IP connected to the database?

That is where selective auditing becomes useful.

2. The Basic Architecture

A cost-effective architecture separates the problem into two stages:

                Amazon RDS for MySQL
                        |
                        |
              Audit Plugin
                        |
                        v
             Local Audit Log
      /rdsdbdata/log/audit/
         server_audit.log
                        |
             +----------+----------+
             |                     |
             v                     v
       CloudWatch Logs          S3 Archive
             |                     |
             |                     |
             v                     v
      Real-Time Search        Long-Term Storage
             |                     |
             v                     v
       Alerts / SOC          Athena / Grafana

The architecture has two important responsibilities:

Step 1 — Generate audit events

The MySQL engine needs to actually generate the audit events.

For RDS MySQL, the provided architecture uses the AWS-supported MariaDB Audit Plugin through an RDS option group.

The plugin writes audit information to the local RDS audit log.

Step 2 — Export and retain the logs

Once audit events are generated, they can be routed externally.

Two approaches are possible:

  • RDS → CloudWatch Logs
  • RDS → scheduled retrieval → S3

The first is simpler and provides near-real-time visibility.

The second can significantly reduce ingestion costs when dealing with large audit volumes.

The supplied architecture describes these two stages explicitly: audit generation through MARIADB_AUDIT_PLUGIN, followed by log export through the RDS Audit Log export setting.

3. Why the Audit Plugin Matters

One common mistake is to enable:

RDS → Log exports → Audit log

and assume audit logging is now working.

It isn't necessarily enough.

The database engine must first generate audit events.

The architecture therefore uses:

RDS Option Group
       |
       v
MARIADB_AUDIT_PLUGIN
       |
       v
server_audit.log
       |
       v
CloudWatch Logs

The audit plugin is responsible for generating the audit information, while the RDS log-export mechanism is responsible for shipping it.

The specification also highlights an important operational trap: enabling the CloudWatch audit export without configuring the audit plugin can result in a CloudWatch log group that exists but contains no audit events.

4. The Three Audit Logging Levels

One of the most important decisions is deciding how much SQL activity should actually be logged.

A useful way to think about this is to create three audit tiers.

Tier 1
Selective
    ↓
Authentication + DDL

Tier 2
Moderate
    ↓
Authentication + DDL + DML

Tier 3
Unfiltered
    ↓
Everything

The more you log, the more you pay—in storage, ingestion, processing, and potentially database performance.

5. Tier 1 — Selective Auditing

For most production environments, the first question should be:

Do we really need every database query?

Usually, the answer is no.

A selective audit configuration focuses on security-sensitive events.

Example:

SERVER_AUDIT_EVENTS =
CONNECT,QUERY_DDL

You can also exclude infrastructure and monitoring accounts:

SERVER_AUDIT_EXCL_USERS =
rdsadmin,
datadog_agent,
healthcheck_user,
replication_user

And control the query log size:

SERVER_AUDIT_QUERY_LOG_LIMIT = 1024

This captures events such as:

Authentication

CONNECT

Useful information includes:

  • User
  • Source IP
  • Timestamp
  • Successful connections
  • Failed authentication attempts
  • Disconnect events

For security investigations, this information can be much more useful than millions of routine SELECT statements.

Schema changes

QUERY_DDL

This captures operations such as:

CREATE TABLE
ALTER TABLE
DROP TABLE
TRUNCATE TABLE
RENAME TABLE

For example:

DROP TABLE customers;

An audit trail showing:

User: application_admin
Source IP: 10.20.5.12
Timestamp: 2026-09-21 10:32:11
Statement: DROP TABLE customers

can be extremely valuable during an incident.

The supplied architecture estimates Tier 1 at approximately 1–5 GB/day, compared with dramatically larger volumes for broader auditing.

6. Tier 2 — Moderate Auditing

Some organizations need to know when data is changed.

In that case, authentication and DDL events aren't enough.

You may also need:

QUERY_DML_NO_SELECT

This adds operations such as:

INSERT
UPDATE
DELETE
REPLACE

The resulting configuration becomes:

CONNECT
+
QUERY_DDL
+
QUERY_DML_NO_SELECT

Notice what is intentionally missing:

SELECT

This is an important optimization.

Suppose your application executes:

SELECT * FROM customers WHERE id = 123;

millions of times per day.

Logging every one of those queries can produce enormous audit volumes.

Instead, you can focus on mutations:

UPDATE customers
SET email = 'new@example.com'
WHERE id = 123;

This provides a much stronger audit trail for environments where data modification matters.

The supplied design estimates Tier 2 at roughly 15–50 GB/day, with greater CPU and I/O overhead than selective auditing.

7. Tier 3 — Unfiltered Auditing

The third approach is:

Log everything.

For example:

SERVER_AUDIT_EVENTS = CONNECT,QUERY

This means you may capture:

SELECT
INSERT
UPDATE
DELETE
CREATE
ALTER
DROP

as well as application health checks and other routine database traffic.

At first glance, this sounds like the most secure approach.

But more logging does not automatically mean better security.

There are several problems.

Problem 1 — Huge log volumes

A busy production application could generate enormous audit logs.

The architecture estimates approximately:

100–1,000+ GB/day

for this type of unrestricted auditing.

Problem 2 — Cost

If these logs are continuously pushed into CloudWatch, ingestion charges can become significant.

Problem 3 — Performance

The more queries the database has to audit, the greater the processing overhead.

Problem 4 — Sensitive information

SQL statements can contain sensitive information.

For example:

INSERT INTO users
(name, email, token)
VALUES
('John', 'john@example.com', 'secret-token');

If the entire statement is logged, sensitive values may end up in the audit system.

That means audit logging itself needs security controls.

8. Audit Tier Comparison

FeatureTier 1: SelectiveTier 2: ModerateTier 3: UnfilteredAuthenticationYesYesYesFailed loginsYesYesYesDDLYesYesYesINSERT/UPDATE/DELETENoYesYesSELECTNoNoYesApprox. daily volume1–5 GB15–50 GB100–1,000+ GBCPU overheadLowModerateHighStorage pressureLowModerateHighOperational complexityLowModerateHighTypical useSecurity/complianceData mutation auditingDeep forensic investigation

The important lesson is:

Choose the smallest audit scope that satisfies your actual security and compliance requirements.

The source specification similarly separates these tiers based on logged events, volume, cost, CPU overhead, and compliance use cases.

9. CloudWatch vs S3

Once you decide what to log, the next question is:

Where should those logs live?

Two common choices are:

Option A

RDS
 ↓
CloudWatch Logs

Option B

RDS
 ↓
Audit Logs
 ↓
S3

They solve slightly different problems.

10. CloudWatch: The Easy Option

CloudWatch is attractive because AWS manages the entire streaming process.

You enable:

RDS
→ Modify
→ Log exports
→ Audit log

The audit log is then exported into a CloudWatch log group similar to:

/aws/rds/instance/<db-name>/audit

This provides:

  • Near-real-time logs
  • CloudWatch Logs Insights
  • Metric filters
  • Alarms
  • Easy integration with AWS monitoring
  • Minimal infrastructure to maintain

The supplied architecture describes CloudWatch as the simplest operational path, with logs becoming available in roughly 30–60 seconds.

11. The Problem With Keeping Everything in CloudWatch

CloudWatch is excellent for short-term operational investigation.

It isn't always the most economical place for long-term archival.

Imagine:

5 GB/day

That becomes approximately:

150 GB/month

And:

1 year ≈ 1.8 TB

Now imagine a Tier 2 or Tier 3 workload.

The numbers become much larger.

This is why retention policies matter.

A common architecture is:

RDS
 ↓
CloudWatch
 ↓
7-day retention
 ↓
S3
 ↓
Glacier lifecycle

CloudWatch handles your immediate operational needs.

S3 handles your long-term retention.

The supplied design specifically recommends short CloudWatch retention rather than leaving logs indefinitely in CloudWatch.

12. S3 for Long-Term Audit Storage

Amazon S3 is a natural destination for long-term audit archives.

A possible structure is:

s3://company-audit-logs/

    rds/
        production/
            mysql/
                2026/
                    09/
                        21/
                            audit-001.gz
                            audit-002.gz

This makes the data easier to partition by:

  • Environment
  • Database
  • Year
  • Month
  • Day

You can then apply S3 Lifecycle policies.

For example:

Day 0–30
    S3 Standard

Day 30–90
    S3 Glacier Instant Retrieval

Day 90+
    Glacier Deep Archive

The exact lifecycle should depend on your compliance and investigation requirements.

13. Two Ways to Get RDS Audit Logs Into S3

There are two architectural approaches.

Approach 1 — CloudWatch First

RDS
 ↓
CloudWatch Logs
 ↓
Export/archive
 ↓
S3

This is simpler operationally.

The downside is that the logs first incur CloudWatch ingestion.

Approach 2 — Scheduled Lambda

The architecture you provided also describes a more cost-focused design:

RDS
 ↓
DownloadDBLogFilePortion
 ↓
Lambda
 ↓
gzip
 ↓
S3

A typical implementation uses:

EventBridge
       |
       v
     Lambda
       |
       +----> RDS API
       |
       +----> DynamoDB
       |
       v
      S3

EventBridge

Triggers the Lambda periodically.

For example:

Every 10–15 minutes

Lambda

Retrieves new portions of the audit log.

DynamoDB

Stores state so Lambda knows which portion of the log has already been processed.

S3

Stores compressed audit files.

The supplied design identifies this as a way to bypass CloudWatch ingestion entirely, although it also notes the additional operational complexity and the possibility of log-pruning risk if polling cannot keep up with log rotation.

14. CloudWatch vs Lambda-to-S3

AreaCloudWatchLambda → S3SetupVery simpleMore complexReal-timeYesNoCloudWatch ingestionYesNoLong-term storageExpensiveCheapSearchLogs InsightsAthenaMaintenanceMinimalRequires maintenanceFailure pointsFewMoreBest useOperational monitoringHigh-volume archival

The important architectural point is:

Don't optimize for storage cost at the expense of operational reliability.

If you only generate 1–5 GB/day, CloudWatch may be perfectly reasonable.

If your audit volume becomes tens or hundreds of GB per day, direct S3 archival becomes much more attractive.

15. A Practical Hybrid Architecture

For most production systems, a hybrid architecture is easier to operate:

                  ┌──────────────────────┐
                  │   Amazon RDS MySQL   │
                  └──────────┬───────────┘
                             │
                    MariaDB Audit Plugin
                             │
                             v
                    Audit Log Generation
                             │
                ┌────────────┴────────────┐
                │                         │
                v                         v
        CloudWatch Logs                 S3
        7-day retention            Long-term archive
                │                         │
                │                         │
                v                         v
         Alerts / Logs             Athena Queries
         Insights                      │
                                      v
                                   Grafana

This architecture gives you:

Short-term visibility

CloudWatch provides fast investigation.

Long-term retention

S3 provides inexpensive storage.

Analytics

Athena lets you query archived logs.

Dashboards

Grafana can visualize the audit information.

16. Cost Optimization Doesn't Mean "Use the Cheapest Service"

This is an important DevOps lesson.

Suppose you have two options:

Option A

CloudWatch
$X/month

Option B

Lambda
+
EventBridge
+
DynamoDB
+
S3
+
Athena

Option B may have lower raw ingestion costs.

But it also has:

  • More infrastructure
  • More IAM permissions
  • More failure scenarios
  • More monitoring
  • More code
  • More maintenance

Therefore:

Total cost of ownership matters more than the price of a single AWS service.

For a low-volume audit workload, CloudWatch may be the better engineering decision even if S3 storage is cheaper.

For a high-volume audit workload, the additional architecture may justify itself.

17. CloudWatch Retention Strategy

One of the easiest cost optimizations is simply configuring log retention.

Avoid:

Retention = Never Expire

unless there is a specific reason.

Instead, consider:

CloudWatch
    |
    +-- 7 days

and:

S3
    |
    +-- 30 days Standard
    +-- 90 days Glacier
    +-- Long-term Deep Archive

This creates a clear separation:

Hot data
   ↓
CloudWatch

Warm / archive data
   ↓
S3

Cold compliance data
   ↓
Glacier

18. Querying Archived Logs With Athena

Once audit logs are in S3, you don't necessarily need to move them back into CloudWatch.

You can use:

Amazon Athena

to query them.

Architecture:

S3
 ↓
Athena
 ↓
SQL

For example, conceptually:

SELECT
    event_time,
    user,
    host,
    command
FROM rds_audit_logs
WHERE event_type = 'QUERY_DDL'
AND event_date = '2026-09-21';

You can investigate questions such as:

  • Who changed the schema?
  • When did the change occur?
  • Which database user performed it?
  • What client connected?
  • How many failed login attempts occurred?
  • Which source IP generated the connections?

19. Athena + Grafana

If your organization already operates Grafana, you can build a lightweight audit dashboard.

Architecture:

S3
 ↓
Athena
 ↓
Grafana

Possible dashboard panels:

Authentication

Successful logins
Failed logins
Unique users
Unique source IPs

DDL

CREATE
ALTER
DROP
TRUNCATE

Top users

User
Number of connections
Number of changes

Source IPs

IP address
Connection count
Failed login count

Timeline

Audit events over time

The supplied design estimates the Athena + Grafana approach at approximately $5–$15/month, depending on usage and the existing Grafana infrastructure.

20. Athena + QuickSight

Another option is:

S3
 ↓
Athena
 ↓
Amazon QuickSight

This is attractive when the organization already uses AWS-native BI tooling.

It can provide:

  • Managed dashboards
  • Scheduled reports
  • Visualizations
  • External reporting

The supplied architecture estimates approximately $25–$55/month for the described setup, depending on the QuickSight configuration and usage.

21. Alerting: Don't Just Store Logs

Audit logging is much more useful when important events generate alerts.

For example:

Audit Log
    |
    v
Detection
    |
    v
Alert
    |
    v
Slack / PagerDuty / Security Team

Useful alerts include:

Multiple failed logins

Example threshold:

> 5 failures
within 5 minutes

This can identify potential brute-force activity.

Production schema changes

Alert on:

DROP TABLE
ALTER TABLE
TRUNCATE TABLE

These events can have significant operational impact.

Unexpected source IP

If production RDS should only receive traffic from:

VPC application subnets
VPN
Bastion
Private connectivity

then connections from unexpected locations deserve investigation.

The supplied design proposes these three categories as examples of high-severity audit alerts.

22. Don't Alert on Everything

A common monitoring mistake is creating too many alerts.

For example:

Every SELECT
Every INSERT
Every connection
Every successful login

can create alert fatigue.

Instead, focus alerts on events that require human attention.

For example:

Failed authentication spike
        ↓
Alert

DROP TABLE in production
        ↓
Alert

Unexpected source IP
        ↓
Alert

While normal events can simply be retained:

Successful connection
        ↓
Store

Normal application query
        ↓
Do not audit / store based on policy

23. Security Controls for Audit Logs

Audit logs themselves contain sensitive information.

Therefore, protect them like production data.

Encrypt the logs

Use AWS KMS where appropriate.

For S3:

S3
 ↓
SSE-KMS

For CloudWatch:

CloudWatch Log Group
 ↓
KMS

The architecture recommends KMS-based encryption for both CloudWatch and S3 storage.

24. Restrict Access

Not every engineer needs access to audit logs.

A reasonable model is:

Developers
   ↓
No direct audit access

DevOps
   ↓
Operational access

Security / Compliance
   ↓
Full audit access

Use IAM policies to control:

  • CloudWatch Logs access
  • S3 access
  • Athena access
  • KMS decrypt permissions

For particularly sensitive audit archives, consider additional S3 controls such as:

Bucket policies
Block Public Access
Versioning
Object Lock
KMS
CloudTrail monitoring

25. Protect Against Audit Log Tampering

An audit system is only useful if attackers cannot easily modify the evidence.

A strong architecture separates:

Production AWS Account
        |
        v
Audit Log Bucket
        |
        v
Restricted Security Account

For higher-security environments, consider centralized logging into a dedicated security/logging account.

The goal is to prevent someone who compromises the application environment from simply deleting the audit evidence.

26. Cost Optimization Checklist

Here is the practical checklist I would use when designing RDS audit logging.

1. Don't automatically log every query

Start with:

CONNECT
+
QUERY_DDL

and expand only when there is a documented requirement.

2. Exclude noisy service accounts

Exclude accounts such as:

healthcheck
monitoring
replication

when they do not provide useful audit information.

3. Avoid logging SELECT unless required

SELECT traffic can dominate audit volume.

4. Use CloudWatch for short-term visibility

For example:

7 days

5. Use S3 for long-term retention

Apply lifecycle policies.

6. Compress archived logs

Use:

gzip

before long-term storage.

7. Use Athena for historical investigations

Don't keep every historical log in CloudWatch just because you might need it someday.

8. Reuse existing Grafana infrastructure

If your organization already has Grafana, Athena + Grafana can avoid introducing another dashboard platform.

9. Monitor the audit pipeline

If you use Lambda:

Lambda Errors
Lambda Duration
Lambda Invocations
DynamoDB Errors
S3 Upload Failures
RDS API failures

should be monitored.

10. Review audit requirements periodically

Don't let an audit configuration become permanent simply because someone enabled it years ago.

27. Example Production Architecture

A practical production architecture could look like this:

                       ┌─────────────────────┐
                       │   Application       │
                       └──────────┬──────────┘
                                  │
                                  v
                       ┌─────────────────────┐
                       │ Amazon RDS MySQL    │
                       └──────────┬──────────┘
                                  │
                        Audit Plugin
                                  │
                                  v
                       ┌─────────────────────┐
                       │ Audit Log Generator │
                       └──────────┬──────────┘
                                  │
                 ┌────────────────┴────────────────┐
                 │                                 │
                 v                                 v
        ┌──────────────────┐              ┌─────────────────┐
        │ CloudWatch Logs  │              │       S3        │
        │ 7-day retention  │              │ Long-term logs  │
        └────────┬─────────┘              └────────┬────────┘
                 │                                 │
                 v                                 v
        ┌──────────────────┐              ┌─────────────────┐
        │ Logs Insights    │              │     Athena      │
        └────────┬─────────┘              └────────┬────────┘
                 │                                 │
                 v                                 v
        ┌──────────────────┐              ┌─────────────────┐
        │ CloudWatch       │              │ Grafana / BI    │
        │ Alerts           │              │ Dashboard       │
        └────────┬─────────┘              └─────────────────┘
                 │
                 v
        ┌──────────────────┐
        │ Slack / PagerDuty│
        │ Security Team    │
        └──────────────────┘

This gives you three layers:

Layer 1 — Detection

CloudWatch + alerts.

Layer 2 — Investigation

CloudWatch Logs Insights.

Layer 3 — Historical audit

S3 + Athena + Grafana.

28. A Cost-Effective Strategy by Audit Volume

You can simplify the decision using the following model.

Low-volume audit

1–5 GB/day

Use:

RDS
 ↓
CloudWatch
 ↓
7-day retention
 ↓
S3 archive

The additional operational simplicity is valuable.

Medium-volume audit

15–50 GB/day

Consider:

RDS
 ↓
CloudWatch for short-term
+
S3 for archive

and evaluate whether direct S3 ingestion is justified.

High-volume audit

100+ GB/day

Strongly consider:

RDS
 ↓
Audit logs
 ↓
S3
 ↓
Athena
 ↓
Grafana

while using CloudWatch only for the events that actually require real-time monitoring.

This avoids paying to ingest huge amounts of historical audit data into a hot log analytics system.

29. The Most Important Design Principle

The most important lesson isn't:

"Use S3 because it's cheaper."

It is:

Design the audit scope first, then choose the storage and analytics architecture.

For example:

Requirement
    ↓
What events must be audited?
    ↓
How much data will that generate?
    ↓
Does it require real-time investigation?
    ↓
How long must it be retained?
    ↓
Where should it be stored?
    ↓
How should it be queried?
    ↓
What should generate alerts?

This prevents over-engineering.

30. Recommended Reference Architecture

For a typical AWS production environment, a practical design is:

AUDIT GENERATION
       |
       v
MARIADB_AUDIT_PLUGIN
       |
       +-------------------------+
       |                         |
       v                         v
CONNECT + DDL              DML if required
       |                         |
       +------------+------------+
                    |
                    v
              Audit Logs
                    |
          +---------+---------+
          |                   |
          v                   v
    CloudWatch               S3
    7-day TTL           Long-term archive
          |                   |
          v                   v
      Alerts              Athena
                              |
                              v
                           Grafana

Start with selective auditing.

Expand only when a real requirement exists.

31. Final Takeaway

RDS audit logging doesn't have to become an expensive logging project.

The biggest cost optimization is actually made before the log reaches CloudWatch or S3.

If you generate unnecessary logs, no storage architecture can completely solve the problem.

A better strategy is:

1. Audit only meaningful events
             ↓
2. Exclude noisy service accounts
             ↓
3. Avoid SELECT auditing unless required
             ↓
4. Use CloudWatch for short-term investigation
             ↓
5. Use S3 for long-term retention
             ↓
6. Compress and lifecycle archived logs
             ↓
7. Use Athena for historical analysis
             ↓
8. Use Grafana/QuickSight for dashboards
             ↓
9. Alert only on high-value security events

For many environments, selective auditing + short CloudWatch retention + S3 archival provides a good balance between security visibility, operational simplicity, and cost.

For high-volume audit requirements, a more direct RDS → S3 → Athena → Grafana architecture can reduce CloudWatch ingestion costs, but it introduces additional components and operational responsibilities.

The right architecture is therefore not simply the cheapest one.

It is the one that gives your organization the required audit evidence with the lowest practical operational and financial overhead.

Quick Reference

RequirementRecommended ApproachAuthentication auditingCONNECTSchema-change auditingQUERY_DDLData-change auditingQUERY_DML_NO_SELECTAvoid excessive volumeDon't audit SELECT unless requiredReal-time investigationCloudWatch LogsShort-term retentionCloudWatchLong-term retentionS3Cold archivalS3 Glacier classesHistorical SQL analysisAthenaExisting Grafana environmentAthena + GrafanaAWS-native BIAthena + QuickSightHigh-volume auditPrefer S3-centric architectureLow-volume auditCloudWatch + S3 hybridSecurityKMS + IAM + private S3 + restricted accessAlertingFailed logins, production DDL, unexpected sources

The goal of audit logging is not to collect the maximum amount of data. The goal is to collect the right evidence, retain it securely, and make it available when you actually need it.