<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Novator articles about Odoo</title>
        <link>https://novatorapps.com/articles</link>
        <description>Novator Apps Blog</description>
        <lastBuildDate>Tue, 03 Nov 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Dashboards in Odoo: what is built in, and when you need more]]></title>
            <link>https://novatorapps.com/articles/dashboards-in-odoo</link>
            <guid>https://novatorapps.com/articles/dashboards-in-odoo</guid>
            <pubDate>Tue, 03 Nov 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The reporting tools that come with Odoo Community and Enterprise, what each one is good at, and the questions to ask before adding a dashboard app.]]></description>
            <content:encoded><![CDATA[<p>Most teams ask for "a dashboard" when what they need is one number they can trust, seen every morning. Odoo already has several tools for that. This article walks through them, from the simplest, so you can pick the lightest one that does the job.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-graph-and-pivot-views">1. Graph and pivot views<a href="https://novatorapps.com/articles/dashboards-in-odoo#1-graph-and-pivot-views" class="hash-link" aria-label="Direct link to 1. Graph and pivot views" title="Direct link to 1. Graph and pivot views" translate="no">​</a></h2>
<p>Almost every list in Odoo can switch to a <strong>graph</strong> or <strong>pivot</strong> view with the icons at the top right. Choose the measure (amount, quantity, count), group by up to several fields, and filter. Save the result as a favorite so it opens the same way next time, and share the favorite with other users if they need it.</p>
<p>This answers most one-off questions ("sales by salesperson this quarter") without any setup.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-my-dashboard">2. My Dashboard<a href="https://novatorapps.com/articles/dashboards-in-odoo#2-my-dashboard" class="hash-link" aria-label="Direct link to 2. My Dashboard" title="Direct link to 2. My Dashboard" translate="no">​</a></h2>
<p>The <strong>Dashboards</strong> module of Odoo Community adds a personal <strong>My Dashboard</strong> page. From a graph, pivot or list view, choose <strong>Add to my dashboard</strong> in the search options; the view then appears as a block on your own dashboard. It is simple and personal: each user builds their own.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-the-dashboards-app-spreadsheet-dashboards">3. The Dashboards app (spreadsheet dashboards)<a href="https://novatorapps.com/articles/dashboards-in-odoo#3-the-dashboards-app-spreadsheet-dashboards" class="hash-link" aria-label="Direct link to 3. The Dashboards app (spreadsheet dashboards)" title="Direct link to 3. The Dashboards app (spreadsheet dashboards)" translate="no">​</a></h2>
<p>The <strong>Dashboards</strong> app shows ready-made dashboards that come with the apps you install, such as Sales, Accounting or Point of Sale. In Odoo Community you can open and filter them. Building or editing dashboards in the spreadsheet editor, and inserting your own pivots and charts into them, uses Odoo Spreadsheet, which is part of Odoo Enterprise.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-reports-built-for-a-purpose">4. Reports built for a purpose<a href="https://novatorapps.com/articles/dashboards-in-odoo#4-reports-built-for-a-purpose" class="hash-link" aria-label="Direct link to 4. Reports built for a purpose" title="Direct link to 4. Reports built for a purpose" translate="no">​</a></h2>
<p>Several apps have their own analysis menus (for example <strong>Sales &gt; Reporting</strong>), with the right measures already chosen. Check them before building something new; they often already contain the number you are after.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="when-the-built-in-tools-are-not-enough">When the built-in tools are not enough<a href="https://novatorapps.com/articles/dashboards-in-odoo#when-the-built-in-tools-are-not-enough" class="hash-link" aria-label="Direct link to When the built-in tools are not enough" title="Direct link to When the built-in tools are not enough" translate="no">​</a></h2>
<p>You may need more when:</p>
<ul>
<li class=""><strong>Several sources on one screen.</strong> Sales, cash and stock side by side, for a meeting or a wall screen.</li>
<li class=""><strong>Numbers compared to a target or a previous period</strong>, with a clear up or down.</li>
<li class=""><strong>Many users who should see the same dashboard</strong>, defined once by someone else.</li>
<li class=""><strong>A dashboard that refreshes on its own</strong> on a screen in the office or the warehouse.</li>
<li class=""><strong>A summary by email</strong> for people who do not open Odoo every day.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="questions-to-ask-before-adding-a-dashboard-app">Questions to ask before adding a dashboard app<a href="https://novatorapps.com/articles/dashboards-in-odoo#questions-to-ask-before-adding-a-dashboard-app" class="hash-link" aria-label="Direct link to Questions to ask before adding a dashboard app" title="Direct link to Questions to ask before adding a dashboard app" translate="no">​</a></h2>
<ol>
<li class=""><strong>Does it respect access rights?</strong> A dashboard should show each user only the records they are allowed to see. Totals computed with elevated rights can leak information.</li>
<li class=""><strong>Does it read live data or copies?</strong> Live data is always current; copied data needs a schedule and can be out of date.</li>
<li class=""><strong>Who maintains it?</strong> Dashboards built with point-and-click settings survive upgrades better than custom code or SQL written for one version.</li>
<li class=""><strong>What does it cost to run?</strong> Heavy dashboards that refresh often on large tables can slow the database for everyone.</li>
</ol>
<p>Start with one dashboard and three to five numbers that drive a decision. It is easier to add a chart later than to get people to trust a crowded screen.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related">Related<a href="https://novatorapps.com/articles/dashboards-in-odoo#related" class="hash-link" aria-label="Direct link to Related" title="Direct link to Related" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://docs.novatorapps.com/dashboard-builder" target="_blank" rel="noopener noreferrer" class="">Dashboard Builder</a> adds KPI tiles, charts and lists from any Odoo data, computed with each user's own access rights. Pro adds drill-down, TV mode, SQL items (which read the database directly, so they are limited to the people you allow) and email digests.</li>
</ul>]]></content:encoded>
            <category>reporting</category>
            <category>dashboards</category>
        </item>
        <item>
            <title><![CDATA[Odoo user permissions explained: groups, access rights and record rules]]></title>
            <link>https://novatorapps.com/articles/odoo-user-permissions-explained</link>
            <guid>https://novatorapps.com/articles/odoo-user-permissions-explained</guid>
            <pubDate>Tue, 03 Nov 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[How Odoo decides what a user can see and do, and why hiding a menu or a field is not the same as securing it.]]></description>
            <content:encoded><![CDATA[<p>When a user can see something they should not, or cannot do something they need, the answer is almost always in one of four layers: groups, access rights, record rules and the interface itself. Knowing which layer does what saves a lot of trial and error.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="groups">Groups<a href="https://novatorapps.com/articles/odoo-user-permissions-explained#groups" class="hash-link" aria-label="Direct link to Groups" title="Direct link to Groups" translate="no">​</a></h2>
<p>A <strong>group</strong> is a role, such as <em>Sales / User: Own Documents Only</em> or <em>Inventory / Administrator</em>. Users get rights only through their groups. On the user form you pick a level for each app, and each level is a group that usually includes the levels below it. From Odoo 19 the user form organizes these groups by <em>privilege</em>, but the principle is the same.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="access-rights-which-models">Access rights: which models<a href="https://novatorapps.com/articles/odoo-user-permissions-explained#access-rights-which-models" class="hash-link" aria-label="Direct link to Access rights: which models" title="Direct link to Access rights: which models" translate="no">​</a></h2>
<p><strong>Access rights</strong> (<code>ir.model.access</code>) say whether a group may <strong>read, write, create or delete</strong> records of a model, for example sales orders. They add up: if any of the user's groups grants an operation, the user has it. If no group grants read access to a model, the user cannot open its records at all and gets an access error.</p>
<p>You find them in <strong>Settings &gt; Technical &gt; Security &gt; Access Rights</strong> (developer mode).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="record-rules-which-records">Record rules: which records<a href="https://novatorapps.com/articles/odoo-user-permissions-explained#record-rules-which-records" class="hash-link" aria-label="Direct link to Record rules: which records" title="Direct link to Record rules: which records" translate="no">​</a></h2>
<p><strong>Record rules</strong> (<code>ir.rule</code>) narrow access down to specific records with a domain, for example "only orders where I am the salesperson" or "only records of my companies". Two kinds combine differently:</p>
<ul>
<li class=""><strong>Global rules</strong> (rules without a group) apply to everyone and are combined with AND. A record must pass all of them.</li>
<li class=""><strong>Group rules</strong> apply to the user's groups and are combined with OR. A record must pass at least one of them, and also all global rules.</li>
</ul>
<p>This is why adding a user to a broader group (for example <em>All Documents</em>) widens what they see: its rule is added with OR. You find them in <strong>Settings &gt; Technical &gt; Security &gt; Record Rules</strong>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-interface-menus-buttons-and-fields">The interface: menus, buttons and fields<a href="https://novatorapps.com/articles/odoo-user-permissions-explained#the-interface-menus-buttons-and-fields" class="hash-link" aria-label="Direct link to The interface: menus, buttons and fields" title="Direct link to The interface: menus, buttons and fields" translate="no">​</a></h2>
<p>Groups can also be set on menus, buttons and fields in views. This only changes <strong>what is displayed</strong>:</p>
<ul>
<li class="">A hidden menu does not stop a user from opening the same records through a link, a related field or an export, if their access rights allow it.</li>
<li class="">A field hidden in a view can still be read through other views or the API, unless the field itself is restricted to a group in its definition.</li>
</ul>
<p>So the rule of thumb is: use access rights and record rules to <strong>secure</strong> data, and use the interface to <strong>simplify</strong> what people see. Doing only the second leaves the data reachable.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-superuser">The superuser<a href="https://novatorapps.com/articles/odoo-user-permissions-explained#the-superuser" class="hash-link" aria-label="Direct link to The superuser" title="Direct link to The superuser" translate="no">​</a></h2>
<p>Odoo has an internal superuser that bypasses access rights and record rules. It is used by the system itself and by the <em>become superuser</em> option in developer mode. The regular <em>Administrator</em> user is not the superuser: record rules still apply to it, which is why an administrator may not see records of a company that is not selected.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="multi-company">Multi-company<a href="https://novatorapps.com/articles/odoo-user-permissions-explained#multi-company" class="hash-link" aria-label="Direct link to Multi-company" title="Direct link to Multi-company" translate="no">​</a></h2>
<p>In a multi-company database, most models have a global record rule that limits records to the companies the user has selected in the company switcher. A user who "cannot find" a record often only needs to select the right company.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="checking-a-change-safely">Checking a change safely<a href="https://novatorapps.com/articles/odoo-user-permissions-explained#checking-a-change-safely" class="hash-link" aria-label="Direct link to Checking a change safely" title="Direct link to Checking a change safely" translate="no">​</a></h2>
<ol>
<li class="">Make the change on a test user that has exactly the groups of the real user.</li>
<li class="">Sign in as that user in a private browser window and try the actual task: open the menu, open a record, export, print.</li>
<li class="">Try the paths around the interface too, such as a direct link to a record, to confirm the data is protected and not only hidden.</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related">Related<a href="https://novatorapps.com/articles/odoo-user-permissions-explained#related" class="hash-link" aria-label="Direct link to Related" title="Direct link to Related" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://docs.novatorapps.com/access-manager" target="_blank" rel="noopener noreferrer" class="">Access Manager</a> builds profiles that hide menus, set read-only users and turn off developer mode; Pro adds rules for fields, buttons, records, chatter and filters.</li>
</ul>]]></content:encoded>
            <category>security</category>
            <category>permissions</category>
            <category>administration</category>
        </item>
        <item>
            <title><![CDATA[Connecting a weighing scale to Odoo Point of Sale]]></title>
            <link>https://novatorapps.com/articles/weighing-scales-in-odoo-point-of-sale</link>
            <guid>https://novatorapps.com/articles/weighing-scales-in-odoo-point-of-sale</guid>
            <pubDate>Tue, 03 Nov 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The ways a scale can feed weights into Odoo Point of Sale, what each needs, and what to check before buying a scale.]]></description>
            <content:encoded><![CDATA[<p>Selling by weight means the cashier puts the item on the scale and the price follows from the weight. For that, the weight has to get from the scale into the Point of Sale. There are three common ways to do it, and the right one depends on your Odoo version, your scale and your counter.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="products-sold-by-weight">Products sold by weight<a href="https://novatorapps.com/articles/weighing-scales-in-odoo-point-of-sale#products-sold-by-weight" class="hash-link" aria-label="Direct link to Products sold by weight" title="Direct link to Products sold by weight" translate="no">​</a></h2>
<p>Whatever the connection, start with the products. A product sold by weight has a unit of measure in weight (kg or lb) and, on the product's <strong>Point of Sale</strong> tab, the option <strong>To Weigh</strong>. Its sales price is the price per unit of weight. When the cashier adds it and a scale is connected, Point of Sale asks the scale for the weight.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="option-1-an-odoo-iot-system">Option 1: an Odoo IoT system<a href="https://novatorapps.com/articles/weighing-scales-in-odoo-point-of-sale#option-1-an-odoo-iot-system" class="hash-link" aria-label="Direct link to Option 1: an Odoo IoT system" title="Direct link to Option 1: an Odoo IoT system" translate="no">​</a></h2>
<p>Odoo's standard way to connect hardware is an <strong>IoT Box</strong> (or, for some devices, a virtual IoT system on a Windows computer). The scale is plugged into the IoT system, which talks to Odoo over the network. Odoo's documentation states that an IoT subscription is required for production use. Check Odoo's list of compatible IoT devices for your scale model before you buy.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="option-2-the-browser-web-serial">Option 2: the browser (Web Serial)<a href="https://novatorapps.com/articles/weighing-scales-in-odoo-point-of-sale#option-2-the-browser-web-serial" class="hash-link" aria-label="Direct link to Option 2: the browser (Web Serial)" title="Direct link to Option 2: the browser (Web Serial)" translate="no">​</a></h2>
<p>Chrome, Edge and Opera on a computer can talk to a USB or serial device directly through the <strong>Web Serial</strong> standard, with the user's permission. No box is needed: the scale is plugged into the computer that runs Point of Sale. A few things to know:</p>
<ul>
<li class="">The page must be opened over <strong>HTTPS</strong>, which is normal for Odoo.sh and for any properly set up server.</li>
<li class="">The first time, the browser asks which port to use, and remembers the choice.</li>
<li class="">Web Serial is not available in Safari or Firefox, or on phones and most tablets.</li>
<li class=""><strong>Odoo 20</strong> includes this for scales that use the Toledo protocol, so on Odoo 20 with such a scale nothing extra is needed. Other scales send their weight in their own text format and need an app that understands it.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="option-3-weight-in-the-barcode">Option 3: weight in the barcode<a href="https://novatorapps.com/articles/weighing-scales-in-odoo-point-of-sale#option-3-weight-in-the-barcode" class="hash-link" aria-label="Direct link to Option 3: weight in the barcode" title="Direct link to Option 3: weight in the barcode" translate="no">​</a></h2>
<p>Many counter scales print a <strong>label</strong> with a barcode that contains the weight or the price. The cashier scans the label and Odoo reads the weight from the barcode, so the scale is never connected to Odoo at all. This is set up in the barcode nomenclature that Point of Sale uses (its settings show which one), with a rule that matches the label format of your scale. With developer mode on, nomenclatures are under <strong>Inventory &gt; Configuration &gt; Products &gt; Barcode Nomenclatures</strong>. It suits shops where goods are weighed and packed before they reach the till.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-to-check-before-buying-a-scale">What to check before buying a scale<a href="https://novatorapps.com/articles/weighing-scales-in-odoo-point-of-sale#what-to-check-before-buying-a-scale" class="hash-link" aria-label="Direct link to What to check before buying a scale" title="Direct link to What to check before buying a scale" translate="no">​</a></h2>
<ol>
<li class=""><strong>Connection:</strong> USB or RS-232 serial. USB scales usually appear as a serial port; some use a different USB mode and are not readable as a serial device.</li>
<li class=""><strong>Output format:</strong> whether the scale sends its weight continuously or answers a command, and in which text format. The manual or the dealer can tell you.</li>
<li class=""><strong>Port settings:</strong> speed (baud rate), data bits, parity and stop bits. Note them; you will need them.</li>
<li class=""><strong>Legal for trade:</strong> in many countries a scale used to sell by weight must be approved and verified by the authority for weights and measures. Check the rules where you sell.</li>
<li class=""><strong>Test it</strong> with your actual computer and browser before you rely on it at a busy counter, and keep a way to type a weight by hand if the scale is not available.</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related">Related<a href="https://novatorapps.com/articles/weighing-scales-in-odoo-point-of-sale#related" class="hash-link" aria-label="Direct link to Related" title="Direct link to Related" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://docs.novatorapps.com/pos-scale" target="_blank" rel="noopener noreferrer" class="">POS Scale Integration</a> reads text-output scales in the browser with your own port settings, on Odoo 13 to 20, without an IoT Box. It is free and open source.</li>
</ul>]]></content:encoded>
            <category>point-of-sale</category>
            <category>hardware</category>
            <category>scales</category>
        </item>
        <item>
            <title><![CDATA[Where does the storage of an Odoo database go?]]></title>
            <link>https://novatorapps.com/articles/where-odoo-storage-goes</link>
            <guid>https://novatorapps.com/articles/where-odoo-storage-goes</guid>
            <pubDate>Tue, 03 Nov 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[How Odoo stores files and data, how to measure what takes the space, and how to reduce it safely.]]></description>
            <content:encoded><![CDATA[<p>An Odoo database is two things: a PostgreSQL database with the records, and a <strong>filestore</strong> with the files. When a hosting plan or an Odoo.sh project says the database is too big, it is usually the filestore. This article explains where the space goes and how to measure it before you change anything.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="records-and-files-are-stored-separately">Records and files are stored separately<a href="https://novatorapps.com/articles/where-odoo-storage-goes#records-and-files-are-stored-separately" class="hash-link" aria-label="Direct link to Records and files are stored separately" title="Direct link to Records and files are stored separately" translate="no">​</a></h2>
<p>Every file in Odoo is an <strong>attachment</strong> (the <code>ir.attachment</code> model): email attachments, PDF reports, product images, documents uploaded to a chatter, and also files Odoo generates for itself. By default the attachment record is in the database and the file content is in the filestore, a folder on disk at <code>&lt;data directory&gt;/filestore/&lt;database name&gt;</code>. The system parameter <code>ir_attachment.location</code> decides this; its default value is <code>file</code>.</p>
<p>Two details matter when you look at sizes:</p>
<ul>
<li class=""><strong>Identical files are stored once.</strong> The file name in the filestore is derived from the content, so the same PDF attached to ten records takes the space of one file.</li>
<li class=""><strong>Deleting an attachment does not free the space immediately.</strong> Odoo marks the file and removes it later, during the scheduled clean-up, once nothing refers to it any more.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="measure-before-you-delete">Measure before you delete<a href="https://novatorapps.com/articles/where-odoo-storage-goes#measure-before-you-delete" class="hash-link" aria-label="Direct link to Measure before you delete" title="Direct link to Measure before you delete" translate="no">​</a></h2>
<p>If you can run SQL on the database (your own server, or the shell of an Odoo.sh build), three queries give a clear picture.</p>
<p>Size of the PostgreSQL database:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">SELECT</span><span class="token plain"> pg_size_pretty</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">pg_database_size</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">current_database</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>Biggest tables, including their indexes:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">SELECT</span><span class="token plain"> relname</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> pg_size_pretty</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">pg_total_relation_size</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">relid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">FROM</span><span class="token plain"> pg_catalog</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">pg_statio_user_tables</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">ORDER</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">BY</span><span class="token plain"> pg_total_relation_size</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">relid</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">DESC</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">LIMIT</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">15</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>Files by the kind of record they belong to:</p>
<div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">SELECT</span><span class="token plain"> res_model</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">count</span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">*</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> pg_size_pretty</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">sum</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file_size</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">FROM</span><span class="token plain"> ir_attachment</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">GROUP</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">BY</span><span class="token plain"> res_model</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">ORDER</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">BY</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sum</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file_size</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">DESC</span><span class="token plain"> NULLS </span><span class="token keyword" style="color:#00009f">LAST</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">LIMIT</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">20</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>The last query reads the <code>file_size</code> stored on each attachment, so it measures the files without touching the disk.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-usual-suspects">The usual suspects<a href="https://novatorapps.com/articles/where-odoo-storage-goes#the-usual-suspects" class="hash-link" aria-label="Direct link to The usual suspects" title="Direct link to The usual suspects" translate="no">​</a></h2>
<ul>
<li class=""><strong>Email and chat attachments.</strong> Every incoming email with attachments adds files to the record it is linked to, and to the discussion it belongs to.</li>
<li class=""><strong>Saved PDF reports.</strong> Some reports, invoices for example, are kept as an attachment the first time they are printed, so the document stays identical later.</li>
<li class=""><strong>Images.</strong> An image field keeps the original and several resized copies.</li>
<li class=""><strong>Message history.</strong> Chatter messages and field tracking (<code>mail_message</code>, <code>mail_tracking_value</code>) grow with every change on every tracked record. This is database space, not filestore.</li>
<li class=""><strong>Generated files.</strong> Odoo also stores its own compiled web assets as attachments. They are rebuilt when needed and are not something to clean by hand.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="reduce-it-safely">Reduce it safely<a href="https://novatorapps.com/articles/where-odoo-storage-goes#reduce-it-safely" class="hash-link" aria-label="Direct link to Reduce it safely" title="Direct link to Reduce it safely" translate="no">​</a></h2>
<ol>
<li class=""><strong>Never delete files from the filestore folder directly.</strong> The attachment record would point to a missing file and the document would no longer open. Always delete through Odoo, which also handles files shared by several records.</li>
<li class=""><strong>Back up first</strong>, and test a clean-up on a copy of the database.</li>
<li class=""><strong>Decide what may go.</strong> Old email attachments on closed records are often safe to remove; posted invoices and their PDFs usually have to be kept for legal reasons. Check the rules that apply to your company.</li>
<li class=""><strong>Move instead of delete.</strong> Files you must keep but rarely open can live in cheaper storage, such as Amazon S3, Cloudflare R2 or Google Drive, while Odoo keeps the record and opens the file from there.</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-it-matters-on-odoosh">Why it matters on Odoo.sh<a href="https://novatorapps.com/articles/where-odoo-storage-goes#why-it-matters-on-odoosh" class="hash-link" aria-label="Direct link to Why it matters on Odoo.sh" title="Direct link to Why it matters on Odoo.sh" translate="no">​</a></h2>
<p>On Odoo.sh the storage used by a project is part of what you pay for, and the database is copied for every staging build and every backup. A large filestore makes backups, restores and staging builds slower as well as more expensive. Check the current limits of your plan on odoo.sh.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related">Related<a href="https://novatorapps.com/articles/where-odoo-storage-goes#related" class="hash-link" aria-label="Direct link to Related" title="Direct link to Related" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://docs.novatorapps.com/storage-manager/analyzer" target="_blank" rel="noopener noreferrer" class="">Storage Analyzer</a> shows the same breakdown inside Odoo, with growth over time, without SQL.</li>
<li class=""><a href="https://docs.novatorapps.com/storage-manager/offload" target="_blank" rel="noopener noreferrer" class="">Storage Manager</a> moves old files to S3, R2 or Google Drive with rules.</li>
</ul>]]></content:encoded>
            <category>storage</category>
            <category>odoo-sh</category>
            <category>administration</category>
        </item>
    </channel>
</rss>