so I gave it a try to compare between it and kaminari:
2.5.1 :043 > pagy(Box.all, items: 1, page: 2)
(2.0ms) SELECT COUNT(*) FROM "boxes"
Box Load (1.0ms) SELECT "boxes".* FROM "boxes" LIMIT $1 OFFSET $2 [["LIMIT", 1], ["OFFSET", 1]]
=> [#<Pagy:0x00007fd7e88073a8 @vars={:page=>2, :items=>1, :outset=>0, :size=>[1, 4, 4, 1], :page_param=>:page, :params=>{}, :anchor=>"", :link_extra=>"", :item_path=>"pagy.info.item_name", :cycle=>false, :count=>106}, @count=106, @items=1, @outset=0, @page=2, @last=106, @pages=106, @offset=1, @from=2, @to=2, @prev=1, @next=3>, #<ActiveRecord::Relation [#<Box id: "2fbf947f-c0d8-4c02-9c71-22d7deaaff2e", shipping_request_id: "7dab8aba-961a-4d28-80c8-20b2fb9a63b7", created_at: "2019-03-14 18:22:33", updated_at: "2019-03-14 18:22:33", external_uuid: "b44f08ec-ccbc-424c-b0aa-4cbcbe94cd74", inventory_id: 78, dimension: {"length"=>4.5, "width"=>5.5, "height"=>5.6, "unit"=>"cm"}, weight: 56.6, label_url: nil, warehouse_state: "processing", proforma_url: nil, barcode: "EXOBOX-B44F08EC", proforma_name: nil, tracking_url: "", private_tracking: true, external_shipment_id: nil, state: "preparing", tracking_history: [{"status"=>"preparing", "datetime"=>"2019-03-14 20:22:33 +0200", "active"=>true, "order"=>0}, {"status"=>"pending_pick_up", "datetime"=>"", "active"=>false, "order"=>1}, {"status"=>"picked_up", "datetime"=>"", "active"=>false, "order"=>2}, {"status"=>"en_route_to_destination", "datetime"=>"", "active"=>false, "order"=>3}, {"status"=>"delivered", "datetime"=>"", "active"=>false, "order"=>4}], parent_id: nil, tracking_number: "EXOTRACK-B44F08EC">]>]
2.5.1 :044 > Box.all.page(2).per(1)
Box Load (1.0ms) SELECT "boxes".* FROM "boxes" LIMIT $1 OFFSET $2 [["LIMIT", 1], ["OFFSET", 1]]
=> #<ActiveRecord::Relation [#<Box id: "2fbf947f-c0d8-4c02-9c71-22d7deaaff2e", shipping_request_id: "7dab8aba-961a-4d28-80c8-20b2fb9a63b7", created_at: "2019-03-14 18:22:33", updated_at: "2019-03-14 18:22:33", external_uuid: "b44f08ec-ccbc-424c-b0aa-4cbcbe94cd74", inventory_id: 78, dimension: {"length"=>4.5, "width"=>5.5, "height"=>5.6, "unit"=>"cm"}, weight: 56.6, label_url: nil, warehouse_state: "processing", proforma_url: nil, barcode: "EXOBOX-B44F08EC", proforma_name: nil, tracking_url: "", private_tracking: true, external_shipment_id: nil, state: "preparing", tracking_history: [{"status"=>"preparing", "datetime"=>"2019-03-14 20:22:33 +0200", "active"=>true, "order"=>0}, {"status"=>"pending_pick_up", "datetime"=>"", "active"=>false, "order"=>1}, {"status"=>"picked_up", "datetime"=>"", "active"=>false, "order"=>2}, {"status"=>"en_route_to_destination", "datetime"=>"", "active"=>false, "order"=>3}, {"status"=>"delivered", "datetime"=>"", "active"=>false, "order"=>4}], parent_id: nil, tracking_number: "EXOTRACK-B44F08EC">]>
2.5.1 :045 >
they're running the same query too (regardless select count from boxes query) , so how can I spot the difference between them, and who's better, It feels like they're both the same, knowing that we're using them in an API Project
The level of advantages depends on how you use the pagination in your API. The more pagination info you pack into the API response, the more convenient is Pagy.
From the DB point of view, if you use a classic pagination that needs to calculate the count of the collection, there is no difference in the query time. And it couldn't be, since all the pagination gems need always to perform the same 2 queries: one for getting the count and another for getting the page of results.
So in that case the improvement is not in the queries... UNLESS your API doesn't need to add the total count of results in the response, e.g. if you just need to get the page of results and the links for previous, next, etc. then you can completely avoid the count query by using the pagy countless extra and that could be a huge improvement.
A big advantage using Pagy over other gems is that it is not only many time faster doing its calculations (you can easily waste 20ms per render with Kaminari, depending on the settings), but also that it uses a small fraction of the memory needed by the other gems. That means that it's a big load-relief for the server especially if your app is high-traffic. Its efficiency amounts to hundreds of times more than Kaminari in normal UI conditions, and it should be still many tens of time more in API conditions even with minimal pagination info in the response.
There is a migration guide that should make the migration from legacy gems quite simple. If your Kaminari usage is standard, it will be a mere matter of minutes (mostly search and replace). If you monkey-patched Kaminari or used it in weird ways (probably not with an API), you may have to read some more Pagy doc or ask for live support.
For your API, you can also take a look at the headers extra which encapsulate the API needs for pagination.
FYI: The Pagy v3 (that will be out soon) will improve the speed and lightness even more (noticeably more), if you use ruby 2.0+ with UI helpers. It is still missing the benchmarks it for APIs, but it will certainly improve the headers extra though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With