ESCO: the whole 6.3 MB classification, in all 28 languages, is parsed and kept in every process #1110
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#1110
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?
What exists today
src/postulo/jobs/esco.py:129-147classification()(lru_cache(maxsize=1)) doesjson.loads(path.read_text())ofjobs/data/esco-1.2.1.json(6,362,937 bytes): 436 unit groups and 3,039 occupations, each with names in all 28 ESCO languages._occupations_by_name()(:209) and_unit_groups_by_name()(:228) then build one folded index per reading language (lru_cache(maxsize=32)).It is reached on every
JobPosting.save()that may write the title (jobs/models.py:1762,esco.code_for(self.title)), byname_for()(jobs/models.py:1781), and by the title datalist (esco.suggestions()atapplications/forms.py:196andjobs/forms.py:1032), so in practice every worker loads it soon after start. Skills are already split: they live inesco-skills-1.2.1.zipand are read per language member.Measured with
tracemallocunderpostulo.config.settings.test(audit/m_scripts/mem.py m3):classification()14.6 MB retained, 29.2 MB peak, 0.22 s; thencode_for(..., "en")+0.3 MB andcode_for(..., "pt-PT")+1.0 MB. A copy pruned to English only (audit/m_scripts/esco_split.py) is 0.31 MB on disk and 2.4 MB in memory; English plus Portuguese 0.54 MB and 2.7 MB.What would change
Have
manage.py fetch_escowrite the occupation and unit-group names per language, as the skills already are: the structure (isco,nace,major, revision, languages) in one member and the names in one member per language, in a zip like the skills.classification()keeps the structure only, and a per-languagelru_cacheloads names for the languages actually read (the reader's and English, the fallback). The public functions (code_for,name_for,unit_groups,suggestions,divisions_for) keep their signatures. The data-file check injobs/checks.pyand the licence notice follow the new layout. No library needed:jsonandzipfile, as the skills reader already uses.What it saves or protects
medium: 14.6 MB retained and 29 MB peak per worker (measured); about 2.5 MB if only the languages read were loaded
Accessibility
none
Decisions
Found by the efficiency and reliability audit of 2026-10-30 (finding M3; index postulo/postulo#1108). Checked against
mainatdaee30b15(2026-10-30).