Many applications already depend on MySQL. They have existing database schemas, stored procedures, SQL queries, application services, and reporting systems built around the MySQL ecosystem.
When these applications start experiencing increased traffic or require better availability, developers often consider moving to a managed database service.
Amazon Aurora MySQL-Compatible Edition is one option.
Aurora provides a managed relational database engine that maintains compatibility with MySQL while introducing a different storage architecture, automated backups, read replicas, and managed failover.
The important advantage is that an existing application can often continue using its MySQL drivers, SQL queries, and database access code with relatively few changes.
However, MySQL compatibility does not mean that every MySQL feature behaves identically in Aurora. Developers should understand the supported versions, database architecture, connection endpoints, and operational differences before migrating.
In this article, we will explore how to use Amazon Aurora MySQL with an existing application and connect it to a C# application using the MySqlConnector library.
What Is Amazon Aurora MySQL?
Amazon Aurora MySQL is a managed relational database engine available through Amazon Relational Database Service (Amazon RDS).
It is designed to provide MySQL compatibility while using an AWS-managed distributed storage architecture.
The application continues communicating with the database using the MySQL protocol. Existing database drivers, development tools, and many application queries can continue working without significant modifications.
Some important capabilities include:
- MySQL-compatible SQL and application connectivity.
- Managed database backups and recovery.
- Automated failover.
- Read replicas for read-intensive workloads.
- Storage that grows automatically as database requirements increase.
- Integration with AWS monitoring and security services.
- Support for managed database maintenance and engine upgrades.
One important distinction is that Aurora is not simply a MySQL database installed on an Amazon EC2 instance. Its storage and database infrastructure are designed specifically for the AWS environment.
Understand MySQL Compatibility and Supported Versions
Before selecting Aurora, identify the MySQL version currently used by your application.
Aurora has its own engine versioning system, and its version numbers do not always match the corresponding Community MySQL release.
The main compatibility options include:
Aurora version | MySQL compatibility |
|---|
Aurora MySQL 2.x | MySQL 5.7 |
Aurora MySQL 3.x | MySQL 8.0 |
Aurora MySQL 8.4 | MySQL 8.4 |
Aurora MySQL 8.4 became generally available in May 2026. It introduces direct version alignment with the corresponding Community MySQL 8.4 releases.
For new deployments, Aurora MySQL 8.4 is worth evaluating when the application supports MySQL 8.4.
For applications currently running MySQL 8.0, Aurora MySQL 3.x may be an appropriate compatibility target.
However, version compatibility alone is not enough. Check the exact Aurora engine version, supported features, and end-of-support dates before selecting a release.
For example, AWS lists April 30, 2028, as the end of standard support for Aurora MySQL 3. The corresponding Community MySQL 8.0 release reached its end of life in April 2026.
Aurora MySQL 8.4 has a longer support horizon, with standard support currently listed through April 2032.
These dates make version selection an important part of long-term database planning.
Understand How Aurora MySQL Architecture Works
The most important difference between traditional MySQL deployments and Aurora is the database architecture.
In a traditional MySQL deployment, the database engine and its storage are closely associated with the database server.
Aurora separates the database compute layer from its distributed storage layer.
An Aurora cluster contains:
- A primary database instance that handles read and write operations.
- Optional Aurora Replicas that handle read-only operations.
- A shared cluster storage volume used by the database instances.
Aurora automatically maintains six copies of storage data across three Availability Zones.
This architecture provides durability and allows Aurora to continue operating when individual storage components become unavailable.
Aurora also supports up to 15 Aurora Replicas in a cluster.
The important point is that these replicas share the same underlying cluster storage volume. They do not require a traditional full database copy for every reader instance.
This makes it possible to add read capacity without managing an entirely separate replication infrastructure.
Connect an Existing C# Application to Aurora MySQL
One of the advantages of Aurora MySQL is that existing MySQL-compatible drivers can be reused.
For a .NET application, MySqlConnector is a popular ADO.NET driver that supports MySQL, MariaDB, and Amazon Aurora.
Install the package:
dotnet add package MySqlConnector
Now configure the database connection string.
{
"ConnectionStrings": {
"AuroraWriter": "Server=your-cluster.cluster-xxxx.us-east-1.rds.amazonaws.com;Port=3306;Database=AppDb;User ID=appuser;Password=your-password;SslMode=VerifyFull;",
"AuroraReader": "Server=your-cluster.cluster-ro-xxxx.us-east-1.rds.amazonaws.com;Port=3306;Database=AppDb;User ID=appuser;Password=your-password;SslMode=VerifyFull;"
}
}
The endpoint values are examples. Replace them with the actual endpoints from your Aurora cluster.
For production, do not store database passwords directly in appsettings.json. Use AWS Secrets Manager or another secure configuration provider.
Also configure the trusted certificate authority required by your environment when using full TLS certificate verification.
The important configuration is the database endpoint.
Aurora provides different endpoints for different connection purposes. We will examine them before implementing the repository.
Understand Aurora Database Endpoints
Aurora provides managed endpoints that allow applications to connect to the appropriate database instances.
Endpoint | Purpose |
|---|
Cluster endpoint | Connects to the current primary instance |
Reader endpoint | Distributes connections among available reader instances |
Instance endpoint | Connects to a specific database instance |
Custom endpoint | Connects to a configured group of database instances |
The cluster endpoint should be used for write operations such as INSERT, UPDATE, and DELETE.
It can also handle read queries.
The reader endpoint is designed for read-only workloads such as reporting, dashboards, and data retrieval.
One important detail is that the reader endpoint balances connections, not individual SQL queries. If an application keeps one connection open, its queries continue using the instance selected for that connection.
This distinction matters when implementing connection pooling.
Implement Database Access Using C#
Let's create a simple repository that retrieves customer information from Aurora.
The example uses the MySqlConnector library directly.
using MySqlConnector;
public class CustomerRepository
{
private readonly string _connectionString;
public CustomerRepository(IConfiguration configuration)
{
_connectionString =
configuration.GetConnectionString("AuroraWriter")
?? throw new InvalidOperationException(
"Aurora connection string is missing.");
}
public async Task<Customer?> GetCustomerAsync(
int customerId,
CancellationToken cancellationToken)
{
await using var connection =
new MySqlConnection(_connectionString);
await connection.OpenAsync(cancellationToken);
const string sql = """
SELECT CustomerId, CustomerName, Email
FROM Customers
WHERE CustomerId = @CustomerId;
""";
await using var command =
new MySqlCommand(sql, connection);
command.Parameters.AddWithValue(
"@CustomerId",
customerId);
await using var reader =
await command.ExecuteReaderAsync(cancellationToken);
if (!await reader.ReadAsync(cancellationToken))
{
return null;
}
return new Customer
{
CustomerId = reader.GetInt32("CustomerId"),
CustomerName = reader.GetString("CustomerName"),
Email = reader.GetString("Email")
};
}
}
public class Customer
{
public int CustomerId { get; set; }
public string CustomerName { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
}
The important part is that the repository uses a standard MySQL connection.
There is no special Aurora-specific SQL syntax in this example.
The application opens a connection, executes a parameterized query, and reads the result.
This is one of the reasons Aurora can be attractive for applications that already use MySQL.
However, always test your existing SQL queries, stored procedures, triggers, and database features against the selected Aurora engine version before migration.
Separate Read and Write Operations
As an application grows, sending every query to the primary database instance can increase its workload.
Aurora allows developers to distribute read-only operations across Aurora Replicas.
A practical approach is to maintain separate connection strings.
For example:
public class CustomerReadRepository
{
private readonly string _connectionString;
public CustomerReadRepository(IConfiguration configuration)
{
_connectionString =
configuration.GetConnectionString("AuroraReader")
?? throw new InvalidOperationException(
"Aurora reader connection string is missing.");
}
}
Use the writer endpoint for operations that modify data and the reader endpoint for suitable read-only operations.
However, do not send every SELECT query to a reader automatically.
Consider an application that creates an order and immediately retrieves it.
If the read goes to a reader before replication has made the latest changes visible, the application may temporarily return stale information.
For read-after-write scenarios that require immediate consistency, use the writer endpoint.
For reporting and other workloads that can tolerate replication lag, the reader endpoint is generally more appropriate.
Plan for Automatic Failover
Database availability is an important consideration for production applications.
Aurora automatically detects failures of the primary instance and can promote an available Aurora Replica to become the new primary.
The cluster endpoint automatically follows the new primary instance.
This means applications do not need to permanently store the hostname of a particular writer instance.
However, automatic failover does not mean existing application connections will never fail.
During failover, active connections can be interrupted. Applications should be prepared to reconnect and retry appropriate operations.
For .NET applications, consider the following practices:
- Use the Aurora cluster endpoint instead of a fixed instance endpoint for writes.
- Configure sensible connection timeouts.
- Handle transient database errors.
- Reopen connections when necessary.
- Use bounded retries with appropriate backoff.
- Avoid retrying non-idempotent operations without checking whether the previous operation succeeded.
- Test failover behavior before production deployment.
For applications requiring additional connection management, Amazon RDS Proxy can also be evaluated.
Understand the Limitations of MySQL Compatibility
Although Aurora supports MySQL compatibility, developers should not assume that every MySQL feature is available.
Some features and behaviors differ because Aurora uses its own database architecture and managed implementation.
Before migration, review:
- Storage engine requirements.
- Stored procedures and triggers.
- Replication and binary logging requirements.
- User authentication plugins.
- Database parameter settings.
- SQL modes and server variables.
- Third-party extensions and integrations.
- Administrative privileges and unsupported operations.
For example, applications that depend on a particular MySQL storage engine or low-level server configuration may require changes.
Aurora MySQL 8.4 also introduces security-related differences. New clusters enforce TLS by default, and new accounts use the caching_sha2_password authentication plugin.
Applications with older database drivers or authentication configurations should be tested before upgrading.
Do not treat a successful database connection as proof that the entire application is compatible.
Summary
Amazon Aurora MySQL provides a managed database option for applications that need to retain their existing MySQL ecosystem.
Its compatibility allows many applications to reuse existing SQL queries, drivers, and database access code. At the same time, Aurora introduces a distributed storage architecture, managed backups, read replicas, and automatic failover.
For .NET applications, MySqlConnector provides a familiar way to connect to Aurora using standard ADO.NET patterns.
The most important implementation decisions involve selecting the correct MySQL-compatible engine version, using the appropriate database endpoints, separating read and write workloads, and preparing the application for connection interruptions during failover.
Aurora can reduce database infrastructure management, but compatibility should always be verified against the application's actual SQL, drivers, authentication requirements, and operational workload before moving production data.
Join the conversation! Your thoughts help the community grow.