SYSTEM Cited by 1 source
fast_page gem¶
What it is¶
fast_page is a
PlanetScale-authored Ruby gem that applies the MySQL
deferred-join optimisation to
ActiveRecord::Relation objects via a single .fast_page
method:
Post.all.order(created_at: :desc).limit(25).offset(100)
# Post Load (1228.7ms) — slow baseline
Post.all.order(created_at: :desc).limit(25).offset(100).fast_page
# Post Pluck (456.9ms) + Post Load (0.4ms) — 2.7× faster
Introduced in Mike Coutermarsh's 2022-08-16 PlanetScale blog
post, the gem is a direct Ruby port of Caleb Porzio / Aaron
Francis's Laravel equivalent,
hammerstonedev/fast-paginate
(also 2022). Both gems are packaged implementations of the
deferred-join technique documented
in High Performance MySQL.
(Source: sources/2026-04-21-planetscale-introducing-fastpage-faster-offset-pagination-for-rails-apps.)
What it does¶
Mechanically, .fast_page rewrites a
.order(…).limit(N).offset(M) chain into two SQL queries:
- Index-only primary-key pluck:
SELECT id FROM t ORDER BY … LIMIT N OFFSET M. - Hydrate by primary key:
SELECT * FROM t WHERE id IN (…) ORDER BY ….
The database does M + N index-only leaf walks and only
N clustered-index descents —
instead of M + N clustered-index descents in the
baseline. For wide SELECT * at deep offsets this collapses
the dominant cost.
Scope and non-scope¶
Scope — what the gem is:
- A narrow query-rewriter for
ActiveRecord::Relation objects using
offset / limit.
- A bridge to the
deferred-
join-for-offset-pagination pattern that doesn't require
developers to hand-write the SQL.
- An application-tier library — runs in the Rails client
process, not in the database or proxy.
Non-scope — what the gem isn't:
- Not part of the PlanetScale database product; works
against any MySQL instance (RDS, Aurora, self-hosted,
PlanetScale).
- Not a cursor-pagination
implementation. It preserves offset semantics (you can
still GOTO PAGE 47); cursor pagination is the
separately-named alternative for next/previous-only UX.
- Not a planner hint or SQL extension. Pure Ruby-level
query rewriting.
Operational guidance (from the post)¶
- Apply conditionally past page N. The gem runs two queries instead of one, so it's slower for shallow pages. Canonical usage: See patterns/conditional-optimization-by-page-depth.
- Benchmark on your own data. Coutermarsh's
> 5is a starting heuristic; the correct crossover depends on row width, network RTT, and data distribution. - Requires
ORDER BY. Without one, the first query has no index to prefer and the optimisation's premise collapses. - Benefits scale with page depth. For shallow apps (OFFSET always < 100) the wins are modest; for deep pagination (OFFSET > 10k) the wins are dramatic.
Place in PlanetScale's Ruby ecosystem¶
fast_page is one of several PlanetScale-authored Ruby
gems surfacing in wiki sources:
planetscale_rails— Rails migration runner that bridges ActiveRecord migrations to PlanetScale's deploy-request lifecycle.activerecord- sql_commenter— swaps Rails-default query-log tag format for Google's SQLCommenter.fast_page(this page) — rewrites offset-pagination queries to use a deferred join.
All three are application-tier tooling written by PlanetScale's Rails team against their internal Rails monolith, not database-product components. They canonicalise a pattern the wiki sees often in PlanetScale sources: the company's Rails engineers packaging internal operational fixes as open-source gems.
Scope the source does not cover¶
- Gem internals — the post shows the user-facing API
but not the implementation (how
.fast_pageis attached toActiveRecord::Relation, which ActiveRecord versions are supported, whether it handles edge cases likeincludes/joins/selectchains). - Cross-database support — the post benchmarks on MySQL
only. The deferred-join technique works on PostgreSQL
too, but it's unclear whether
fast_pageproduces Postgres-compatible SQL out of the box (the gem name and blog framing are MySQL-specific). - Performance at extreme offsets (OFFSET > 100k) — benchmark stops at ~2000 pages × 100 per page = ~200k.
- Production-deployment experience at PlanetScale — no
disclosure of which PlanetScale application queries
adopted
.fast_page, what crossover threshold they settled on, or incident counts before / after. - Interaction with Vitess — PlanetScale's own product
uses Vitess as the MySQL proxy; whether
fast_page's two-query pattern interacts with VTGate's query planner, buffering, or cross-shard execution is not discussed (the Rails app in the post connects directly to MySQL, not to a VTGate).
Seen in¶
- sources/2026-04-21-planetscale-introducing-fastpage-faster-offset-pagination-for-rails-apps — canonical wiki source. Mike Coutermarsh's introduction of the gem. 2.7× benchmark at offset 100 on a 1M-row table; 2000-page sweep chart; explicit cross-ecosystem credit to Hammerstone's Laravel port and Aaron Francis's blog post Efficient Pagination Using Deferred Joins. Author's byline: Mike Coutermarsh, PlanetScale Rails-team engineer — his fourth wiki ingest after 2022-01-18 (Rails CI), 2022-02-17 (self-healing Sidekiq), 2022-06-29 (SQLCommenter in Rails), and 2024-04-04 (PlanetScale schema changes).
Related¶
- systems/planetscale
- systems/ruby-on-rails
- systems/mysql
- systems/innodb
- systems/planetscale-rails-gem
- concepts/deferred-join
- concepts/offset-pagination-cost
- concepts/cursor-pagination
- concepts/secondary-index
- concepts/clustered-index
- concepts/composite-index
- patterns/deferred-join-for-offset-pagination
- patterns/conditional-optimization-by-page-depth
- companies/planetscale