{"id":1755,"date":"2014-12-16T18:49:28","date_gmt":"2014-12-16T18:49:27","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=1755"},"modified":"2025-06-13T23:51:53","modified_gmt":"2025-06-14T06:51:53","slug":"pagination-couchbase","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/","title":{"rendered":"Pagination Best Practices with Couchbase"},"content":{"rendered":"<p style=\"margin-bottom: 0px;font-family: ff-kievit-web, 'MS UI Gothic', 'MS PGothic', Osaka, Batang, Georgia, 'Times New Roman', Times, sans-serif;font-size: 16px\"><em style=\"line-height: 23px;font-size: 1em;font-family: ff-meta-serif-web-pro-1, ff-meta-serif-web-pro-2, Georgia, 'Times New Roman', Times, serif\">[This blog was syndicated from https:\/\/blog.grallandco.com]<\/em><\/p>\n<div><\/div>\n<p>If you have to deal with a large number of documents when doing queries against a Couchbase cluster it is important to use pagination to get rows by page. You can find some information in the documentation in the chapter &#8220;<a href=\"https:\/\/docs.couchbase.com\/couchbase-manual-2.2\/#pagination\" target=\"_blank\" rel=\"noopener\">Pagination<\/a>&#8220;, but I want to go in more details and sample code in this article.<br \/>\n<span style=\"font-family: inherit;font-size: 1em;line-height: 1.4375em\">For this pagination example I will start by creating a simple view based on the <\/span><span style=\"font-size: 1em;line-height: 1.4375em;font-family: 'Courier New', Courier, monospace\">beer-sample<\/span><span style=\"font-family: inherit;font-size: 1em;line-height: 1.4375em\"> dataset, the view is used to find brewery by country:<\/span><\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">function (doc, meta) {<br \/>\nif (doc.type == &#8220;brewery&#8221; &amp;&amp; doc.country){<br \/>\nemit(doc.country);<br \/>\n}<br \/>\n}<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>This view list all the breweries by country, the index looks like:<\/p>\n<div class=\"responsive-table\">\n<table>\n<tbody>\n<tr>\n<th>Doc id<\/th>\n<th>Key<\/th>\n<th>Value<\/th>\n<\/tr>\n<tr>\n<td>bersaglier<\/td>\n<td>Argentina<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>cervecera_jerome<\/td>\n<td>Argentina<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>brouwerij_nacional_balashi<\/td>\n<td>Aruba<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>australian_brewing_corporation<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>carlton_and_united_breweries<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>coopers_brewery<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>foster_s_australia_ltd<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>gold_coast_brewery<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>lion_nathan_australia_hunter_street<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>little_creatures_brewery<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>malt_shovel_brewery<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>matilda_bay_brewing<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<\/tr>\n<tr>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<\/tr>\n<tr>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<\/tr>\n<tr>\n<td>yellowstone_valley_brewing<\/td>\n<td>United States<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>yuengling_son_brewing<\/td>\n<td>United States<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>zea_rotisserie_and_brewery<\/td>\n<td>United States<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>fosters_tien_gang<\/td>\n<td>Viet Nam<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>hue_brewery<\/td>\n<td>Viet Nam<\/td>\n<td>null<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p><span style=\"font-family: inherit;font-size: 1em;line-height: 1.4375em\">So now you want to navigate in this index with a page size of 5 rows.<\/span><\/p>\n<h3>Using skip \/ limit Parameters<\/h3>\n<p>The most simplistic approach is to use <span style=\"font-family: Courier New, Courier, monospace\">limit<\/span> and <span style=\"font-family: Courier New, Courier, monospace\">skip<\/span> parameters for example:<\/p>\n<p>Page 1 : \u00a0<span style=\"font-family: Courier New, Courier, monospace\">?limit=5&amp;skip0<\/span><br \/>\nPage 2: \u00a0 <span style=\"font-family: Courier New, Courier, monospace\">?limit=5&amp;skip=5<\/span><br \/>\n&#8230;<br \/>\nPage x: \u00a0 <span style=\"font-family: Courier New, Courier, monospace\">?limit=5&amp;skip(limit*(page-1))<\/span><\/p>\n<p>You can obviously use any other parameters you need to do range or key queries (<span style=\"font-family: Courier New, Courier, monospace\">startkey\/endkey, key, keys<\/span>) and sort option (<span style=\"font-family: Courier New, Courier, monospace\">descending<\/span>).<\/p>\n<p>This is simple but not the most efficient way, since the query engine has to read all the rows that match the query, until the skip value is reached.<\/p>\n<p>Some code sample in python that paginate using this view :<\/p>\n<p>This application loops on all the pages until the end of the index.<\/p>\n<p>As I said before this does not represent pagination best practices since the system must read all the values until the skip is reached. The following example shows a better way to deal with this.<\/p>\n<h3>Using startkey \/ startkey_docid parameters<\/h3>\n<div>To make this pagination more efficient it is possible to take another approach. This approach uses the <span style=\"font-family: Courier New, Courier, monospace\">startkey<\/span>\u00a0and <span style=\"font-family: Courier New, Courier, monospace\">startkey_docid<\/span> \u00a0to select the proper documents.<\/div>\n<div>\n<ul>\n<li>The <span style=\"font-family: Courier New, Courier, monospace\">startkey<\/span> parameter will be the value of the key where the query should start to read (based on the last key of the &#8220;previous page&#8221;<\/li>\n<li>Since for a key for example &#8220;Germany&#8221; you may have one or more ids (documents) it is necessary to say to Couchbase query engine where to start, for this you need to use the\u00a0<span style=\"font-family: 'Courier New', Courier, monospace\">startkey_docid\u00a0<\/span>parameter, and ignore this id since it is the last one of the previous page.<\/li>\n<\/ul>\n<\/div>\n<div><\/div>\n<div>So if we look at the index, and add a row number to explain the pagination<\/div>\n<div>\n<div class=\"responsive-table\">\n<table>\n<tbody>\n<tr>\n<th>Row num<\/th>\n<th>Doc id<\/th>\n<th>Key<\/th>\n<th>Value<\/th>\n<\/tr>\n<tr>\n<td colspan=\"4\">Query for page 1 : <span style=\"font-family: Courier New, Courier, monospace\">?limit=5<\/span><\/td>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>bersaglier<\/td>\n<td>Argentina<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>cervecera_jerome<\/td>\n<td>Argentina<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td>brouwerij_nacional_balashi<\/td>\n<td>Aruba<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td>australian_brewing_corporation<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td>carlton_and_united_breweries<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td colspan=\"4\">Query for page 2: <span style=\"font-family: Courier New, Courier, monospace\">?limit=5&amp;startkey=&#8221;Australia&#8221;&amp;startkey_docid=carlton_and_united_breweries&amp;skip=1<\/span><\/td>\n<\/tr>\n<tr>\n<td>6<\/td>\n<td>coopers_brewery<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>7<\/td>\n<td>foster_s_australia_ltd<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>8<\/td>\n<td>gold_coast_brewery<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>9<\/td>\n<td>lion_nathan_australia_hunter_street<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>10<\/td>\n<td>little_creatures_brewery<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td colspan=\"4\">Query for page 3 : <span style=\"font-family: Courier New, Courier, monospace\">limit=5&amp;startkey=&#8221;Australia&#8221;&amp;startkey_docid=little_creatures_brewery<\/span><span style=\"font-family: 'Courier New', Courier, monospace\">&amp;skip=1<\/span><\/td>\n<\/tr>\n<tr>\n<td>11<\/td>\n<td>malt_shovel_brewery<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>12<\/td>\n<td>matilda_bay_brewing<\/td>\n<td>Australia<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<\/tr>\n<tr>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<\/tr>\n<tr>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<\/tr>\n<tr>\n<td>&#8230;<\/td>\n<td>yellowstone_valley_brewing<\/td>\n<td>United States<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>&#8230;<\/td>\n<td>yuengling_son_brewing<\/td>\n<td>United States<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>&#8230;<\/td>\n<td>zea_rotisserie_and_brewery<\/td>\n<td>United States<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>&#8230;<\/td>\n<td>fosters_tien_gang<\/td>\n<td>Viet Nam<\/td>\n<td>null<\/td>\n<\/tr>\n<tr>\n<td>&#8230;<\/td>\n<td>hue_brewery<\/td>\n<td>Viet Nam<\/td>\n<td>null<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>So as you can see in the examples above, the query uses the startkey, a document id, and just passes it using skip=1.<\/p>\n<p>Let&#8217;s now look at the application code, once again in Python<\/p>\n<\/div>\n<p>&nbsp;<\/p>\n<div>This application loops on all the pages until the end of the index<\/div>\n<div>Using this approach, the application start to read the index at a specific key (<span style=\"font-family: Courier New, Courier, monospace\">startkey<\/span>\u00a0parameter), and only loop on the necessary entry in the index. This is more efficient than using the simple skip approach.<\/div>\n<p>&nbsp;<\/p>\n<h4>Views with Reduce function<\/h4>\n<div>When your view is using a reduce function, if you want to paginate on the various keys only (with the reduce function) you need to\u00a0<span style=\"line-height: 1\">use the\u00a0<\/span><span style=\"line-height: 1;font-family: 'Courier New', Courier, monospace\">skip<\/span><span style=\"line-height: 1\">\u00a0and\u00a0<\/span><span style=\"line-height: 1;font-family: 'Courier New', Courier, monospace\">limit<\/span><span style=\"line-height: 1\">\u00a0parameters.<\/span><\/div>\n<div><\/div>\n<div>When you are using the\u00a0<span style=\"line-height: 1\">\u00a0paramater <\/span><span style=\"line-height: 1;font-family: 'Courier New', Courier, monospace\">startkey_docid<\/span><span style=\"line-height: 1\">\u00a0with a reduce function it will calculate the reduce only to the subset of document ids that are part of your query.<\/span><\/div>\n<h3>Couchbase Java SDK Paginator<\/h3>\n<div>\n<p>In the previous examples, I have showed how to do pagination using the various query parameters. The Java SDK provides a Paginator object to help developers to deal with pagination. The following example is using the same view with the Paginator API.<\/p>\n<p>So as you can see you can easily paginate on the results of a Query using the Java Paginator.<\/p>\n<ul>\n<li>At the line #37, the Paginator is created from using the view and query objects and a page size is specified<\/li>\n<li>Then you just need to use the hasNext() and next() methods to navigate in the results.<\/li>\n<\/ul>\n<p>The Java Paginator \u00a0is aware of the fact that they query is using a reduce or not, so you can use it with all type of queries &#8211; Internally it will switch between the skip\/limit approach and the doc_id approaches. You can <a href=\"https:\/\/github.com\/couchbase\/couchbase-java-client\/blob\/1.1.9\/src\/main\/java\/com\/couchbase\/client\/protocol\/views\/Paginator.java#L176-L195\" target=\"_blank\" rel=\"noopener\">see how it is done in the Paginator class<\/a>.<\/p>\n<p>Note that if you want to do that in a Web application between HTTP request you must keep the Paginator object in the user session since the current API keeps the current page in its state.<\/p>\n<h3>Conclusion<\/h3>\n<p>In this blog post you have \u00a0learned how to deal with pagination in Couchbase views; to summarize<\/p>\n<ul>\n<li>The pagination is based on some specific parameters that you send when executing a query.<\/li>\n<li>Java developers can use the Paginator class that simplifies pagination.<\/li>\n<\/ul>\n<div>I am inviting you to look at the new Couchbase Query Language N1QL, still under development, that will provide more pagination options to developers, using LIMIT &amp; OFFSET parameters, for example:<\/div>\n<div><\/div>\n<div>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">SELECT fname, age<br \/>\nFROM tutorial<br \/>\nWHERE age &gt; 30<br \/>\nLIMIT 2<br \/>\nOFFSET 2<\/div>\n<\/div>\n<div>\n<p>If you want to learn more about N1QL:<\/p>\n<ul>\n<li><a href=\"https:\/\/query.couchbase.com\/\">N1QL on Couchbase Community Portal<\/a><\/li>\n<li><a href=\"https:\/\/query.pub.couchbase.com\/tutorial\/\" target=\"_blank\" rel=\"noopener\">N1QL Online Tutorial<\/a><\/li>\n<\/ul>\n<\/div>\n<div><\/div>\n<div><span style=\"font-size: 10px\"><em>PS: Edited on Oct 8th to clarify the Pagination with Reduce function<\/em><\/span><\/div>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>[This blog was syndicated from https:\/\/blog.grallandco.com] If you have to deal with a large number of documents when doing queries against a Couchbase cluster it is important to use pagination to get rows by page. You can find some information [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1812],"tags":[1241],"ppma_author":[8968],"class_list":["post-1755","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-n1ql-query","tag-views"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Pagination Best Practices: Options &amp; Examples | Couchbase<\/title>\n<meta name=\"description\" content=\"Many documents when doing queries against a Couchbase cluster requires pagination to get rows by page. We provide best practices with sample codes.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Pagination Best Practices with Couchbase\" \/>\n<meta property=\"og:description\" content=\"Many documents when doing queries against a Couchbase cluster requires pagination to get rows by page. We provide best practices with sample codes.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-12-16T18:49:27+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T06:51:53+00:00\" \/>\n<meta name=\"author\" content=\"The Couchbase Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"The Couchbase Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/\"},\"author\":{\"name\":\"The Couchbase Team\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/764f4a6771ee19bc7af70b70a326fb93\"},\"headline\":\"Pagination Best Practices with Couchbase\",\"datePublished\":\"2014-12-16T18:49:27+00:00\",\"dateModified\":\"2025-06-14T06:51:53+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/\"},\"wordCount\":1085,\"commentCount\":4,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"views\"],\"articleSection\":[\"SQL++ \/ N1QL Query\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/\",\"name\":\"Pagination Best Practices: Options & Examples | Couchbase\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2014-12-16T18:49:27+00:00\",\"dateModified\":\"2025-06-14T06:51:53+00:00\",\"description\":\"Many documents when doing queries against a Couchbase cluster requires pagination to get rows by page. We provide best practices with sample codes.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Pagination Best Practices with Couchbase\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/764f4a6771ee19bc7af70b70a326fb93\",\"name\":\"The Couchbase Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/7befc37d02226b59499817eafdec60c3\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/b4c18c758421903398e84d6c9560f319f39c665798d7d23e6a6f9dff8a8f984e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/b4c18c758421903398e84d6c9560f319f39c665798d7d23e6a6f9dff8a8f984e?s=96&d=mm&r=g\",\"caption\":\"The Couchbase Team\"},\"description\":\"Jennifer Garcia is a Senior Web Manager at Couchbase Inc. As the website manager, Jennifer has overall responsibility for the website properties including design, implementation, content, and performance.\",\"sameAs\":[\"https:\/\/www.couchbase.com\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/jennifer-garcia\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Pagination Best Practices: Options & Examples | Couchbase","description":"Many documents when doing queries against a Couchbase cluster requires pagination to get rows by page. We provide best practices with sample codes.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/","og_locale":"en_US","og_type":"article","og_title":"Pagination Best Practices with Couchbase","og_description":"Many documents when doing queries against a Couchbase cluster requires pagination to get rows by page. We provide best practices with sample codes.","og_url":"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/","og_site_name":"The Couchbase Blog","article_published_time":"2014-12-16T18:49:27+00:00","article_modified_time":"2025-06-14T06:51:53+00:00","author":"The Couchbase Team","twitter_card":"summary_large_image","twitter_misc":{"Written by":"The Couchbase Team","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/"},"author":{"name":"The Couchbase Team","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/764f4a6771ee19bc7af70b70a326fb93"},"headline":"Pagination Best Practices with Couchbase","datePublished":"2014-12-16T18:49:27+00:00","dateModified":"2025-06-14T06:51:53+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/"},"wordCount":1085,"commentCount":4,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["views"],"articleSection":["SQL++ \/ N1QL Query"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/","url":"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/","name":"Pagination Best Practices: Options & Examples | Couchbase","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2014-12-16T18:49:27+00:00","dateModified":"2025-06-14T06:51:53+00:00","description":"Many documents when doing queries against a Couchbase cluster requires pagination to get rows by page. We provide best practices with sample codes.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/pagination-couchbase\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Pagination Best Practices with Couchbase"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/764f4a6771ee19bc7af70b70a326fb93","name":"The Couchbase Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/7befc37d02226b59499817eafdec60c3","url":"https:\/\/secure.gravatar.com\/avatar\/b4c18c758421903398e84d6c9560f319f39c665798d7d23e6a6f9dff8a8f984e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b4c18c758421903398e84d6c9560f319f39c665798d7d23e6a6f9dff8a8f984e?s=96&d=mm&r=g","caption":"The Couchbase Team"},"description":"Jennifer Garcia is a Senior Web Manager at Couchbase Inc. As the website manager, Jennifer has overall responsibility for the website properties including design, implementation, content, and performance.","sameAs":["https:\/\/www.couchbase.com"],"url":"https:\/\/www.couchbase.com\/blog\/author\/jennifer-garcia\/"}]}},"authors":[{"term_id":8968,"user_id":2,"is_guest":0,"slug":"jennifer-garcia","display_name":"The Couchbase Team","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/b4c18c758421903398e84d6c9560f319f39c665798d7d23e6a6f9dff8a8f984e?s=96&d=mm&r=g","author_category":"","last_name":"Garcia","first_name":"Jennifer","job_title":"","user_url":"https:\/\/www.couchbase.com","description":"Jennifer Garcia is a Senior Web Manager at Couchbase Inc. As the website manager, Jennifer has overall responsibility for the website properties including design, implementation, content, and performance."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1755","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=1755"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1755\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=1755"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=1755"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=1755"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=1755"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}