Duplicate check: /captures/known misses listings beyond the 200 newest at a path, such as Indeed's /viewjob?jk= #556
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#556
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found on 2026-09-29 in a read-only review of postulo at
95348908d, by readingjobs/known.pyand runningknown()against 250 listings at one Indeed path.Checked again on 2026-10-01 against
mainat0a5cad587: still present. The code is now atapi/api.py:754-804(known_captures);jobs/known.py,jobs/capture_views.pyandcore/addresses.pyhave not moved.known()narrows in SQL withurl__icontains=_needle(url), where the needle is the path alone, then decides withsame_url, which keeps the query string, in Python, over at mostLIMIT = 200of the newest rows. On boards that carry the job id in the query (Indeed's/viewjob?jk=…, LinkedIn's…/jobs/search/?currentJobId=…) every listing from that board matches the needle, so once a person has more than 200 of them the older ones are never compared, and the endpoint answers that a posting already held has never been seen: the duplicate #178 was written to prevent comes back. The same shape also makes each answer read up to 200 whole listings and 200 whole captures.jobs/known.py:23-25(LIMIT),jobs/known.py:43-46_needle,jobs/known.py:57-78known; callersapi/api.py:752-800known_captures(up to 100 postings per call, oneknown()each),jobs/capture_views.py:107(the capture form) andjobs/capture_views.py:253-266(the review screen);core/addresses.py:66-84same_url.https://www.indeed.com/viewjob?jk=<id>,known()finds the newest (1 match) and nothing for any of the 50 oldest (0 matches), checked on the snapshot. For cost, the other reviewer's experiment with 300 Indeed listings (5 KB descriptions) and 150 waiting captures: a/captures/knowncall for 40 new postings made 133 queries and took 1.7 s, reading every listing's description and every capture'sdatato answer "none known". The browser extension calls it each time its popup opens on a results page.url_keycolumn holdingsame_url(url)toJobPostingandCapture, set on save, with a data migration for existing rows, and answer withfilter(url_key=key)(orurl_key__in=keysfor the whole API call): one indexed query, no cap and no comparison in Python. Until then, at least include the query string in the needle when there is one, and load only the fields the answer shows (.only(...), or.defer("description")on listings and.defer("data", "learning")on captures).Related to #178 (closed), which introduced the check.
Done when
tests/test_known.pycreates 250 listings athttps://www.indeed.com/viewjob?jk=<n>and asserts thatknown()finds the oldest one; it fails today./captures/knowncall for 40 postings runs a number of queries independent of how many listings the account holds.