Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Mongoid extension that enables infinite scrolling with MongoDB.
Tag: v0.1.0

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.

Mongoid::Scroll Build Status

Mongoid extension that enable infinite scrolling.

The Problem

Traditional pagination does not work when data changes between paginated requests, which makes it unsuitable for infinite scroll behaviors.

  • If a record is inserted before the current page limit, the collection will shift to the right, and the returned result will include a duplicate from a previous page.
  • If a record is removed before the current page limit, the collection will shift to the left, and the returned result will be missing a record.

The solution implemented by the scroll extension paginates data using a cursor, giving you the ability to restart pagination where you left it off. This is a non-trivial problem when combined with sorting over non-unique record fields, such as timestamps.


Add mongoid-scroll to Gemfile.

gem 'mongoid-scroll'

A sample model.

module Feed
  class Item
    include Mongoid::Document
    field :content, type: String
    field :created_at, type: DateTime

Scroll and save a cursor to the last item.

saved_cursor = nil
Feed::Item.desc(:created_at).limit(5).scroll do |record, next_cursor|
  # each record, one-by-one
  saved_cursor = next_cursor

Resume iterating using the previously saved cursor.

Feed::Item.desc(:created_at).limit(5).scroll(saved_cursor) do |record, next_cursor|
  # each record, one-by-one
  saved_cursor = next_cursor

The iteration finishes when no more records are available. You can also finish iterating over the remaining records by omitting the query limit.

Feed::Item.desc(:created_at).scroll(saved_cursor) do |record, next_cursor|
  # each record, one-by-one


You can use Mongoid::Scroll::Cursor.from_record to generate a cursor. This can be useful when you just want to return a collection of results and the cursor pointing to after the last item.

record = Feed::Item.desc(:created_at).limit(3).last
cursor = Mongoid::Scroll::Cursor.from_record(record, { field: Feed::Item.fields["created_at"] })
# cursor or cursor.to_s can be returned to a client and passed into .scroll(cursor)

Note that unlike MongoDB cursors, Mongoid::Scroll::Cursor values don't expire.


Fork the project. Make your feature addition or bug fix with tests. Send a pull request. Bonus points for topic branches.

Copyright and License

MIT License, see LICENSE for details.

(c) 2013 Daniel Doubrovkine, based on code by Frank Macreery, Artsy Inc.

Something went wrong with that request. Please try again.