There are 2 main methods of rendering pages in the api:

  • pageNo (page number, it happens from both 1 and 0) and pageSize (page size)
  • offset and limit (number of elements)

PageNo/pageSize is easy to convert to offset/limit:

  • offset = pageNo * pageSize
  • limit = pageSize

Calculating pageNo based on offset/limit is a non-trivial task. There are options when you have to request more items and then discard some of them. For example, something like this :

public static PageSizeOffsetLimit toPageSize(int offset, int limit) {
    if (offset < limit) {
        return new PageSizeOffsetLimit(0, offset + limit, offset, limit);
    if (offset == limit) {
        return new PageSizeOffsetLimit(1, limit, 0, limit);

    for (int size = limit; size < 2 * limit; size++) {
        int newOffset = offset % size;
        if ((size - limit) >= newOffset) {
            return new PageSizeOffsetLimit(offset / size, size, newOffset, limit);
    throw new RuntimeException(String.format(
        "Cannot determinate page and size from offset and limit (offset: %s, limit: %s)",

(as you can see, the compiler does not really understand exactly whether we will find the value or not - one of the examples of code that is not covered in tests)

So the offset/limit pair is more universal and more understandable (there is no beginning from 0, then from 1), but if you then have to switch to pageNo/pageSize, then this may require additional tricks.

In general, I try to use offset/limit in the API.