Readyset Weekly: Issue 12
How to Scale MySQL Without Sharding
Sharding (splitting your data across databases) is a well-known strategy for scaling MySQL. However, it comes at a high cost: complex joins, extra application logic, weaker transaction support, complicated backup and restore strategies, and migration pain when shard boundaries shift.
Sharding can make sense once you’ve exhausted other scale levers. However, many teams implement it prematurely, spending months managing unnecessary complexity.
Before reaching for sharding, here are strategies to scale MySQL that preserve your schema and avoid data fragmentation:
- Read replicas offload read traffic with minimal app changes. Unlike sharding, they preserve complete query flexibility. But at scale, they can become expensive, introduce replica lag, and strain connection pools under load.
- Materialized views precompute the results of expensive joins or aggregations. In systems that support them, materialized views can eliminate the need for app-side denormalization and brittle cross-shard logic. However, unless they're incrementally maintained, they can be costly to refresh due to locks and difficult to operate at scale.
- Vertical scaling (increasing CPU, RAM, or IOPS) buys time without requiring an app rewrite. However, it doesn’t eliminate redundant query execution or planner overhead, and performance gains diminish once the working set fits in memory.
- SQL-aware database proxies, such as ProxySQL, support more innovative query routing and load balancing. They reduce connection churn without the complexity of shard-aware clients, but they don’t natively cache or precompute results.
- Readyset incrementally caches the results of expensive read queries and keeps them fresh automatically. It runs as a drop-in proxy with no schema changes, avoids manual invalidation logic, and preserves standard SQL semantics for supported workloads.
Each of these approaches targets a specific scaling bottleneck without forcing you to shard your data or abandon SQL. For many teams, they offer a faster, safer path to scale than sharding.
🔍 What We’re Watching in the Database Ecosystem
Building a Master-Slave Postgres Database with RisingWave: A Step-by-Step Guide A hands-on guide on how to utilize Change Data Capture (CDC) and RisingWave to offload reads from a write-intensive Postgres database. It streams changes into a real-time analytics layer, utilizing Docker and a Streamlit dashboard to demonstrate the setup. The architecture avoids traditional replication and requires no changes to application logic. This approach highlights the growing interest in streaming-based replicas as lightweight, flexible alternatives for scaling read workloads.
Announcing PlanetScale for Postgres PlanetScale now supports PostgreSQL, offering a fully managed service built on local NVMe storage, automatic failovers via Raft consensus, and connection pooling through their multi-tenant proxy layer. While Postgres v17 isn’t out yet, PlanetScale plans to support zero-downtime upgrades to major versions as they become available.
Unified Memory Management An interesting write-up by Justin Jaffray explores the shift towards unified memory management in databases, where a single buffer pool dynamically handles both disk caching and query memory. Systems like DuckDB adopt this model to improve resource efficiency, multitenancy, and adaptability, thereby reducing the need for manual memory tuning in cloud-native environments.
In Case You Missed It
When Query Optimization Isn’t Enough: Solving MySQL Overload with Caching Last week, we published a post analyzing why even optimized queries can overwhelm a MySQL database. In our benchmark, high-frequency reads stressed CPU resources, despite a fully warmed cache. Readyset absorbed the load, reducing latency by 99% and cutting CPU usage by 38%. When tuning falls short, caching fills the gap. See the full post for perf stat output and detailed results.
Get Readyset Weekly in your inbox
One email a week — what shipped, what we learned, and what is worth reading.