Offset is the right default when the dataset is small and stable, when users genuinely need to jump to an arbitrary page number, or when you must show a total count and total pages. It is simple to build, easy to reason about, and fine for an admin table of a few thousand rows.
Offset breaks down on two fronts. It gets slow on deep pages because of the row skipping, and it produces drift on live data. If a new row is inserted at the top while a user pages through, every later page shifts down by one, so they see a duplicate at the boundary or miss a row entirely.
Cursor pagination fixes both problems. It stays fast at any depth and it does not skip or duplicate items when the underlying data changes, because the anchor is tied to a row, not a position. The cost is that you usually lose random page access and a reliable total count, and the sort key must be stable and unique, which is why most cursors combine a timestamp with a tie-breaking id.