Optimizing MySQL and PostgreSQL performance is crucial for modern applications, especially those with read-heavy workloads. Readyset is a drop-in SQL caching engine that sits between your application and the database. It automatically caches query results to improve response times without requiring application changes. In this post, we'll cover: Installing Readyset on Ubuntu 24.04 using a .deb package Configuring Readyset to connect to an upstream MySQL database Running queries and caching r

Wagner Bianchi
2025-03-05 · 4 min read
Optimizing MySQL and PostgreSQL performance is crucial for modern applications, especially those with read-heavy workloads. Readyset is a drop-in SQL caching engine that sits between your application and the database. It automatically caches query results to improve response times without requiring application changes.
In this post, we'll cover:
Installing Readyset on Ubuntu 24.04 using a .deb package
Configuring Readyset to connect to an upstream MySQL database
Running queries and caching results using MySQL's employee's sample database
Managing cached queries to optimize performance
Before installing Readyset, ensure you have a running MySQL or PostgreSQL database. Readyset requires access to the database to snapshot the schema and cache queries.
Readyset should be installed on a separate host from the database to avoid resource contention.
3The database server should allow Readyset to connect remotely.
For this tutorial, we assume:
CREATE USER IF NOT EXISTS `readyset`@`10.0.0.%`
IDENTIFIED WITH caching_sha2_password BY '<password>';
GRANT SELECT, INSERT, UPDATE, DELETE, LOCK TABLES
ON employees.*
TO `readyset`@`10.0.0.%`;
GRANT BACKUP_ADMIN, REPLICATION CLIENT, REPLICATION SLAVE
ON *.* TO `readyset`@`10.0.0.%`;
If you haven't already set up the employees sample database, you can download it here and import it into MySQL.
wget https://github.com/readysettech/readyset/releases/download/stable-250123/readyset_1.11.0-1_amd64.deb
dpkg -i readyset_1.11.0-1_amd64.deb
After installation, you should see:
Selecting previously unselected package readyset.
(Reading database ... 168043 files and directories currently installed.)
Preparing to unpack readyset_1.11.0-1_amd64.deb ...
Unpacking readyset (1.11.0-1) ...
Setting up readyset (1.11.0-1) ...
Created symlink /etc/systemd/system/multi-user.target.wants/readyset.service → /usr/lib/systemd/system/readyset.service.
Before starting Readyset, you must configure its connection settings in /etc/readyset/readyset.conf.
vim /etc/readyset/readyset.conf
Modify or add the following lines:
UPSTREAM_DB_URL="mysql://readyset:<password>@10.0.0.11:3306/employees"
LISTEN_ADDRESS="0.0.0.0:3307"
systemctl start readyset
To check if it's running:
systemctl status readyset
Once Readyset is running, connect using the MySQL client:
mysql -h 10.0.0.12 -P 3307 -u readyset -p
Since Readyset acts as a proxy, queries sent here will be cached automatically. For connecting to Readyset, I am assuming you have already created the below user on MySQL:
Run a real-world query using MySQL's employees database:
SELECT b.dept_name
, c.first_name
, c.last_name
, c.gender, c.hire_date
FROM dept_emp a, departments b, employees c
WHERE ((a.dept_no=b.dept_no AND a.emp_no=c.emp_no)
AND (last_name='Pelz' AND first_name='Samphel'));
1 row in set (0.38 sec)
Since this is the first run, Readyset still doesn't have a cache for this query, causing it to be proxied straightaway to MySQL. You can verify it using EXPLAIN LAST STATEMENT:
MySQL processes it as usual.
To check if Readyset intercepted the query:
SHOW PROXIED QUERIES\G
Expected output:
*************************** 1. row ***************************
query id: q_497640df754b2626
proxied query: SELECT `b`.`dept_name`, `c`.`first_name`, `c`.`last_name`, `c`.`gender`, `c`.`hire_date`
FROM `dept_emp` AS `a`, `departments` AS `b`, `employees` AS `c`
WHERE (((`a`.`dept_no` = `b`.`dept_no`) AND (`a`.`emp_no` = `c`.`emp_no`))
AND ((`last_name` = $1) AND (`first_name` = $2)))
readyset supported: yes
count: 1
To explicitly cache this query:
CREATE CACHE ALWAYS my_query FROM q_497640df754b2626;
I named the cache I created "my_query." If you don't give it a name, a string like "q_497640df754b2626" will be created automatically to identify your cache uniquely.
Expected output:
Query OK, 0 rows affected (1.11 sec)
Check if the query is cached:
SHOW CACHES WHERE query_id="q_497640df754b2626"\G
Expected output:
*************************** 1. row ***************************
query id: q_497640df754b2626
cache name: my_query
query text: SELECT `b`.`dept_name`, `c`.`first_name`, `c`.`last_name`, `c`.`gender`, `c`.`hire_date`
FROM `dept_emp` AS `a`, `departments` AS `b`, `employees` AS `c`
WHERE (((`a`.`dept_no` = `b`.`dept_no`) AND (`a`.`emp_no` = `c`.`emp_no`))
AND ((`last_name` = $1) AND (`first_name` = $2)))
fallback behavior: no fallback
count: 0
At this point, Readyset is caching this query!
Rerun the query, but now using Readyset:
SELECT b.dept_name
, c.first_name
, c.last_name
, c.gender, c.hire_date
FROM dept_emp a, departments b, employees c
WHERE ((a.dept_no=b.dept_no AND a.emp_no=c.emp_no)
AND (last_name='Pelz' AND first_name='Samphel'));
1 row in set (0.00 sec)
Query execution time dropped to 0.00 sec! 🚀
Readyset served the result from the cache, avoiding a full database query. We can validate it once again using the EXPLAIN LAST STATEMENT. Observe below where the query was executed:
mysql> EXPLAIN LAST STATEMENT\G
*************************** 1. row ***************************
Query_destination: readyset
Readyset_error: ok
1 row in set (0.00 sec)
To remove the cache, run:
DROP CACHE my_query;
Verify that it's gone:
SHOW CACHES;
Expected output:
Empty set (0.01 sec)
Using Readyset, you can significantly improve MySQL query performance with minimal effort.
With Readyset running on a separate host, you reduce database server overhead while ensuring cached queries execute efficiently.
Modern applications demand instant performance, even under unpredictable load. Readyset helps you eliminate slow queries, stabilize latency, and scale confidently.
Revolutionize your database performance with Readyset
Serve requests at sub-millisecond latencies with the modern database scaling and query caching system for MySQL and PostgreSQL.
Join our newsletter
Stay updated with the latest news, insights, and developments from Readyset — straight to your inbox.