All Subscriptions takes about a second to list, nearly all of it one query #188

Closed
opened 2026-10-11 06:16:55 -07:00 by rays · 1 comment
Owner

GET /api/entries (every subscribed feed's items, Unread, newest first, 50) took 1002 ms on 2026-10-11 13:06 UTC, of which 939 ms is the entries_in query (trace c3700464f90542301193c5e6f41975d7, with the steps added in #187); sanitising, DeadAir and the count take 20, 6 and 20 ms. Its p95 over the day before was 837 ms, the slowest regular request. One feed's list (/api/feeds/{id}/entries) is 5-20 ms. Worth an EXPLAIN on production's Postgres for that query.

GET /api/entries (every subscribed feed's items, Unread, newest first, 50) took 1002 ms on 2026-10-11 13:06 UTC, of which 939 ms is the entries_in query (trace c3700464f90542301193c5e6f41975d7, with the steps added in #187); sanitising, DeadAir and the count take 20, 6 and 20 ms. Its p95 over the day before was 837 ms, the slowest regular request. One feed's list (/api/feeds/{id}/entries) is 5-20 ms. Worth an EXPLAIN on production's Postgres for that query.
rays added the bug label 2026-10-11 06:16:55 -07:00
Author
Owner

Fixed in 35fca0a, deployed 14:42 UTC. The sort needed each item's date, which was only in its row, so all 13,700 rows of a person's subscriptions were read (cold, off disk: the 0.5-1.9 s first requests); count_in, needing no date, was 20 ms throughout. Now an index holds keys and dates (entries_by_time), the page's keys are sorted and cut from it, and only the 50 rows shown are read. On a copy of the shape in the test database: 619 pages against 4,174, no visits to the table; neither change alone helped. In production, warm: entries_in 37-38 ms (was ~130-170 for the request, 939 cold), the request 58-64 ms (traces c8a69b24b72cb8013c2c059dc5a317bc, a3198425b129be98039e9d8319721671). The first after a quiet spell is the number to watch: {container="iPX"} |= ""route":"/api/entries"" in the next prod check.

Fixed in 35fca0a, deployed 14:42 UTC. The sort needed each item's date, which was only in its row, so all 13,700 rows of a person's subscriptions were read (cold, off disk: the 0.5-1.9 s first requests); count_in, needing no date, was 20 ms throughout. Now an index holds keys and dates (entries_by_time), the page's keys are sorted and cut from it, and only the 50 rows shown are read. On a copy of the shape in the test database: 619 pages against 4,174, no visits to the table; neither change alone helped. In production, warm: entries_in 37-38 ms (was ~130-170 for the request, 939 cold), the request 58-64 ms (traces c8a69b24b72cb8013c2c059dc5a317bc, a3198425b129be98039e9d8319721671). The first after a quiet spell is the number to watch: {container="iPX"} |= "\"route\":\"/api/entries\"" in the next prod check.
rays closed this issue 2026-10-11 07:43:38 -07:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: rays/ipx#188