🚀 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.