Post

Reducing Count Query Cost in Pagination

Reducing Count Query Cost in Pagination

What I Didn’t Know

While implementing pagination for the Gift API at Kakao Tech Campus, I used Spring Data JPA’s Page as the return type. Mentor told me something during code review:

“Page internally needs to know the total data count, so an additional count query runs.”

I didn’t know that using Page triggers SELECT COUNT(*) on every request.


Why Is Count Query Dangerous?

With small datasets, it’s fine. But with millions of rows, COUNT(*) can become a bottleneck.

For infinite scroll UI, total count isn’t needed. But if you use Page, you’re running unnecessary count queries.

Mentor feedback:

“Page exposes a lot of unnecessary information internally. totalPages, totalElements, sort, numberOfElements… If the client only needs some of this, there’s unnecessary serialization cost.”

“To avoid this, use Slice. Slice only determines if there’s a next page, so it doesn’t run a count query.”


Page vs Slice

PropertyPageSlice
Count queryRunsDoesn’t run
Total page countKnownUnknown
Has next pageKnownKnown
Best forPage number UIInfinite scroll, “Load more”

When to Use What?

Page

  • When you need page numbers like “1 2 3 4 5 … 100”
  • When you need total count like “2,340 products total”

Slice

  • Infinite scroll
  • Just a “Load more” button
  • When total count isn’t needed

Lessons Learned

  • Learned that Page triggers count queries
  • Use Slice when total count isn’t needed
  • Need to understand what the framework does behind the scenes

From Kakao Tech Campus 3rd cohort Gift API clone coding, summarizing mentor feedback.

This post is licensed under CC BY 4.0 by the author.