Running MySQL in Azure: Azure Database for MySQL

Azure Database for MySQL Flexible Server is Microsoft’s managed MySQL service. You get a real MySQL server — the same SQL syntax, drivers, and tools you already know — without managing the underlying OS, patching MySQL binaries, or setting up replication. This page walks through creating a server, connecting to it, and configuring it for production use.

What Flexible Server gives you

Azure Database for MySQL Flexible Server is the current generation of Azure’s managed MySQL service. Compared to the retired Single Server model, Flexible Server adds:

  • Availability zone support — you can pin the server to a specific zone for predictable latency from zone-local VMs
  • Same-zone high availability — a standby replica in the same zone for fast failover
  • Zone-redundant high availability — standby in a different zone for higher resilience
  • Configurable maintenance windows — you choose when patches and updates happen
  • Burstable compute — smaller instance types that can burst CPU for short periods, good for dev/test

The MySQL version, connection strings, drivers, and SQL syntax are identical to a self-managed MySQL server. Migrating an existing MySQL application to Azure requires no code changes.

Creating a MySQL Flexible Server

# Create a MySQL Flexible Server with public access and a firewall rule
az mysql flexible-server create \
  --resource-group my-storage-rg \
  --name my-mysql-server-demo \
  --location eastus \
  --admin-user mysqladmin \
  --admin-password "P@ssw0rd!MySQL123" \
  --sku-name Standard_B1ms \
  --tier Burstable \
  --version 8.0 \
  --storage-size 32 \
  --public-access 0.0.0.0

# The --public-access 0.0.0.0 creates the server but only allows Azure services
# For dev access, add your own IP:
MY_IP=$(curl -s ifconfig.me)
az mysql flexible-server firewall-rule create \
  --resource-group my-storage-rg \
  --name my-mysql-server-demo \
  --rule-name AllowMyIP \
  --start-ip-address $MY_IP \
  --end-ip-address $MY_IP

The Standard_B1ms SKU with Burstable tier is a small instance (1 vCore, 2 GB RAM) suitable for development. For production, use Standard_D or Standard_E tier with more vCores.

Available compute tiers:

  • Burstable — low baseline CPU, can burst for short periods. Good for development and low-traffic apps.
  • General Purpose — balanced compute and memory, suitable for most production workloads.
  • Memory Optimized — high memory-to-vCore ratio, good for cache-heavy MySQL workloads.

Creating a server with VNet integration (production)

For production, create the server inside a VNet so it has no public endpoint:

# Create a VNet and subnet first
az network vnet create \
  --resource-group my-storage-rg \
  --name my-app-vnet \
  --address-prefix 10.0.0.0/16

az network vnet subnet create \
  --resource-group my-storage-rg \
  --vnet-name my-app-vnet \
  --name mysql-subnet \
  --address-prefix 10.0.1.0/24

# Create the MySQL server with private VNet access
az mysql flexible-server create \
  --resource-group my-storage-rg \
  --name my-mysql-private \
  --location eastus \
  --admin-user mysqladmin \
  --admin-password "P@ssw0rd!MySQL123" \
  --sku-name Standard_D2ds_v4 \
  --tier GeneralPurpose \
  --version 8.0 \
  --vnet my-app-vnet \
  --subnet mysql-subnet \
  --private-dns-zone my-mysql-private.private.mysql.database.azure.com

With VNet integration, the server gets a private IP address in the subnet. Only resources connected to the VNet (or peered networks) can reach it.

Connecting to the server

The connection hostname follows the pattern: <server-name>.mysql.database.azure.com.

# Connect with the standard MySQL client
mysql \
  --host my-mysql-server-demo.mysql.database.azure.com \
  --user mysqladmin \
  --password \
  --ssl-mode REQUIRED

# Or with all parameters inline (not recommended for interactive use — password appears in history)
mysql -h my-mysql-server-demo.mysql.database.azure.com \
      -u mysqladmin -p"P@ssw0rd!MySQL123" \
      --ssl-mode REQUIRED

SSL is required by default. The MySQL client connects over TLS using Azure’s certificate. If your application’s MySQL client library requires an explicit SSL CA certificate, download the DigiCert Global Root G2 certificate from Microsoft’s documentation.

Basic operations after connecting

-- Create a database
CREATE DATABASE myappdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- Create a dedicated application user (not using the admin account)
CREATE USER 'appuser'@'%' IDENTIFIED BY 'AppUserP@ss123';
GRANT SELECT, INSERT, UPDATE, DELETE ON myappdb.* TO 'appuser'@'%';
FLUSH PRIVILEGES;

-- Use the database
USE myappdb;

-- Create a table
CREATE TABLE products (
    id INT AUTO_INCREMENT PRIMARY KEY,
    sku VARCHAR(50) NOT NULL UNIQUE,
    name VARCHAR(200) NOT NULL,
    price DECIMAL(10, 2) NOT NULL,
    stock_quantity INT DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_sku (sku)
) ENGINE=InnoDB;

-- Insert test data
INSERT INTO products (sku, name, price, stock_quantity)
VALUES
    ('PROD-001', 'Widget A', 9.99, 100),
    ('PROD-002', 'Widget B', 14.99, 50),
    ('PROD-003', 'Gadget X', 49.99, 25);

-- Query with aggregation
SELECT
    COUNT(*) AS total_products,
    SUM(price * stock_quantity) AS total_inventory_value,
    AVG(price) AS avg_price
FROM products;

Server configuration parameters

Azure Database for MySQL exposes MySQL server variables that you can tune. Common ones to check:

# List all server parameters
az mysql flexible-server parameter list \
  --resource-group my-storage-rg \
  --server-name my-mysql-server-demo \
  --output table

# Show a specific parameter
az mysql flexible-server parameter show \
  --resource-group my-storage-rg \
  --server-name my-mysql-server-demo \
  --name max_connections

# Change a parameter (e.g., slow query log threshold)
az mysql flexible-server parameter set \
  --resource-group my-storage-rg \
  --server-name my-mysql-server-demo \
  --name slow_query_log \
  --value ON

az mysql flexible-server parameter set \
  --resource-group my-storage-rg \
  --server-name my-mysql-server-demo \
  --name long_query_time \
  --value 2

Common mistakes

  1. Using the admin account in application connection strings. The admin account has superuser privileges. If your application’s connection string is compromised, an attacker gets full access to all databases on the server. Create a dedicated application user with only the permissions needed for that application.
  2. Not specifying the database character set on creation. MySQL defaults to latin1 in older versions or utf8mb3 in 8.0. Create databases with CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci explicitly. utf8mb4 supports the full Unicode range including emoji, while utf8mb3 (MySQL’s “utf8”) does not.
  3. Choosing Burstable tier for production workloads. Burstable instances accumulate CPU credits and burst when available, but they can be throttled when credits run out. For sustained production traffic, use General Purpose or Memory Optimized. Burstable is for dev/test only.
  4. Forgetting that the server needs to be restarted after some parameter changes. Some MySQL server parameters require a server restart to take effect. Check the parameter’s isDynamicConfig value — if false, a restart is needed. Plan maintenance windows for these changes.

Frequently asked questions

What happened to Azure Database for MySQL Single Server?

Single Server was the original deployment model. Microsoft has retired it in favor of Flexible Server, which offers more control, better performance options, and additional features. If you have an existing Single Server deployment, Microsoft is migrating those to Flexible Server. All new MySQL deployments on Azure should use Flexible Server.

What MySQL versions does Azure Database for MySQL support?

Azure Database for MySQL Flexible Server supports MySQL 5.7 and MySQL 8.0. MySQL 5.7 reaches end of life in October 2023 (community support), so new applications should target MySQL 8.0.

Can I use Azure Database for MySQL with a VNet?

Yes. During creation you can deploy the server with private access (VNet integration), which means it has no public endpoint — only resources inside the VNet can connect. Alternatively, you can deploy with public access and restrict it with firewall rules. Private VNet access is recommended for production.

Last verified: 19 March 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.