Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
G

geared_pagination

> 编程语言
Open source

Paginate Active Record sets at variable speeds

912 stars0 likes2 views
WebsiteGitHub

About

Paginate Active Record sets at variable speeds

Geared Pagination

Most pagination schemes use a fixed page size. Page 1 returns as many elements as page 2. But that's frequently not the most sensible way to page through a large recordset when you care about serving the initial request as quickly as possible. This is particularly the case when using the pagination scheme in combination with an infinite scrolling UI.

Geared Pagination allows you to define different ratios. By default, we will return 15 elements on page 1, 30 on page 2, 50 on page 3, and 100 from page 4 and forward. This has proven to be a very sensible set of ratios for much of the Basecamp UIs. But you can of course tweak the ratios, use fewer, or even none at all, if a certain page calls for a fixed-rate scheme.

On JSON actions that set a page, we'll also automatically set Link and X-Total-Count headers for APIs to be able to page through a recordset.

Example

ruby
class MessagesController  of  ( total messages):

  No more pages!

  

Cursor-based pagination

By default, Geared Pagination uses offset-based pagination: the page query parameter contains the page number. Each page’s records are located using a query with an OFFSET clause, like so:

sql
SELECT *
FROM messages
ORDER BY created_at DESC
LIMIT 30
OFFSET 15

You may prefer to use cursor-based pagination instead. In cursor-based pagination, the page parameter contains a “cursor” describing the last row of the previous page. Each page’s records are located using a query with conditions that only match records after the previous page. For example, if the last record on the previous page had a created_at value of 2019-01-24T12:35:26.381Z and an ID of 7354857, the current page’s records would be found with a query like this one:

sql
SELECT *
FROM messages
WHERE (created_at = '2019-01-24T12:35:26.381Z' AND id 

Cursors encode the information Geared Pagination needs to query for the corresponding page’s records: the page number for choosing a page size, and the values of each of the ordered attributes (created_at and id).

When should I use cursor-based pagination?

Cursor-based pagination can outperform offset-based pagination when paginating deeply into a large number of records. DBs commonly execute queries with OFFSET clauses by counting past OFFSET records one at a time, so each page in offset-based pagination takes slightly longer to load than the last. With cursor-based pagination and an appropriate index, the DB can jump directly to the beginning of each page without scanning.

The tradeoff is that Geared Pagination only supports cursor-based pagination on simple relations with simple, column-only orders. Cursor-based pagination also won’t perform better than offset-based pagination without an ordered index. Stick with offset-based pagination if:

  • You need complex ordering on a complex relation
  • You’re paginating a small and/or bounded number of records

Caching

To account for the current page in fragment caches, include the @page directly. That includes the current page number and gear ratios.

Fragment caching a message's comments:

ruby

  

NOTE: The page does not include cache keys for all the records. That would require loading all the records, defeating the purpose of using the cache. Use a parent record, like a message that's touched when new comments are posted, as the cache key instead.

ETags

When a controller action sets an ETag and uses geared pagination, the current page and gear ratios are automatically included in the ETag.

License

Geared Pagination is released under the MIT License.

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Ruby

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言