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. During code review, my mentor pointed out:

“Page internally needs the total data count, so an extra count query runs.”

I had no idea that using Page triggers SELECT COUNT(*) on every request.


Why Is Count Query Dangerous?

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

For infinite scroll UIs, you don’t even need the total count. But if you’re using Page, you’re paying for unnecessary count queries.

Mentor feedback:

“Page exposes a lot of unnecessary info internally—totalPages, totalElements, sort, numberOfElements… If the client doesn’t need all of this, you’re wasting serialization cost.”

“Try using Slice instead. Slice only checks if there’s a next page, so it skips the count query entirely.”


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 to display total count like “2,340 products”

Slice

  • Infinite scroll
  • “Load more” button
  • When total count is irrelevant

Lessons Learned

  • Now I know that Page triggers count queries
  • Use Slice when total count isn’t needed
  • Always understand what the framework does under the hood

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.