10. november 2026 | Egenutvikling | Odoo, ytelse og søkemotorer
Et Odoo-nettsted rendrer hver side på nytt ved hvert kall: databasespørringer, maler, oversettelser, priser. For én enkelt besøkende merkes det knapt. Men når søkemotorer og KI-indeksere henter hundrevis eller tusenvis av sider på mange språk, blir det en konstant belastning, og ekte kunder må vente med. Derfor har vi utviklet Odoo 19-modulen website_page_cache og publisert den på GitHub som åpen kildekode (LGPL-3): Butikk- og bloggsider som hentes anonymt, leveres nærmest statisk fra en hurtigbuffer, enten fra filer eller fra arbeidsminnet (RAM), og hver endring – også i en oversettelse – fjerner de berørte sidene fra bufferen automatisk igjen.
Viktig for alle som ønsker å bli funnet: Modulen sperrer ingen søkemotor og ingen KI-crawler. Alle indeksere får det samme innholdet som enhver besøkende, bare raskere. Dette innlegget forklarer hvordan hurtigbufferen fungerer, hvordan dashbordet ser ut (med skjermbilder), hvordan du ser om sidene dine passer i arbeidsminnet og hvor mye ekstra RAM som ville trengs, hvilke sikkerhetsregler som gjelder og hvordan du installerer modulen.
Innhold i dette innlegget
- Kortversjon
- Problemet: crawler-belastning på Odoo-nettsteder
- Slik fungerer sidebufferen
- Fil eller RAM: velg lagringssted
- Passer nettstedet i arbeidsminnet? Og hvor mye RAM mangler?
- Endringer og oversettelser rydder opp i bufferen
- Dashbord og statistikk
- Sikkerhet: det som aldri kommer fra bufferen
- Søkemotorer og KI-indeksere: ingenting sperres
- Minimere HTML og levere komprimert
- Installasjon og innstillinger
- Begrensninger du bør kjenne til
- Ofte stilte spørsmål
- Støtte fra Biricon IT Services
Kortversjon
| Tema | Dette gjelder |
|---|---|
| Modul | website_page_cache for Odoo 19, lisens LGPL-3, offentlig på GitHub |
| Hva bufres? | Offentlige butikk- og bloggsider (lister, kategorier, produkter, innlegg) på alle språk på hvert nettsted |
| For hvem? | Kun for anonyme besøkende, kun GET-kall uten søkeparametere, kun status 200 med HTML |
| Lagringssted | Filer på disk eller RAM (tmpfs, delt av alle arbeidsprosesser); automatisk etter plassbehov |
| Aktualitet | Hver endring (også oversettelser, importer, skript) oppretter via databaseutløsere en journalpost og ugyldiggjør de berørte sidene |
| Dashbord | Innstillinger, status, statistikk (treff, bom, spart servertid) og kontrollen «Passer det i arbeidsminnet?» inkludert «ekstra nødvendig RAM» |
| Søkemotorer og KI | Ingenting sperres eller strupes; alle får de samme sidene, bare raskere |
| Nødbrems | En bryter (enabled = 0) slår av bufferen i alle arbeidsprosesser i løpet av 30 sekunder |
Problemet: crawler-belastning på Odoo-nettsteder
Odoo er et fullstendig ERP-system, og nettstedet er én av mange moduler. Hver side som en besøkende eller en robot henter, går gjennom den samme veien: behandle forespørselen, spørre databasen, laste produkt- og prisdata, rendre QWeb-malen, sette inn oversettelser og levere resultatet. Det tar, avhengig av siden, noen hundre millisekunder og opptar i denne tiden en av de få arbeidsprosessene.
For søkemotorer og KI-indeksere er dette et vedvarende problem:
- Mange språk, mange adresser: En side som finnes på 46 språk, er 46 forskjellige adresser for en crawler.
- Hver adresse hentes enkeltvis, ofte av mange distribuerte avsendere samtidig. En vanlig nettleserbuffer hjelper ikke her, fordi hvert kall gjelder en ny adresse.
- Få arbeidsprosesser: En Odoo-tjeneste kjører vanligvis med en håndfull prosesser. Er de opptatt med crawler-forespørsler, står ekte besøkende i kø.
- Samme innhold, om og om igjen: Et blogginnlegg endres sjelden, men bygges opp på nytt med stor kostnad ved hvert kall.
Den nærliggende utveien – å sperre crawlere – er ikke noe alternativ for et selskap som vil bli funnet. Synlighet i søkemotorer og i KI-svar er verdifull. Bedre er det å levere sidene så raskt at belastningen knapt merkes. Akkurat det gjør sidebufferen.
Slik fungerer sidebufferen
Modulen kobler seg på Odoos forespørselsinngang (ir.http). Ved hvert sidekall avgjør den på brøkdelen av et millisekund om siden kan komme fra bufferen, og leverer den da uten database, uten mal og uten rendering.
- Kontroll: Bare et anonymt
GET-kall uten søkeparametere til en tillatt sti (butikk, kategorier, produkter, blogg) kommer på tale. Alt annet går som vanlig gjennom Odoo. - Buffernøkkel: Den består av nettsted, vertsklasse, språk, sti, prisliste, skatteposisjon og status for informasjonskapsel-samtykke. Besøkende som ville sett noe annet, deler derfor aldri en oppføring. Verten normaliseres: Odoo skriver absolutte adresser alltid ut fra nettstedets domene, ikke fra forespørselen; forespørselsadressen avgjør bare om siden regnes som hovedadresse (språklenker) og om den skal indekseres. Alle fremmede vertsnavn deler derfor én oppføring med
noindex-merknad, i stedet for å oppta hver sin kopi. - Treff: Finnes det en gyldig oppføring, leveres den. CSRF-tokenet i siden settes da på nytt for hver forespørsel. Kall til blogginnlegg telles fortsatt.
- Bom: Mangler oppføringen eller er den utdatert, rendrer Odoo siden som vanlig. Kan resultatet bufres (status 200, HTML, ingen informasjonskapsel, ingen økt-ID i teksten), lagres det; neste kall er et treff.
- Synlig i headeren: Hvert svar har headeren
X-Page-Cache: HITellerMISS. Slik kan du kontrollere med et hvilket som helst verktøy hva som skjedde.
Hvor mye raskere?
I testsystemet vårt (kopi av nettstedene våre, noen hundre sider) var gjennomsnittlig renderingstid per side rundt 490 millisekunder, mens levering fra bufferen tok rundt 23 millisekunder: omtrent tjue ganger raskere. Jo mer krevende en side er, desto større gevinst. Ut fra begge verdiene beregner dashbordet også den anslåtte sparte servertiden.
Fil eller RAM: velg lagringssted
Bufferen har to lagringssteder. Begge er felles synlige for alle Odoo-arbeidsprosesser, så hver side finnes bare én gang, ikke én gang per prosess.
| Innstilling | Hvor ligger sidene? | Egenskaper |
|---|---|---|
| Filer | Katalog i Odoos datamappe, per database | overlever omstarter; operativsystemet holder uansett ofte brukte sider i minnet |
| Arbeidsminne | tmpfs under /dev/shm | raskeste levering; går tapt ved omstart av serveren og bygges ganske enkelt opp igjen |
| Automatisk | RAM så lenge alt får plass; ellers filer | En vedlikeholdsjobb (hvert 10. minutt) avgjør ut fra estimatet; blir på RAM ved «passer» og «knapt», slik at valget ikke skifter hele tiden |
For de fleste installasjoner er Automatisk det riktige valget: Du får RAM-hastighet når det er plass, og faller ellers tilbake på filer uten at du må gripe inn.
Passer nettstedet i arbeidsminnet? Og hvor mye RAM mangler?
Om en RAM-buffer er mulig, avhenger av tre ting: av antall sider, av deres gjennomsnittlige størrelse og av tilgjengelig minne. Dashbordet regner dette ut for deg:
- Antall sider: Per nettsted teller det publiserte produkter, butikklistesider, kategorier, blogginnlegg og blogglister, og multipliserer med antall språk.
- Sidestørrelse: Så snart det ligger sider i bufferen, måles den faktiske gjennomsnittsverdien; inntil da gjelder en antatt verdi.
- Plass til bufferen: den minste verdien av det innstilte RAM-budsjettet, størrelsen på tmpfs og halvparten av tilgjengelig arbeidsminne. Serveren skal aldri få minnemangel på grunn av bufferen.
- Vurdering: «passer med reserve», «knapt», «for stor» eller «RAM-buffer ikke tilgjengelig». «Passer» gjelder når behovet er høyst 80 prosent av tilgjengelig plass.
Nytt: Hvor mye ekstra RAM trengs?
Passer ikke bufferen, vil man vite hva som må endres. Dashbordet oppgir derfor under vurderingen en konkret linje: «Ekstra RAM for en RAM-buffer: omtrent … mer arbeidsminne på denne serveren» – eller «ingen» hvis plassen allerede er nok. Hvis det ikke er serveren, men bare en innstilling som er for liten, står det under hvilken: modulens RAM-budsjett eller størrelsen på tmpfs (/dev/shm).
Regnestykket bak er enkelt og etterprøvbart:
- Behov = sider × gjennomsnittlig sidestørrelse.
- Med reserve = behov delt på 0,8. Denne verdien må få plass i RAM-budsjettet og i tmpfs for at vurderingen skal bli «passer».
- Ledig minne: Siden bufferen høyst kan bruke halvparten av tilgjengelig arbeidsminne, trenger serveren minst det dobbelte av verdien fra trinn 2 som fritt tilgjengelig minne. Mangler noe, er differansen det ekstra nødvendige RAM-et.
Eksemplet i bildet (12 000 sider à 25 KB) er et regnehjelpemiddel, ikke en måling av sidene våre. For små nettsteder holder noen få titalls megabyte; eksempeldataene i skjermbildene klarte seg med rundt 13 MB.
Viktig for helhetsvurderingen: Estimatet teller ikke ekstra versjoner per prisliste eller land. Den som bruker mange av dem, bør planlegge litt reserve. Og: Et for lite RAM-budsjett er den vanligste grunnen til at automatikken blir på filer – ikke manglende arbeidsminne. Dashbordet viser i så fall akkurat denne linjen.
Endringer og oversettelser rydder opp i bufferen
En buffer er bare brukbar hvis den aldri leverer utdaterte sider. En ren tidsgrense («forkast hver tolvte time») ville vært for grov: En endret pris eller en rettet skrivefeil måtte vente i opptil tolv timer. Modulen arbeider derfor innholdsbasert.
- Databaseutløsere: På alle tabeller som kan påvirke en side (produkter, varianter, bilder, beholdning, attributter, kategorier, priser, skatter, prislister, blogginnlegg og stikkord, partner- og firmadata, visninger, assets, menyer, språk, nettstedsinnstillinger) sitter det PostgreSQL-utløsere. De fører hver endring inn i et endringsjournal.
- Avhengigheter og databasestand: Hver bufret side husker hvilke poster den viser, og databasestanden den ble generert med.
- Avstemming: Finnes det en journalpost som oppsto etter denne stillingen og som gjelder en av disse postene, er siden utdatert.
- Bufre på nytt: Ved neste kall forkastes den utdaterte siden, rendres på nytt og lagres igjen.
Også oversettelser er dekket
Odoo 19 lagrer oversatte tekster i samme post som originalteksten (som et JSON-felt). En endret oversettelse er derfor for databasen en helt vanlig radendring – og utløseren ser den. Dette gjelder like fullt for redigering via grensesnittet, for importer, for grensesnitt mot andre systemer og for skript som skriver direkte til databasen. En automatisk oversettelse til 46 språk ugyldiggjør dermed akkurat de sidene hvis tekst har endret seg, og ikke flere.
- Målrettet i stedet for generelt: Et endret produkt ugyldiggjør sine sider, listene det står i, og den tilhørende kategorien. Resten blir værende i bufferen.
- Globale endringer (maler, assets, språk, menyer, skatter, valutaer) ugyldiggjør alt på én gang, fordi de kan påvirke hver side.
- Tellere holdes utenfor: Visningstelleren for blogginnlegg endres ved hvert besøk; den utløser bevisst ingen ugyldiggjøring, ellers ville bufferen vært virkningsløs for populære innlegg.
- Sikkerhetsnett: I tillegg finnes det en maksimal alder per side (standard 12 timer).
- Ingen skrivefeil på grunn av bufferen: En feil inne i en utløser loggføres som advarsel og lar ikke selve lagringen mislykkes.
Dashbord og statistikk
Alt du trenger for driften, finnes ett sted: i Odoo under Nettsted → Rapporter → Sidebuffer. Avsnittet Oversikt er dashbordet (med innstillingene), avsnittet Utvikling viser tallene per dag og nettsted.
Skjermbilde fra et testsystem med kopier av nettstedene våre; nettstedsnavnene er erstattet med plassholdere.
Innstillinger
| Innstilling | Betydning |
|---|---|
| Aktiv | Hovedbryter. Er den slått av, leverer Odoo igjen hver side som før, i alle prosesser senest etter 30 sekunder. |
| Lagringssted | Automatisk, filer eller arbeidsminne |
| Maksimal alder (timer) | Sikkerhetsnett; sider fornyes etter denne tiden uavhengig av endringer |
| RAM-budsjett (MB) | Så mye arbeidsminne kan RAM-bufferen høyst oppta; samtidig grensen for vurderingen «passer» |
| Diskgrense (MB) | Maksimal størrelse på filbufferen; eldste oppføringer fjernes først |
Status og statistikk
Status viser aktivt lagringssted med grense, antall og størrelse på bufrede sider og endringssporingen: hvor mange endringer som er registrert de siste 24 timene, og hvor mange tabeller som overvåkes. Mangler en overvåking, advarer dashbordet tydelig, for da kan man ikke stole på bufferen. Knappene øverst lar deg kjøre vedlikeholdet med en gang, tømme bufferen eller kontrollere utløserne og om nødvendig opprette dem på nytt.
Statistikken (I dag, 7 dager, 30 dager) inneholder:
- Fra bufferen og Rendret: treff og bom, og av disse treffprosenten
- Fjernet (endret/utløpt): hvor mange sider som ble forkastet på grunn av endring eller utløp
- Renderingstid og buffertid: gjennomsnittet per side i sammenligning
- Anslått spart servertid og datamengde fra bufferen
Tallene samles av hver arbeidsprosess for seg og skrives én gang i minuttet; rader som er eldre enn 90 dager, ryddes bort av vedlikeholdsjobben.
Utvikling som diagram, pivot og liste
Under Utvikling finnes dagsverdiene per nettsted – som diagram, som pivottabell eller som liste. Slik ser du om treffprosenten stiger igjen etter en omstart eller en stor endring, og hvilket nettsted som får mest trafikk fra bufferen.
Sikkerhet: det som aldri kommer fra bufferen
En sidebuffer må aldri føre til at noen ser en annens innhold. Modulen følger derfor prinsippet: Ved tvil, ikke bufre.
- Bare anonyme besøkende: Den som er pålogget, har en handlekurv eller har en annen øktstatus, får alltid den vanlig rendrede siden.
- Bare
GETuten søkeparametere: Søk, filtre, sorteringer, skjemaer, handlekurv og kasse forblir urørt. - Bare status 200 og HTML: Feilsider, omdirigeringer og filer lagres ikke.
- Ingen økt-ID-er i bufferen: En side som inneholder en økt-ID eller setter en informasjonskapsel, lagres ikke (og loggføres som advarsel).
- CSRF-token per forespørsel: Tokenet i den bufrede siden er en plassholder og settes inn på nytt ved hver levering.
- Fin nøkkel: Nettsted, språk, prisliste, skatteposisjon og samtykke til informasjonskapsler hører til buffernøkkelen; den som ser noe annet, får en annen oppføring.
- Flere databaser: Hver database har egne oppføringer, eget journal og egen statistikk.
- Ingen datalekkasje: Bufferen ligger lokalt på serveren (fil eller RAM). Ingen data overføres til tredjeparter.
Søkemotorer og KI-indeksere: ingenting sperres
Noen driftere svarer på crawler-belastning med sperrer. Det beskytter serveren, men koster synlighet. Modulen velger motsatt vei:
- Samme innhold for alle: Søkemotorer, KI-indeksere og besøkende får den samme siden. Det finnes ingen egen «crawler-versjon» og ingen gjenkjenning etter nettleseridentifikator.
- Raskere svar hjelper indekseringen: En side som svarer på 20 i stedet for 500 millisekunder, belaster crawl-budsjettet mindre, og crawlere kan fange opp flere sider i samme tidsrom.
- Oppdatert innhold: Fordi endringer ugyldiggjør sidene umiddelbart, ser crawlere aldri en utdatert versjon – viktig hvis du vedlikeholder innhold for søk og KI-svar.
- Strukturerte data bevares: JSON-LD, metaangivelser og
hreflang-henvisninger er del av den bufrede siden; områdekart og filer berøres ikke av bufferen.
Hvis du i tillegg vil begrense belastning, er det en separat beslutning du kan ta bevisst – modulen tvinger den ikke på deg.
Minimere HTML og levere komprimert
Bufferen sparer ikke bare regnetid, men også datavolum. Modulen minimerer HTML-en før den lagres og leverer den komprimert når nettleseren eller crawleren tilbyr det:
- Minimere (parameter
website_page_cache.minify): HTML-kommentarer utgår, tomrom slås sammen. Det fjernes helt bare der nettleseren uansett ignorerer det, for eksempel mellom blokkelementer. Avstander mellom inline-elementer beholdes,pre,textareaog skript forblir uendret, strukturerte data (JSON-LD) skrives om kompakt. Avhengig av siden blir sidene 10 til 30 % mindre. I testen med sju ekte sider var tekst, antall elementer, posisjon til alle elementer og skjermbilde identiske med originalen. Den første leveringen (MISS) er minimert nøyaktig som alle senere (HIT). - Komprimere (parameter
website_page_cache.compress): Sider fra bufferen sendes ut med gzip (Content-Encoding: gzip,Vary: Accept-Encoding). De store asset-pakkene (CSS og JavaScript, opptil noen MB) leverer Odoo selv ukomprimert; modulen komprimerer dem én gang, legger kopien på disken og leverer dem deretter direkte. Av 2,1 MB CSS ble det slik 0,27 MB, av 4,8 MB JavaScript 1,1 MB. Gamle kopier ryddes bort av vedlikeholdsjobben. - Etter omstart av maskinen: RAM-bufferen beholdes ved omstart av Odoo, men ikke ved omstart av serveren. Derfor speiler vedlikeholdsjobben den gradvis til disken (parameter
website_page_cache.persist) og gjenoppretter den ved oppstart. Om en gjenopprettet oppføring fortsatt er gyldig, kontrolleres av den samme mekanismen som ellers: alder og endringsjournal. Minimeringen beregnes ikke på nytt i den forbindelse.
Installasjon og innstillinger
- Hente modulen: Last ned kildekoden fra GitHub og legg den i en addons-sti i din Odoo 19-installasjon: github.com/Alex0176/odoo-website-page-cache
- Installere:
odoo-bin -d <Datenbank> -i website_page_cache --stop-after-init. Da opprettes endringsjournalet, utløserne og vedlikeholdsjobben (hvert 10. minutt). - Starte tjenesten på nytt, slik at alle arbeidsprosesser laster modulen.
- Åpne dashbordet: Nettsted → Rapporter → Sidebuffer. Kontroller at endringssporingen er fullstendig, og velg lagringssted (standard: automatisk).
- Kontrollere: Hent en butikk- eller bloggside to ganger og se på headeren
X-Page-Cache: første gangMISS, deretterHIT.
Innstillingene finnes som systemparametere (website_page_cache.enabled, .backend, .ttl_hours, .max_mb_file, .max_mb_ram) og vedlikeholdes vanligvis i dashbordet. Modulen er oversatt til tysk. Avinstallering fjerner utløsere, journal og alle bufrede sider fullstendig igjen.
Tips for RAM-bufferen: RAM-budsjettet i dashbordet og størrelsen på tmpfs (/dev/shm, monteringsvalg size=) må passe til behovet. Begge deler oppgis med konkrete verdier av kontrollen «Passer det i arbeidsminnet?».
Begrensninger du bør kjenne til
- Kort forsinkelse etter endringer: Indeksen til endringsjournalet oppdateres hvert annet sekund. En endret side kan til da fortsatt leveres i gammel versjon.
- Lageravhengige tekster oppdateres via beholdningsendringer og maksimal alder.
- Estimat av plassbehov: Ekstra versjoner per prisliste eller land er ikke medregnet; planlegg litt reserve.
- Ingen erstatning for alt: Bufferen avlaster forespørsler den har lov til å betjene. Påloggede brukere, søk og skjemaer går fortsatt gjennom Odoo.
- Første kall forblir tregt: Etter en omstart av serveren (RAM) eller en global endring rendres hver side én gang på vanlig måte før den ligger i bufferen.
Ofte stilte spørsmål
Hva er sidebufferen for Odoo?
En åpen kildekode-modul (website_page_cache, Odoo 19, LGPL-3) som leverer offentlige butikk- og bloggsider til anonyme besøkende fra en buffer i stedet for å rendre dem på nytt ved hvert kall. Bufferen ligger etter valg i filer eller i arbeidsminnet.
Sperrer modulen søkemotorer eller KI-crawlere?
Nei. Søkemotorer og KI-indeksere får de samme sidene som enhver annen besøkende, bare raskere. Det finnes ingen sperre, ingen struping og ingen egen crawler-versjon.
Bufres endrede sider og oversettelser automatisk på nytt?
Ja. PostgreSQL-utløsere melder hver endring i relevante tabeller til et journal; berørte sider forkastes og rendres og lagres på nytt ved neste kall. Oversettelser er dekket fordi Odoo 19 lagrer dem i samme post.
Bør jeg velge fil eller RAM?
Vanligvis Automatisk: Modulen bruker RAM så lenge alle sider får plass, og viker ellers over til filer. Filer egner seg hvis bufferen skal overleve omstarter eller RAM er knapt; RAM er den raskeste varianten.
Hvordan ser jeg om nettstedet mitt passer i arbeidsminnet?
I dashbordet under Nettsted → Rapporter → Sidebuffer. Avsnittet «Passer det i arbeidsminnet?» teller sidene per nettsted og språk, måler sidestørrelsen og sammenligner behovet med RAM-budsjett, tmpfs-størrelse og tilgjengelig minne.
Hvor mye ekstra RAM trengs for en RAM-buffer?
Dashbordet oppgir det som en egen linje. Det regnes slik: behov = sider × sidestørrelse; med sikkerhetsreserve delt på 0,8. Fordi bufferen høyst kan bruke halvparten av tilgjengelig minne, er det dobbelte av dette det frie minnet som trengs; differansen er det ekstra RAM-et. Er bare RAM-budsjettet eller tmpfs for lite, oppgir dashbordet innstillingen med målverdi.
Kan bufferen vise noen andres innhold?
Nei. Det bufres bare for anonyme GET-kall uten søkeparametere. Påloggede brukere, handlekurver, skjemaer og søk kommer aldri fra bufferen; språk, prisliste, skatteposisjon og samtykke til informasjonskapsler er del av nøkkelen.
Hvordan slår jeg av bufferen i en nødsituasjon?
Slå av bryteren «Aktiv» i dashbordet eller sett systemparameteren website_page_cache.enabled til 0. Det gjelder i alle arbeidsprosesser senest etter 30 sekunder. En avinstallering fjerner dessuten utløsere, journal og bufrede sider.
Hvordan ser jeg om en side kom fra bufferen?
På svarheaderen X-Page-Cache: HIT betyr fra bufferen, MISS betyr nylig rendret og lagret.
Gjør modulen HTML-en mindre og komprimerer den?
Ja. Bufrede sider minimeres konservativt (kommentarer og overflødig tomrom utgår, innhold og visning forblir like) og leveres med gzip ved buffertreff; asset-pakkene komprimeres én gang og leveres fra disken. Begge deler kan slås av med parameterne website_page_cache.minify og website_page_cache.compress.
Støtte fra Biricon IT Services
Reagerer Odoo-nettstedet ditt tregt ved crawler-belastning, eller ønsker du å gjøre butikk og blogg raskere og mer synlige? Vi hjelper til med analyse av belastningen, med oppsett av sidebufferen, med dimensjonering av arbeidsminne og arbeidsprosesser og med flerspråklig søkemotoroptimalisering av Odoo-nettstedet ditt. Kildekoden til modulen finner du på GitHub.
Per: 10. november 2026. Måleverdiene stammer fra et testsystem med eksempeldata og er ingen garanti for andre installasjoner.