How to scale your Strapi data layer using a wire compatible caching proxy and what the results look like on 43,000 real restaurants.
Strapi is an excellent tool for building content driven applications quickly. As a project grows and data becomes more interconnected, keeping the API layer snappy is a common goal for development teams. When you have deeply nested relations like a restaurant linked to locations, menus, and reviews, the database workload naturally increases.
This is a typical stage in the lifecycle of a successful application. Rather than viewing performance bottlenecks as a flaw, they are better seen as an opportunity for architectural optimization. By using a caching proxy, you can make hot queries 10 to 19 times faster at the SQL layer with a one line environment variable change.
What is Strapi
For those new to the ecosystem: Strapi is an open source headless CMS written in Node.js. It allows you to define content types in an admin UI and then auto generates REST and GraphQL APIs for you. Under the hood, it is a Koa app backed by knex. It usually runs on Postgres, MySQL, or SQLite in production, issuing standard SQL just like any other web application.
To test this at scale, we used the official FoodAdvisor example app. This app features nested relations between restaurants, categories, and reviews, making it a perfect candidate for performance testing.
Growing with Strapi
The Strapi architecture is flexible, but like any ORM based system, it can face challenges with complex data. As noted in the official documentation, using broad population can lead to many database queries. Specifically, the ORM can generate one SQL query per relation per row. A single request for a restaurant list might issue 150 or more queries to hydrate all the related fields.
Since Strapi does not have a built in database query cache, teams often look for external solutions. Common approaches include rewriting queries or manually managing Redis, but these add significant code complexity. We wanted a solution that improves performance without adding a heavy maintenance burden.
How Readyset Helps
Readyset is a wire compatible caching proxy for Postgres and MySQL. It sits between Strapi and your database. It uses logical replication to materialize the results of queries and keeps them fresh incrementally as writes stream in.
The integration is a zero code change. Strapi continues to speak Postgres; it just speaks it to Readyset instead of directly to the database. The setup is two lines in your configuration:
|
1 2 |
DATABASE_HOST=readyset # was: postgres DATABASE_PORT=5433 # was: 5432 |
Why this approach works:
- Automatic Invalidation: Readyset monitors the database replication stream.
- Instant Refresh: When you edit content, the cache updates instantly without writing TTL logic.
- SQL Level Caching: It caches by SQL structure (shape), not just the URL.
- Safe Fallbacks: Writes, DDL, and transactions go straight to the main database automatically.
The Benchmark
We built a test stack with Postgres and Strapi, seeded with real data for 43,320 restaurants. We tested the specific queries that Strapi emits for a restaurant list page, which you can view in our benchmark script.
| Query Type | Postgres | Readyset | Speedup |
| Pagination Count | 3.5 ms | 0.33 ms | 10x |
| Sorted List Page | 8.6 ms | 0.45 ms | 19x |
| Place Aggregation | 3.3 ms | 0.33 ms | 10x |
Honest Caveats:
- Point Lookups: Simple queries by ID are already very fast on Postgres (~0.3 ms) and do not see a massive boost.
- Application Overhead: While the database layer becomes sub millisecond, the Strapi Node.js layer still handles JSON assembly and authentication. Overall HTTP response times typically see a 2 times improvement.
Try It Yourself
The full demo is open source and reproducible on any machine with Docker.
|
1 2 3 |
git clone https://github.com/vgrippa/mydemos cd mydemos/readyset-strapi-foodadvisor ./demo.sh |
The script sets up the stack, loads the data, and prints the performance table to your terminal.
How to Reach Out
- Book a demo: readyset.io/book-a-demo
- GitHub: Check out the main Readyset project and our demo repo.
If you are scaling a Strapi project, we would love to hear from you. We want to build these tools in the open with real feedback from the community.
The floor is yours.
0 comments · Moderated · civil & on-topicFirst comment appears here once approved. Questions, corrections, and counterpoints welcome — just no self-promotion.