Loading learning content...
You've now gained deep knowledge of MySQL—its storage engine architecture, replication capabilities, how it compares to PostgreSQL, and the cloud offerings that extend its capabilities. The final question is the most practical: When should you actually choose MySQL for your system?
Database selection is a high-stakes decision. Migrating databases after launch is expensive, risky, and disruptive. Teams often live with suboptimal choices for years because the cost of change is too high. Getting this decision right initially—or at least making an informed trade-off—saves enormous future pain.
This page synthesizes everything you've learned into actionable decision frameworks. We'll examine where MySQL excels, where it struggles, real-world success stories, and red flags that suggest a different database might be better.
The goal isn't to make MySQL the answer to every problem—it's to help you recognize when MySQL is genuinely the right tool for your specific requirements.
By the end of this page, you will understand MySQL's ideal use cases and workload profiles, recognize anti-patterns where MySQL isn't the best fit, learn from real-world MySQL deployments at scale, and develop a systematic decision framework for database selection.
MySQL has powered some of the world's largest websites and applications for decades. Let's examine the workloads and use cases where MySQL genuinely excels.
Web Applications and SaaS Platforms:
MySQL's heritage is in the LAMP stack (Linux, Apache, MySQL, PHP/Python/Perl). This isn't just historical accident—MySQL's design genuinely suits web application patterns:
E-commerce and Transactional Systems:
E-commerce platforms need ACID guarantees, complex joins across products/orders/customers, and reliable replication for high availability. MySQL with InnoDB delivers all of this.
| Requirement | MySQL Capability |
|---|---|
| Inventory updates must be atomic | InnoDB ACID transactions with row-level locking |
| Order history across 100M+ orders | Clustered index on order_id for efficient range scans |
| Shopping cart state | Foreign keys to products table with cascade delete |
| Payment processing | Durable commits with innodb_flush_log_at_trx_commit=1 |
| Read scaling for product catalog | Read replicas behind load balancer |
Content Management Systems:
WordPress, the world's most popular CMS, uses MySQL (or MariaDB). Drupal, Joomla, and countless other CMS platforms do too. Why?
High-Availability Critical Systems:
When you need proven HA with auto-failover, InnoDB Cluster and Group Replication provide built-in solutions that don't require external orchestration tools:
If your application is a "typical" web application with user accounts, content, and transactions, MySQL will handle it excellently. The advice "start with MySQL and migrate if needed" is reasonable because most applications never actually need to migrate—MySQL serves them well indefinitely.
Nothing validates technology choices like production use at scale. Let's examine how major companies use MySQL.
YouTube / Google:
YouTube built Vitess specifically to scale MySQL for video metadata. Today, Vitess (and by extension, PlanetScale) powers YouTube's database layer.
GitHub:
GitHub runs on MySQL. As of 2023, GitHub's database infrastructure includes:
| Company | Scale | Notable Approach |
|---|---|---|
| Facebook/Meta | Billions of users, 60M+ QPS | Custom MySQL (MyRocks), sharding, semi-sync replication |
| Airbnb | Millions of listings, global | MySQL on AWS RDS, read replicas for scale |
| Uber | Millions of trips daily | Custom MySQL layer with Schemaless abstraction |
| Shopify | Thousands of merchants, billions of transactions | MySQL with Vitess-style sharding |
| Netflix | Billing and metadata | MySQL for transactional data (not streaming) |
| Twitter/X | Billions of tweets | MySQL for user accounts, supplemented by other stores |
What These Examples Teach Us:
The companies listed above have dedicated database teams, custom tooling, and years of institutional knowledge. Don't assume you can replicate their architecture on day one. Start simple, scale incrementally, and invest in operations as you grow.
Knowing where MySQL excels is important, but equally important is recognizing where it struggles. Here are workloads and patterns where MySQL may not be the best choice.
Complex Analytical Queries:
If your primary workload is analytics—complex aggregations, joins across many tables, window functions over large datasets—MySQL's optimizer may struggle:
Document-Centric Workloads:
While MySQL supports JSON, if your data is primarily documents with variable schemas and nested structures:
Graph Relationships:
For social networks, recommendation engines, or any workload requiring multi-hop relationship traversals:
1234567891011121314151617181920212223
-- Find friends of friends (2 hops)SELECT DISTINCT f2.friend_idFROM friendships f1JOIN friendships f2 ON f1.friend_id = f2.user_idWHERE f1.user_id = 123;-- This works, but... -- Find friends within 6 degrees of separation?-- Recursive CTEs work but are inefficient for deep traversalsWITH RECURSIVE connections AS ( SELECT friend_id, 1 as depth FROM friendships WHERE user_id = 123 UNION SELECT f.friend_id, c.depth + 1 FROM connections c JOIN friendships f ON c.friend_id = f.user_id WHERE c.depth < 6)SELECT * FROM connections;-- This gets expensive FAST on large graphs -- Graph databases (Neo4j, Dgraph) are optimized for exactly this:-- They store adjacency lists, not join tables-- Traversals are O(edges) not O(nodes^2)Time-Series Data:
IoT sensors, metrics, logs—high-volume append-only time-stamped data:
| Challenge | Why It's Hard in MySQL | Better Alternative |
|---|---|---|
| Write volume | Row-by-row inserts; B+tree overhead | InfluxDB, TimescaleDB (columnar, batch ingestion) |
| Time-based queries | Standard indexes; no built-in retention | Native time partitioning and automatic roll-off |
| Aggregations | Compute at query time | Pre-aggregated rollups, continuous aggregates |
| Storage efficiency | Row storage overhead | Columnar compression (10x reduction) |
Full-Text Search as Primary Workload:
If your application is search-centric:
Choosing MySQL because "we always use MySQL" when your workload is fundamentally different creates long-term pain. A graph database for a social network, a time-series database for IoT, or Elasticsearch for search isn't over-engineering—it's using the right tool for the job.
Let's develop a systematic framework for evaluating whether MySQL fits your requirements.
Requirement Categories:
| Requirement | MySQL Strong | MySQL Neutral | MySQL Weak |
|---|---|---|---|
| ACID transactions | ✓ | ||
| Relational data model | ✓ | ||
| Read-heavy workloads | ✓ | ||
| Simple CRUD patterns | ✓ | ||
| Built-in HA | ✓ | ||
| Framework/ORM support | ✓ | ||
| Complex analytics | ✓ | Better: PostgreSQL, analytics DB | |
| Advanced JSON querying | ✓ | Better: PostgreSQL JSONB | |
| Multi-hop graph traversals | Better: Graph DB | ||
| High-volume time-series | Better: TimescaleDB, InfluxDB | ||
| Search-centric workload | Better: Elasticsearch | ||
| Horizontal write scaling | ✓ (Vitess) | Consider NoSQL if extreme |
The MySQL Decision Flow:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546
┌────────────────────────────────────────────────────────────┐│ Should I Use MySQL? │└───────────────────────────┬────────────────────────────────┘ │ ▼┌───────────────────────────────────────────────────────────┐│ Is your data fundamentally relational (tables, joins)? ││ ││ YES ──────────────────────────────────────▶ Continue ││ NO ───▶ Consider: Document DB, Graph DB, Key-Value │└───────────────────────────┬───────────────────────────────┘ │ ▼┌───────────────────────────────────────────────────────────┐│ Do you need ACID transactions? ││ ││ YES (critical) ───────────────────────────▶ Continue ││ NO (eventual consistency OK) ─▶ Consider: NoSQL options │└───────────────────────────┬───────────────────────────────┘ │ ▼┌───────────────────────────────────────────────────────────┐│ What's your primary query pattern? ││ ││ Simple CRUD, lookups by key ───────────▶ MySQL fits well ││ Complex analytics, large scans ─▶ Consider: PostgreSQL ││ Search/full-text heavy ─────────▶ Consider: Elasticsearch││ Graph traversals ───────────────▶ Consider: Neo4j │└───────────────────────────┬───────────────────────────────┘ │ ▼┌───────────────────────────────────────────────────────────┐│ Do you need horizontal write scaling beyond 1 node? ││ ││ NO ─────────────────────────────────────▶ MySQL fits well││ YES ─▶ Consider: PlanetScale/Vitess, or NoSQL options │└───────────────────────────┬───────────────────────────────┘ │ ▼┌───────────────────────────────────────────────────────────┐│ Does your team have MySQL expertise? ││ ││ YES ─────────────────────────────────────▶ MySQL fits ││ NO, but willing to learn ────────────────▶ MySQL fits ││ Prefer PostgreSQL expertise ─────▶ Consider: PostgreSQL │└───────────────────────────────────────────────────────────┘If you reach the end of this decision tree and both MySQL and PostgreSQL would work, choose based on: (1) Team expertise, (2) Specific features needed (PostGIS, JSONB, InnoDB Cluster), (3) Cloud provider offerings (Aurora vs AlloyDB). Neither is wrong for general workloads.
If you've decided MySQL is the right choice, this checklist ensures you're ready for production.
Infrastructure:
Configuration:
1234567891011121314151617181920212223242526
[mysqld]# InnoDB Settingsinnodb_buffer_pool_size = 12G # 70-80% of available RAMinnodb_log_file_size = 2G # Larger for write-heavy workloadsinnodb_flush_log_at_trx_commit = 1 # ACID compliance (use 2 on replicas)innodb_file_per_table = ON # Easier table managementinnodb_flush_method = O_DIRECT # Skip OS cache for data (Linux) # Replicationgtid_mode = ON # Use GTIDs for replicationenforce_gtid_consistency = ONbinlog_format = ROW # Deterministic replicationlog_slave_updates = ON # Replicas can replicate to otherssync_binlog = 1 # Durability for binlog # Connectionsmax_connections = 500 # Monitor and adjustthread_cache_size = 100 # Reuse threads # Query Monitoringslow_query_log = ONlong_query_time = 1 # Log queries over 1 secondlog_queries_not_using_indexes = ON # Find missing indexes # Performance Schemaperformance_schema = ON # Required for monitoringApplication-Level:
Operational Readiness:
The #1 production incident trap: assuming failover works without testing it. Schedule quarterly failover tests. The first time you exercise your HA setup should not be during a real outage at 3 AM.
Database migrations are expensive but sometimes necessary. Here's guidance for common migration scenarios.
Migrating TO MySQL:
| Source | Complexity | Key Considerations |
|---|---|---|
| PostgreSQL | Medium | Data types differ (arrays, JSONB); no partial indexes; RETURNING clause needs workaround |
| SQL Server | Medium-High | Stored procedure rewriting; different transaction semantics; collation differences |
| Oracle | High | PL/SQL to MySQL procedures; partitioning differences; hint syntax |
| MongoDB | High | Schema design required; denormalization strategy; many-to-many relationships |
Migrating FROM MySQL:
| Target | Reason to Migrate | Key Considerations |
|---|---|---|
| PostgreSQL | Need advanced features (JSONB, PostGIS, better optimizer) | Most SQL is compatible; test complex queries carefully |
| Aurora MySQL | Want cloud-native MySQL with better HA/performance | Minimal changes; mostly operational/cost evaluation |
| PlanetScale | Need horizontal scaling, better DevEx | Remove foreign keys; adjust for no FK enforcement |
| Vitess (self-hosted) | Need sharding with full control | Significant operational complexity; choose sharding keys |
Migration Best Practices:
AWS Database Migration Service (DMS) handles ongoing replication between source and target during migration. It supports MySQL as both source and target, and can transform data during migration. Useful for continuous replication until cutover.
Choosing MySQL today should account for where your system might be in 3-5 years. Here's how to keep your options open.
Design for Scalability:
Cloud-Native Readiness:
Operational Excellence:
MySQL has been production-critical for 30 years and shows no signs of declining relevance. Oracle continues active development, cloud providers invest heavily in MySQL offerings, and community forks (MariaDB, Percona) provide alternatives. Your MySQL investment is future-safe.
We've covered when to choose MySQL, examining ideal use cases, anti-patterns, and production readiness. Let's consolidate the key decision points:
Module Complete:
You've now completed a comprehensive deep dive into MySQL. You understand:
This knowledge enables you to make informed decisions about MySQL in system design, whether you're evaluating it for a new project, optimizing an existing deployment, or planning a migration.
Congratulations! You've mastered MySQL from first principles to production deployment. Whether you're designing a new system, interviewing for a system design role, or optimizing an existing MySQL deployment, you now have the deep knowledge needed to make expert-level decisions.