Get your case straight. First, a proper table definition. We need a PK or similar to break ties unambiguously:

~~~pgsql
CREATE TABLE users (
  user_id     int PRIMARY KEY
, update_time timestamptz NOT NULL
, about_me    text NOT NULL
);
~~~

The column `update_time` is type `timestamptz`. Keep working with `timestamptz`, and don't mix with `timestamp`.

Next, sample rows to exhibit possible problems:

~~~pgsql
INSERT INTO users VALUES
  (1, '2023-04-06 19:59:56.771388 +00:00', 'Hello! How are you?')
, (3, '2023-04-02 03:31:09.833925 +00:00', 'Hello!!!')
, (2, '2023-04-06 00:36:26.822102 +00:00', 'Hello!')
, (4, '2023-04-05 19:16:20.968274 +00:00', 'Hey!')
, (5, '2023-04-02 03:31:09.833925 +00:00', 'Same len')
, (7, '2023-05-02 03:31:09.833925 +00:00', 'Later!!!')
, (6, '2023-03-02 03:31:09.833925 +00:00', 'Earlier!')
;
~~~

Proper base query:

~~~pgsql
SELECT user_id, update_time, about_me
FROM   users u
ORDER  BY date_bin('14 days', update_time, '2023-04-07 23:11:56+0') DESC
        , length(about_me) DESC
        , user_id DESC;  -- !
~~~

`'2023-04-07 23:11:56+0'` being your arbitrary (but constant!) time anchor.

Notably, you added `user_id` as 3rd expression to `ORDER BY` to break ties. That's good. But if you want to keep using [***Row Constructor Comparison***][1], all 3 expressions must share the **same sort direction**. All `ASCENDING` or all `DESCENDING`. (Else it gets more complex and expensive.) See: 

- [SQL syntax term for 'WHERE (col1, col2) < (val1, val2)'][2]
- [How to form a WHERE condition matching multiple ORDER BY items?][3]

Also, add `user_id` to the `SELECT` list. It's essential for your pagination.

Then, to get the 1st page with an example page size of ***3***: 

~~~pgsql
SELECT user_id, update_time, about_me
FROM   users u
ORDER  BY date_bin('14 days', update_time, '2023-04-07 23:11:56+0') DESC
     , length(about_me) DESC
     , user_id DESC
LIMIT  3;
~~~

2nd page:

~~~pgsql
SELECT user_id, update_time, about_me
FROM   users u
WHERE (date_bin('14 days', update_time, '2023-04-07 23:11:56+0'), length(about_me), user_id)
    < ('2023-03-25 00:11:56+01', 8, 5)
ORDER  BY date_bin('14 days', update_time, '2023-04-07 23:11:56+0') DESC
     , length(about_me) DESC
     , user_id DESC
LIMIT  3;
~~~

[fiddle](https://dbfiddle.uk/ON5GXBHt)

`('2023-03-25 00:11:56+01', 8, 5)` being derived from the last row of the first page.

`'2023-03-25 00:11:56+01'` is the result of the `date_bin()` expression. You might add it to the `SELECT` list for simplicity. (I added it in the fiddle.)

Since your `date_bin()` expression uses an arbitrary time anchor (and interval?), using an index is sophisticated, but still possible. Work with the lower / upper bounds of possible `date_bin()` values ...

These two `timestamptz` values are exactly the same:

~~~none
'2023-03-24 23:11:56+00'
'2023-03-25 00:11:56+01'
~~~

The *display* depends on the `timezone` setting of your session, the *value* is the same. Basics:

- [Ignoring time zones altogether in Rails and PostgreSQL][4]


  [1]: https://www.postgresql.org/docs/current/functions-comparisons.html#ROW-WISE-COMPARISON
  [2]: https://stackoverflow.com/a/32982895/939860
  [3]: https://stackoverflow.com/a/56009745/939860
  [4]: https://stackoverflow.com/a/9576170/939860