and runs during HTML parse, but hubspotutk is set by js.hs-analytics.net, measured loading at ~834ms. On a first visit the cookie does not exist yet, so a single read returns nothing and the visitor gets no external ID at all — and a first visit is exactly what an ad click is. So poll briefly until HubSpot sets it. The SDK loads lazily (~4.5s) and replays a queue, so an init queued a second or two in still lands before any events are transmitted. */ (function attachExternalId() { var attempts = 0; var MAX_ATTEMPTS = 40; /* 40 x 200ms = 8s, then give up quietly */ var timer = null; function tryAttach() { var raw = getExternalId(); if (!raw) { if (++attempts >= MAX_ATTEMPTS && timer) clearInterval(timer); return; } if (timer) clearInterval(timer); sha256Hex(raw).then(function (hash) { oaiq("init", { user: { external_id_sha256: hash } }); }).catch(function () {}); } tryAttach(); /* returning visitor: immediate */ if (!getExternalId()) timer = setInterval(tryAttach, 200); })(); /* --------------------------------------------------------------------------- 2. Load the SDK off the critical path Whichever comes first: the main thread going idle after load, or the first sign of real user intent. No preconnect on purpose — a TLS handshake during LCP for a script we deliberately deferred is a net loss. Measured on clickpost.ai: load event 3614ms, SDK fetched 4508ms. ------------------------------------------------------------------------ */ var loaded = false; var INTENT = ["pointerdown", "keydown", "scroll"]; function loadSdk() { if (loaded) return; loaded = true; INTENT.forEach(function (t) { removeEventListener(t, loadSdk, { passive: true }); }); var s = document.createElement("script"); s.src = SDK; s.async = true; s.fetchPriority = "low"; document.head.appendChild(s); } INTENT.forEach(function (t) { addEventListener(t, loadSdk, { passive: true, once: true }); }); addEventListener("load", function () { window.requestIdleCallback ? requestIdleCallback(loadSdk, { timeout: 2500 }) : setTimeout(loadSdk, 1500); }, { once: true }); /* --------------------------------------------------------------------------- 3. Conversion id sha256(lowercase(email) + "|" + formId + "|" + ISO-hour), first 20 hex, "lead_" prefix. - email lowercased/trimmed so casing does not fork the id - formId keeps two different forms in the same hour from colliding - the hour bucket is only the server's fallback; the id computed here is sent to the relay verbatim, so the two paths cannot disagree even when a submit straddles an hour boundary Ads Manager's own sample omits event_id. We send it so the pixel event and the relay event collapse into one conversion instead of counting twice. ------------------------------------------------------------------------ */ function buildEventId(email, formId) { var seed = [ String(email || "").trim().toLowerCase(), String(formId || ""), new Date().toISOString().slice(0, 13) ].join("|"); return crypto.subtle.digest("SHA-256", new TextEncoder().encode(seed)).then(function (buf) { var hex = Array.prototype.map.call(new Uint8Array(buf), function (b) { return b.toString(16).padStart(2, "0"); }).join(""); return "lead_" + hex.slice(0, 20); }); } /* Guards a re-fire from the history.pushState that book-a-demo-core.js runs after submit, and from back-navigation onto the same state. */ function firedOnce(id) { try { if (sessionStorage.getItem("oaiq_" + id)) return true; sessionStorage.setItem("oaiq_" + id, "1"); return false; } catch (e) { return false; /* private mode / blocked storage: fire rather than lose it */ } } /* Path 2. keepalive lets the request finish even if the page navigates away. Failures are swallowed deliberately: a reporting call must never surface an error to someone who just submitted a form. The relay hashes the email server-side into user.emails_sha256 and adds the caller's IP and user agent, so this event carries the same match signals the pixel gets for free. */ function sendToRelay(email, formId, eventType, eventId) { try { var payload = { token: RELAY_TOKEN, email: email, form_id: formId || "", event_type: eventType, event_id: eventId, /* verbatim, so both paths always match */ source_url: location.href }; var oppref = getOppref(); if (oppref) payload.oppref = oppref; var externalId = getExternalId(); if (externalId) payload.external_id = externalId; fetch(RELAY_URL, { method: "POST", keepalive: true, headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload) }).catch(function () {}); } catch (e) {} } /* Capture the email while the form is still on the page. onFormSubmitted does not reliably carry submissionValues, and by then the form may be removed. */ var lastEmail = ""; document.addEventListener("submit", function (e) { var f = e.target; if (!f || !f.querySelector) return; var i = f.querySelector('input[name="email"], input[type="email"]'); if (i && i.value) lastEmail = i.value; }, true); /* Every HubSpot form on the site reports through this one message event, so no module or theme JS needs editing to add coverage. */ window.addEventListener("message", function (e) { var d = e.data; if (!d || d.type !== "hsFormCallback" || d.eventName !== "onFormSubmitted") return; var email = (d.data && d.data.submissionValues && d.data.submissionValues.email) || lastEmail; if (!email) return; /* without an email there is no stable id to dedupe on */ var eventType = EVENT_BY_FORM[d.id] || EVENT_DEFAULT; buildEventId(email, d.id).then(function (id) { if (firedOnce(id)) return; oaiq("measure", eventType, { type: DATA_TYPE }, { event_id: id }); /* path 1 */ sendToRelay(email, d.id, eventType, id); /* path 2 */ }); }); })();

91ÊÓÆµ

See where your logistics stands on automation Start assessment

Home > Blog >

What is Physical Inventory? How to and Tips in 2024

What is Physical Inventory? How to and Tips in 2024

Devaraj Mahantesh
By Devaraj Mahantesh

Ready to ship smarter? Talk to our logistics experts.

Trusted by 600+ brands

In this blog

    Introduction

    Almost every house has a list of groceries taped on the fridge. If something is out of stock, a person puts it on the list. The same workflow is followed in a warehouse that follows physical inventory protocol. The audit process is used to gauge the inventory levels within the warehouse. 

    In this article, we will explore the many intricacies and complexities surrounding the physical inventory.

    This exploration will allow you to understand what is the ideal workflow for your warehouse and how to improve your order fulfillment efficiency.

    What is Physical Inventory?

    Physical Inventory is exactly as it sounds. It is the physical count of the inventory in stock. It also typically refers to the method of auditing the inventory levels inside a warehouse against the levels in the system.

    It is typically intended to address discrepancies and bugs, ensuring real-time inventory tracking.

     

    These discrepancies have to be addressed on a priority basis. Otherwise, it may lead to duplicate SKUs or fake stock outs on your website, resulting in a loss of revenue.

    This audit process also provides key data insights at the ground level. With these insights, you can streamline inventory acquisition and management.

    You can even forecast sales figures and use them to plan and strategize other aspects of your e-commerce business.

    3 Methods of Auditing Physical Inventory

    Before we take a deep dive into the concept of physical inventory for e-commerce businesses, let’s understand the classification of the processes. Here are three of the most popular ways to audit physical inventory.

    1. Manual Counting

    When the staff goes around and manually accounts for each SKU, the process is known as Manual Counting.

    Mostly done on a very small scale, this method is the most primitive form of inventory audit. 

    Most stores tend to avoid it due to the high probability of irregularities in the numbers. However, it is one of the cheapest ways due to its barebones nature. 

    2. Electronic Counting

    Under this method, the stores use a POS system and a barcode scanner to account for the inventory levels.

    The barcode will have information about the individual SKUs. Employees scan these barcodes to enter information about their presence in their system. 

    Using can help businesses identify inventory patterns, understand stock movement, and make more informed operational decisions.

    The POS system tracks the outgoing inventory, and this number is then compared against the existing stock.

    The advantage of this method is its high accuracy. However, this auditing method can be quite time-consuming and requires considerable manpower as well. 

    3. Cycle Counting

    In the cycle counting method, the staff audits a part of the inventory to gauge the existing levels. This method is typically used by retailers that want to implement the physical audit without implementing the manual process.

    Under this process, the products are segregated into different categories. Items are audited as per their priority in the business supply chain, and portions are used to account for the entire stock.

    This process is typically faster than the traditional methods and is used by larger warehouses to speed up the audit process.

    5 Best Practices To Follow While Counting Physical Inventory

    Physical inventory may be a tedious and long process, but it is still an effective way to track your inventory levels.

    However, since the process is manual, you may often run into issues. Here are five practices to avoid those errors and establish a near-flawless process.

    1. Consider Seasonal Fluctuations

    Most e-commerce tend to have a specific time of year when they get a huge influx of orders. While physically auditing the inventory, these seasonal fluctuations tend to throw a wrench in the numbers.

    The increased movement of inventory leads to an increase in the discrepancy in the number.

    Hence, you have to account for these seasonal fluctuations beforehand. Another good tip is to focus on either the high-value or high-in-demand.

    This allows you to focus your efforts on high-impact areas and ensure that the irregularities do not have a negative impact on the bottom line.

    2. Install Inventory Control and Management Measures

    Manual control over the inventory is limited in its functionality. If you want to exercise better control, you will have to install an inventory management system.

    This system will act as a mediator during the order processing and record every move in the inventory.

    This visibility allows you to track these orders and enables much better control over the inventory. Along with this, the real-time sync allows you to speed up your physical inventory audit process.

    It improves the accuracy of the process as well, as the system accounts for every movement in the warehouse.

    3. Compute Inventory Turnover Ratio

    The inventory turnover ratio is the frequency of the inventory replenishment required over a period of time. The ratio allows you to understand the overall movement of inventory through the warehouse.

    The number is compared with the levels from the physical audit to point out any irregularities.

    The ratio is also useful to understand the changing trends in sales. You can determine your inventory life cycle with the number.

    Therefore, you can have more holistic control over the physical inventory in your warehouse. Additionally, the turnover ratio also enables easy inventory procurement. 

    4. Automate the Inventory Audit Process

    As long as the processes are manual, the probability of errors and irregularities is always prominent. To iron out these irregularities, incorporate automation features in the auditing process.

    You can automate aspects of the counting process using technology like barcodes and RFID.

    Along with this, you can implement an inventory management system that allows you to track your levels in real time over multiple locations.

    This will help in an efficient expansion and enable better control over your entire fulfillment supply chain.

    5. Include Inventory Forecasting for Procurement

    We have all heard, ‘Everything in proportion.’ This statement holds its weight for inventory management as well.

    You have to ensure the right levels of inventory in your warehouse at all times. For this to be possible, you will have to use the physical inventory audits to understand the turnaround time.

    With the turnaround time and analysis of past data, you can almost accurately forecast the required levels of inventory. You can then study the trends and figure out the optimal procurement plan.

    3 Important KPIs Connected to Physical Inventory

    1. Inventory Turnover Ratio

    As explained, the inventory turnover ratio is the frequency of inventory replenishment. To be exact, it is the total cost of goods divided by the average inventory.

    For a physical inventory, the turnover ratio can help find irregularities without the actual audit.

    2. Stock-to-sales Ratio

    The stock-to-sales ratio is the ratio of the average stock value to the net sales value. It is to understand the level of inventory you are carrying as opposed to the selling capabilities.

    You can reduce the inventory carrying costs with the help of this number and maintain a more realistic inventory number. This will also help in reducing the inventory carrying cost.

    3. Sell-through Rate

    The sell-through rate denotes the inventory consumption rate over a particular time period. The sell-through rate is crucial to understand the accuracy of the physical inventory audits. The number is also vital in determining the procurement schedule.

    What is the Alternative to Physical Inventory?

    Perpetual inventory is the ideal alternative to physical inventory. Simply put, perpetual inventory is a method where the systems maintain the inventory levels in real-time without requiring physical confirmation.

    These systems have become more and more popular as e-commerce companies have started using multiple fulfillment centers for faster deliveries.

    The main benefit of physical inventory is accuracy. The process almost completely eliminates human intervention by syncing the numbers in real time. This real-time sync is maintained with the help of POS systems and scanners.

    This type of inventory also comes in handy when paired with a Material Requirement Planning (MRP) system. The pairing comes in handy to improve your inventory forecasting and streamline your procurement process.

    Conclusion

    Irrespective of the virtual nature of the modern-day ecosystem, inventory, at the core, will have some physical value. Therefore, physical inventory audits might be the right start an e-commerce business needs.

    Though it may be a time-consuming process, it enables a business to verify the integrity of its inventory and warehouse management systems.

    FAQS

    1. What are the main components of inventory management costs?

    The inventory management costs include capital costs, the cost to carry the inventory, and warehouse operational costs.

    It is likely to vary according to the nature of the goods and the size of the warehouse.

    2. Why is physical inventory usually audited?

    Physical audits are usually carried out to match the current inventory levels with the physical stock. It can also be used to understand the irregularities and glitches in the POS and Order Management systems.

    The Logistics Automation Platform for E-commerce

    Momentum Leader - G2 Users Most Likely To Recommend - G2 Best Results Mid-Market - G2
    . window.disableHubSpotCookieBanner = true; function killNative() { var n = document.getElementById("hs-eu-cookie-confirmation"); if (n && n.parentNode) { n.parentNode.removeChild(n); return true; } return false; } killNative(); if (window.MutationObserver) { var mo = new MutationObserver(function () { killNative(); }); mo.observe(document.documentElement, { childList: true, subtree: true }); setTimeout(function () { mo.disconnect(); }, 15000); } var COOKIE = "cp_cookie_consent"; var EU = ["at","be","bg","hr","cy","cz","dk","ee","fi","fr","de","gr","hu","ie","it","lv","lt","lu","mt","nl","pl","pt","ro","sk","si","es","se","gb","uk","is","li","no","ch"]; function readCookie(nm) { var m = document.cookie.match(new RegExp("(?:^|; )" + nm + "=([^;]*)")); return m ? decodeURIComponent(m[1]) : null; } function writeCookie(nm, val, days) { var d = new Date(); d.setTime(d.getTime() + (days * 864e5)); document.cookie = nm + "=" + encodeURIComponent(val) + ";expires=" + d.toUTCString() + ";path=/;SameSite=Lax" + (location.protocol === "https:" ? ";Secure" : ""); } function stored() { var raw = readCookie(COOKIE); if (!raw) return null; try { var o = JSON.parse(raw); if (typeof o.analytics === "boolean") return o; } catch (e) {} return null; } function apply(state, revoke) { window._hsp = window._hsp || []; window._hsp.push(["setHubSpotConsent", { analytics: !!state.analytics, advertisement: !!state.advertisement, functionality: !!state.functionality }]); if (revoke && !state.analytics && !state.advertisement && !state.functionality) { window._hsp.push(["revokeCookieConsent"]); } window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: "cp_cookie_consent", cp_consent_analytics: !!state.analytics, cp_consent_advertisement: !!state.advertisement, cp_consent_functionality: !!state.functionality }); document.documentElement.setAttribute("data-cp-consent", "set"); } function inScope(banner) { if (banner.getAttribute("data-scope") !== "eu_only") return true; var geo = (document.body.getAttribute("data-geo_location") || "").toLowerCase(); if (!geo) return true; return EU.indexOf(geo) !== -1; } function init(banner) { var days = parseInt(banner.getAttribute("data-days"), 10) || 180; var prefs = banner.querySelector("[data-cpcb-prefs]"); var compact = banner.querySelector('[data-cpcb-actions="compact"]'); var expanded = banner.querySelector('[data-cpcb-actions="expanded"]'); var toggles = banner.querySelectorAll("[data-cpcb-toggle]"); function show() { banner.hidden = false; requestAnimationFrame(function () { banner.classList.add("is-visible"); }); } function hide() { banner.classList.remove("is-visible"); setTimeout(function () { banner.hidden = true; }, 300); } function collapse() { if (!prefs) return; prefs.hidden = true; if (expanded) expanded.hidden = true; if (compact) compact.hidden = false; } function expand() { if (!prefs) return; prefs.hidden = false; if (compact) compact.hidden = true; if (expanded) expanded.hidden = false; } function paint(state) { Array.prototype.forEach.call(toggles, function (t) { var key = t.getAttribute("data-cpcb-toggle"); if (key === "necessary") { t.setAttribute("aria-checked", "true"); return; } t.setAttribute("aria-checked", state[key] ? "true" : "false"); }); } function fromToggles() { var state = { analytics: false, advertisement: false, functionality: false }; Array.prototype.forEach.call(toggles, function (t) { var key = t.getAttribute("data-cpcb-toggle"); if (key in state) state[key] = t.getAttribute("aria-checked") === "true"; }); return state; } function commit(state, revoke) { writeCookie(COOKIE, JSON.stringify({ analytics: !!state.analytics, advertisement: !!state.advertisement, functionality: !!state.functionality, v: 1, ts: Date.now() }), days); apply(state, revoke); hide(); } Array.prototype.forEach.call(toggles, function (t) { if (t.disabled) return; t.addEventListener("click", function () { t.setAttribute("aria-checked", t.getAttribute("aria-checked") === "true" ? "false" : "true"); }); }); banner.addEventListener("click", function (e) { if (!e.target || !e.target.closest) return; var btn = e.target.closest("[data-cpcb-action]"); if (!btn) return; var action = btn.getAttribute("data-cpcb-action"); if (action === "customise") { expand(); return; } if (action === "accept") { commit({ analytics: true, advertisement: true, functionality: true }, false); return; } if (action === "reject") { commit({ analytics: false, advertisement: false, functionality: false }, true); return; } if (action === "save") { commit(fromToggles(), true); return; } }); var existing = stored(); if (existing) { apply(existing, false); paint(existing); collapse(); } else if (!inScope(banner)) { // Out of the consent-required region: implied consent, banner never shown. commitSilently(); } else { collapse(); show(); } function commitSilently() { var all = { analytics: true, advertisement: true, functionality: true }; writeCookie(COOKIE, JSON.stringify({ analytics: true, advertisement: true, functionality: true, v: 1, ts: Date.now(), implied: true }), days); apply(all, false); } // Public re-open hook for a footer "Cookie settings" link. window.cpCookieBanner = window.cpCookieBanner || {}; window.cpCookieBanner.open = function () { var s = stored() || { analytics: false, advertisement: false, functionality: false }; paint(s); expand(); show(); }; } function boot() { var banners = document.querySelectorAll("[data-cpcb]"); if (!banners.length) return; init(banners[0]); document.addEventListener("click", function (e) { if (!e.target || !e.target.closest) return; var trigger = e.target.closest("[data-cp-cookie-settings]"); if (!trigger) return; e.preventDefault(); if (window.cpCookieBanner && window.cpCookieBanner.open) window.cpCookieBanner.open(); }); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", boot); } else { boot(); } })();