raw Math
RAW Math Combinatorics Counting Principles

The Mathematics of Pagination

Robert Eisele

Pagination is a problem about covering a finite sequence with consecutive intervals. Once the interval length and the shift between intervals are known, the familiar formulas for page counts, offsets, overlaps, and visible page links all follow from the same construction.

Let

The parameters are integers satisfying

\[ N\geq 0,\qquad P\geq 1,\qquad 0\leq \ell<P. \]

The strict inequality \(\ell<P\) matters. If every item on a page were repeated, the paginator would never advance. The number of new positions gained after the first page is therefore

\[ S=P-\ell, \]

where \(S\) is the step width.

Pages as Overlapping Intervals

Number pages from \(i=1\), but number items from zero as programming languages usually do. Page \(i\) begins after \(i-1\) steps, so its half-open interval is

\[ I_i=[A_i,B_i),\qquad A_i=(i-1)S,\qquad B_i=\min(A_i+P,N). \tag{1} \]

A half-open interval contains its left endpoint but not its right endpoint. Its length is simply \(B_i-A_i\). In one-based notation, the same page starts with item \(1+(i-1)S\) and ends with item \(\min((i-1)S+P,N)\).

page 1 page 2 page 3 item 123 45 456 78 789 1011 123 456 789 1011 ℓ = 2 ℓ = 2

Before truncation at \(N\), the right endpoint of page \(i\) is \((i-1)S+P\). The next page starts at \(iS\). Their intersection therefore has length

\[ ((i-1)S+P)-iS=P-S=\ell. \tag{2} \]

This proves directly that consecutive pages share exactly \(\ell\) items. It also proves that there are no gaps: because \(\ell\geq0\), the next interval begins no later than the previous interval ends.

Deriving the Number of Pages

The first page covers at most \(P\) items. Every additional page moves the right endpoint forward by \(S=P-\ell\). After \(K\) pages, the covered prefix can therefore contain

\[ P+(K-1)S \]

positions. The last page must reach item \(N\), hence

\[ \begin{aligned} P+(K-1)S &\geq N,\\ K-1 &\geq \frac{N-P}{S},\\ K &\geq 1+\frac{N-P}{P-\ell}. \end{aligned} \]

Since \(K\) is an integer and a nonempty sequence needs at least one page, the smallest valid value is

\[ \boxed{ K= \begin{cases} 0, & N=0,\\ 1+\left\lceil\dfrac{\max(0,N-P)}{P-\ell}\right\rceil, & N>0. \end{cases} } \tag{3} \]

The convention \(K=0\) for an empty sequence means that no empty placeholder page is counted. An interface that deliberately displays one empty page can replace that first case with \(K=1\).

Without overlap, \(\ell=0\) and \(S=P\). Equation (3) then reduces to the ordinary formula

\[ K=\left\lceil\frac{N}{P}\right\rceil. \]

At the opposite extreme, \(\ell=P-1\), each additional page contributes exactly one new item. Once the first page is full, every remaining item requires another page.

The Last Page

The last page has index \(K\) and starts at \((K-1)S\). For \(N>0\), its number of items is

\[ \boxed{R=N-(K-1)(P-\ell).} \tag{4} \]

The minimality of \(K\) guarantees \(1\leq R\leq P\). The final page may consist partly of the overlap carried from the previous page, but it always contains at least one item that was not reached by an earlier page.

A Worked Example

Suppose \(N=21\) items are displayed eight at a time with an overlap of three. The step width is

\[ S=P-\ell=8-3=5, \]

and Equation (3) gives

\[ K=1+\left\lceil\frac{21-8}{5}\right\rceil =1+3=4. \]

PageHalf-open sliceOne-based itemsCount
1\([0,8)\)1 through 88
2\([5,13)\)6 through 138
3\([10,18)\)11 through 188
4\([15,21)\)16 through 216

Every pair of neighboring pages shares three items, all 21 items are covered, and the last page contains \(R=21-3\cdot5=6\) items.

Deriving a Fixed-Width Paginator Window

The item ranges and the numbered links solve different problems. Suppose there are \(K\) pages, the current page is \(C\), and the interface may display at most \(W\) numbered links. The actual window width is

\[ U=\min(W,K). \]

Choose a preferred slot \(H\) for the current page within that window, with \(1\leq H\leq U\). Centering uses \(H=\lceil U/2\rceil\). If there were no boundaries, the first visible page would be \(C-H+1\). A real window must also satisfy

\[ 1\leq F\leq K-U+1. \]

Clamping the desired start to that interval gives

\[ \boxed{ F=\max\!\left(1,\min\!\left(C-H+1,K-U+1\right)\right), \qquad G=F+U-1. } \tag{5} \]

The paginator displays the inclusive range \(F,F+1,\ldots,G\). For \(K=20\), \(W=7\), and a centered slot \(H=4\), the window behaves as follows:

Current pageDesired startClamped window
2\(-1\)1 through 7
11\(8\)8 through 14
20\(17\)14 through 20

Near either boundary, clamping moves the whole window rather than shortening it. The current page stays visible, and exactly \(U\) numbered links are shown whenever pages exist.

Translating the Formulas into Code

The implementation can remain close to the notation. It returns the total page count, the half-open data slice for the current page, and the inclusive range of numbered links:

function paginate(itemCount, pageSize, overlapLength, currentPage, maxVisiblePages) {
  if (!Number.isInteger(itemCount) || itemCount < 0 ||
      !Number.isInteger(pageSize) || pageSize < 1 ||
      !Number.isInteger(overlapLength) || overlapLength < 0 || overlapLength >= pageSize) {
    throw new RangeError('Invalid pagination parameters');
  }

  if (itemCount === 0) {
    return { pageCount: 0, itemRange: [0, 0], pageRange: [0, 0] };
  }

  const stepSize = pageSize - overlapLength;
  const pageCount = 1 + Math.ceil(Math.max(0, itemCount - pageSize) / stepSize);
  const selectedPage = Math.max(1, Math.min(currentPage, pageCount));
  const firstItemIndex = (selectedPage - 1) * stepSize;
  const itemEndIndex = Math.min(firstItemIndex + pageSize, itemCount);

  const visiblePageCount = Math.min(Math.max(1, maxVisiblePages), pageCount);
  const preferredPageSlot = Math.ceil(visiblePageCount / 2);
  const firstVisiblePage = Math.max(
    1,
    Math.min(
      selectedPage - preferredPageSlot + 1,
      pageCount - visiblePageCount + 1,
    ),
  );

  return {
    pageCount,
    itemRange: [firstItemIndex, itemEndIndex],
    pageRange: [firstVisiblePage, firstVisiblePage + visiblePageCount - 1],
  };
}

The formulas assume that the ordered sequence remains fixed while the user moves between pages. If items are inserted or deleted between requests, offset-based pages can unexpectedly repeat or skip records. Database-backed interfaces that require stability under concurrent changes generally use keyset pagination; the interval derivation remains useful for finite arrays, static result sets, and the presentation layer of a pagination component.