Client side pagination is not good in some cases

posted Originally published at ozkanpakdil.gitlab.io 2 min read

The Pagination Pitfall: A React + Spring Boot Cautionary Tale

The Setup: "It’ll Be Fine..."

A few years ago, I was working on a dashboard application with a React frontend and a Spring Boot backend. The task seemed simple: display a list of users with pagination.

One of the newer devs suggested:

“Let’s just fetch everything once and paginate on the client side — it’ll be faster for the user.”

We had maybe 500 users at the time, so… sure. Why not?

And then we shipped it.


The Plot Twist: Growth Happens

A few months passed.

Marketing launched a campaign that worked too well.
Suddenly, instead of 500 users, we had 250,000+.

The dashboard became unusable. The browser would freeze, mobile devices would crash, and CPU usage would spike through the roof.
Our once-smooth user experience turned into a memory-leaking nightmare.


⚠️ The Mistake: Client-Side Pagination at Scale

Client-side pagination works only when:

  • The dataset is small and controlled
  • The entire dataset can be loaded efficiently in the browser
  • You don’t expect explosive growth

But when you're working with Spring Boot APIs and React, it's tempting to fetch all data via a single REST call, dump it into state, and let React handle the UI slicing.

What’s wrong with that?

  • You're sending huge payloads over the wire
  • You're increasing memory usage on the frontend
  • You’re locking users into long initial load times
  • You make updates or filtering much harder

✅ The Fix: Server-Side Pagination with Spring Boot + React

We refactored. Here’s what we did:

Backend (Spring Boot)

We used Pageable from Spring Data:

@GetMapping("/users")
public Page<User> getUsers(Pageable pageable) {
    return userRepository.findAll(pageable);
}

Spring Boot handles page number, size, sorting, and total count under the hood.

Frontend (React)

We called the API with query parameters like ?page=0&size=20:

const fetchUsers = async (page, size) => {
  const res = await fetch(`/api/users?page=${page}&size=${size}`);
  const data = await res.json();
  setUsers(data.content);
  setTotalPages(data.totalPages);
};

We then plugged this into a pagination UI. Now, we load only what we need, keep response times fast, and keep the browser happy.


Lessons Learned

  • React + Spring Boot is a powerful combo — but scale with caution
  • Don’t optimize for “today’s data” unless you’re certain it won’t grow
  • Use Spring’s Pageable and let the database do the heavy lifting
  • Keep network traffic and frontend memory usage lean
  • Premature optimization is bad, but premature de-optimization is worse

TL;DR

Using client-side pagination for large or unknown datasets is like bringing a spoon to a firefight.

It might work — for a while — but you’re setting yourself up for disaster.

Use the right tools. Paginate smart. Scale with confidence.

If you read this far, tweet to the author to show them you care. Tweet a Thanks
0 votes
0 votes

More Posts

Offset vs Cursor-based Pagination: Choosing The Right Pagination Strategy

timothyokooboh - Apr 1

Why Talking to AI Without Good Prompts Is Like Yelling at Siri in 2008

Yash - Sep 28

Blazing Fast @m2d/react-markdown

Mayank - Jul 12

Talking to AI Without Good Prompts Is Like Ordering at McDonald’s Blindfolded

Yash - Sep 29

NodeJS Timeouts: The I'm Still Working, Just Not Talking to You Problem

David Oluwatobi Peter - Jul 14
chevron_left