Periklis Ntanasis:
Master's Touch

fade out

Lack of pagination considered harmful

Pagination, also known as paging, is the process of dividing a document into discrete pages, either electronic pages or printed pages.

Pagination can be handled client-side or server-side. Server-side pagination is more common. Client-side pagination can be used when there are very few records to be accessed, in which case all records can be returned, and the client can use JavaScript to view the separate pages. By using AJAX, hybrid server/client-side pagination can be used, in which Javascript is used to request the subsequent page which is loaded and inserted into the Document Object Model via AJAX.

Server-side pagination is appropriate for large data sets providing faster initial page load, accessibility for those not running Javascript, and complex view business logic.

https://en.wikipedia.org/wiki/Pagination
— Wikipedia

Client-side pagination means that the server will return all the results that match some search criteria and the client will under the hood display them in chunks called pages. That just a trick to help the user focus on a subset of the results.

Additionally, the client may let the user filter the results or apply different ordering rules etc.

For sure, if you are the back-end software engineer implementing a system like that is a much simpler implementation and less work for you.

On the other hand, server-side pagination means that the client will request the server only the data that it will display. The burden of implementing the pagination logic is now split both to client and server sides with the server-side pulling most of the weight.

Here is an example of how Google and others let the user navigate between the pages of the result data:

Pagination Examples

In this article I will talk to you about server-side pagination and try to convince you why always you should go for it.

My first encounter with pagination

I think the first time I have considered implementing server-side pagination was during a university web development course where we had to build a Question and Answer website, something like a simplified StackOverflow.

I think inspired partially by Twitter I would like to have the main page load the questions dynamically as the user would scroll down.

From the server perspective there is no actual difference regarding how the client decides to represent the data.

The client is free to implement pages such as the Google results, 9gag, Twitter or whatever.

This worked out beautifully back then and actually since then it seemed to me that this was the best way to implement pagination. I thought that it would be natural for everyone to implement the pagination in the server-side but as I later found it actually wasn’t!

Pagination misfortune

A few years later I was working in a professional environment.

There was an application developed and considered finished by some other team. It was in the process of being penetration tested before being deployed to production.

The pen test has failed and it was up to my team to find out what was going wrong.

The outcome of the pen test was that some requests were timing out. Probably the pen test flagged these requests as potential for DoS attack.

Very soon after exploring the application it was obvious to me what was the problem.

The application had a classic search page with a criteria form that would return the results and display them in pages. This page would fetch all the data from the server and then implement the pagination in the client-side.

For the purposes of the pen test there were generated test data. There were around 12000 entries returned from that service.

The client took a minute or something to fetch all the data and afterwards there were a few dozens of seconds until the browser be actually able to display them properly.

Also, as far as I remember even actions like changing pages were slow because the browser had so many elements in memory to handle.

Long story short, I have implemented server-side pagination and there was a tremendous boost in performance. Everything worked beautifully. App passed the pen test and went live on time with just a couple of over-hours!

That was the first time I realized how important is the server-side pagination. Something that I thought was naturally a better choice and my preferred way of implementing pagination was now proven to me that it was practically the best way.

What I didn’t know was how common that mistake was.

Path to success

From then on when I was implementing such a service I was providing pagination if I had the chance. The implementation specifics could vary but that didn’t really matter.

There were times where quality would decreased in favor of delivering faster. In some cases there wasn’t enough time for implementing server-side pagination. Then, I tried to make sure to communicate the dangers of not having pagination. I made sure that this decision was documented and when the time did came we could identify quickly the problem and pay our debt.

And the time always came. It varied depending how fast the data were growing. It could be one month, six months or even years later. But it would eventually happen.

I have faced the lack of server-side pagination from the client-side too. Again I made sure to let the back-end team know.

Some times I heard as a response that we could implement pagination in the browser if we wanted to. Of course this was never the problem.

Other times I have heard that they know but they didn’t have time at the moment or that they know but by their projections this wouldn’t be a problem for the next X years.

That was ok. I sympathize the developers who make an educated choice and trade-offs for good reasons. I dislike when things happen by coincidence.

More pagination madness

As you can seen not always my concerns were addressed.

I remember working in another app that was going to be used in an internal network. This is a very common setting for "enterprise" class applications.

The app was fetching all the data from the server in each search screen. It also did provide client-side filtering on each column.

Fun fact was that the back-end service was implementing the pagination but it wasn’t implemented in the client. The client did fetch everything explicitly. (However, the service didn’t implement the filtering!)

I have raised my concerns but I was told that it was OK. The app was going to be used in an internal network. It was going to work as expected for a big number of results.

In some screens where the problem was more apparent the client was enforcing a few search filters as mandatory in order to limit the results. This is not bullet proof as again after some time it will cause problems.

And you know what. This app went to the clients for user acceptance test. They have loaded it with lots of test data and boom!

Some requests as expected started to take too much time to respond! Others started to fail some or all of the times with timeouts!

Of course the behavior varied depending on the network quality and load.

From our end we ensured the users that the app was working OK for a couple dozen thousands of results. The users insisted that they got the error sooner.

The cause was simple and it was that their network was slower. We tested the app in a fast local network. Their test server was in an internal network but slower, with more hops and load than ours. So the delay was bigger.

Lessons learned

I hope to have made you see by presenting you 2 real life experiences how nasty can be the lack of server-side pagination. Be sure that I have more similar stories to tell!

I am convinced for sure that the lack of server-side pagination will always sooner or later be a problem. It is not a premature optimization. It should be a standard.

It will start with the application getting slower. After some time and depending the web server configuration it will start failing for some of the requests and eventually for every request.

So, let’s have some bullet points we all like!

  • Server-side pagination for little data or a local network application may be an optimization. For many data or an internet facing application it will be a necessity.

  • If server-side pagination is not implemented make sure to communicate the potential problems with the involved parties and document it so in the future you will move faster when the problem rise.

  • Don’t think that it won’t happen to you. It will!

  • Test your application with sufficient number of data. Consider the data that will be accumulated after a few years of operation and then add some more. With properly implemented pagination it shouldn’t matter and it should work the same regardless the volume.

  • When implementing server-side pagination take into consideration if it is required to support filtering and/or ordering. This is absolutely doable but could be tricky.

  • It takes a correct implementation from both the server and the client in order to have this done correctly.

  • Set a sensible default pages size. I wouldn’t suggest setting a max limit but you can consider it if you want to make sure that the client will use the pagination.

  • Always make educated choices!

Epilogue

I hope I have been motivational enough and you will always implement server-side pagination (or at least seriously consider it)!

It is actually not so hard if you have some experience with it. Modern frameworks provide some of the required functionality and make the process easier.

I could argue and discuss how a (possible) beautiful pagination API should look like but this is a matter of secondary importance.

Deliberately, I haven’t mentioned specific technologies, protocols etc. in this article. It doesn’t matter. Server-side pagination may be implemented in any language, framework or protocol and it should!

So, carry on and code responsibly!

Comments

fade out