Inaccurate stock levels can create problems that go far beyond inventory management. Your PrestaShop store might accept orders for unavailable products, miss sales opportunities, or disappoint customers who expect items to be ready for delivery.
Keeping your online inventory aligned with actual stock is essential for smooth operations and customer trust. Let’s explore why stock discrepancies happen and how to prevent them.
The Quiet Morning You Sell What You Don't Have
PrestaShop stock sync problems rarely announce themselves. They wait until a Tuesday morning when three orders land for the same blue jacket.
The product page said "3 in stock", so three people bought it. One was sold in your physical shop on Saturday. One was reserved on a marketplace listing that never wrote back. The third went out as a replacement for a damaged return that was never logged. Now you refund two customers, absorb the marketplace penalty, and stand in the stockroom wondering who dropped the ball. Nobody did.
PrestaShop rarely lies by accident; it faithfully reports whatever conflicting sources you fed it. Drift accumulates from unsynced ERPs, duplicate order-state decrements, unreturned reservations and overlapping cron jobs.
Editing quantities in the back office resets the clock but not the mechanism that drifted. Within a week, the same gap reappears in the same product category. The fix is diagnostic: find which write path is desynchronised, then close it.
Why Does PrestaShop Show A Different Stock Number to My Warehouse?
Because PrestaShop is answering two different questions at once. Stock Available is a promise, Physical Stock is a fact, and the gap between them is where trust in your catalogue quietly erodes.
In the back office, Quantities shows both side by side. Stock Available is what the front office will sell right now: physical quantity minus everything claimed by live carts and unshipped orders. Physical Stock is the raw count you typed in or imported from a supplier feed.
When a shopper starts an order, PrestaShop does not touch Physical Stock immediately. It records the claim in ps_cart_product and, once the order is validated, in the reservation rows tied to that order. Physical quantity drops only in step with the order state you configured.
Order State Hooks Control the Timing
Every order status has a setting for whether it counts as a valid order and whether it should deduct or restore stock. If "Delivered" and "Payment accepted" are both flagged to decrement, your warehouse count falls twice for one sale. If none are flagged, Physical Stock never moves while Stock Available keeps falling as reservations build.
- Reservations created at checkout explain stock that exists but cannot be sold.
- Shop-level checks reveal how easily the figures drift apart.
- Order state flags decide when the physical count finally catches up.
A module from the PrestaShop Plugins catalogue at FME Modules, an official PrestaShop Partner, typically exists to reconcile these two views rather than replace them. Before you buy anything, open the Quantities screen for one drifting product and compare the numbers. That tells you whether you have a reservation backlog or a state-mapping error.
The Six Usual Suspects Behind PrestaShop Stock Drift
Drift almost always traces back to a small set of repeating patterns. Match your store against the symptoms below; most merchants recognise two or three immediately.
1. ERP and Accounting Connectors That Write Once A Night
Symptom: stock looks correct first thing in the morning, then drifts further out of step as the day goes on.
A nightly sync from an ERP or accounting package writes a single snapshot in the early hours. Every order placed after that point exists in PrestaShop but not in the source system until the next window. By mid-afternoon, the two have quietly separated.
2. Webservice API Calls That Update Physical Stock But Skip Reservations
Symptom: the warehouse total is right, but checkouts oversell the last few units.
The PrestaShop Webservice exposes stock_availables, and plenty of integrations write straight to it. What they miss is the reservation logic that Physical Stock and Stock Available depend on. Two fields move, one doesn't, and the gap fills with orders.
3. Duplicate Order-state Transitions Decrementing Twice
Symptom: a popular product drains faster than its order list can explain.
Each state in Orders > Statuses carries its own stock behaviour checkbox. If a payment or order-management module triggers a stock-decrementing state twice (a retry, a duplicate callback, an overlapping webhook), one sale removes two units.
4. Cancelled and Refunded Orders that Never Restore Quantity
Symptom: cancelled lines sit in the back office while the shelf count never recovers.
Restoring stock on cancellation depends entirely on how the cancelled state is configured. Where the "set stock to zero" or "allow stock reduction" settings were never revisited, the return never happens. Do it a dozen times a week and the shortfall compounds.
5. Shared-catalogue Stock Across A Multistore Setup
Symptom: one shop's sales deplete another shop's availability, often with no warning.
In Advanced Parameters > Multistore, quantities can be shared between shops that sell the same catalogue. That is fine if the warehouse is genuinely one pool and wrong if each shop draws from separate stock. PrestaShop faithfully reports whatever scope you configured, including the one you outgrew.
6. Overlapping Cron Jobs Racing Each Other
Symptom: drift appears in bursts, usually after a slow sync or a traffic spike.
Two cron tasks touching the same products at once can interleave their writes. The second reads a stale value, writes it back, and silently undoes the first. Nothing logs an error, which is why nobody spots it for weeks.
When several of these run together, the fix rarely sits in one place. Modules that centralise order, supplier or stock handling, such as those built by FME, an official PrestaShop Partner, can reduce the number of independent writers touching the same rows. Diagnosis, though, still comes first.
Reading PrestaShop's Stock Tables Like A Detective
When two screens disagree, stop trusting screens and open the database. PrestaShop keeps sellable stock in ps_stock_available: one row per product or combination and per shop, and that row is what the front office reads. Your warehouse system tracks physical units. The gap between them is the drift you are chasing.
Query ps_stock_available for the SKU that misbehaved and read the columns side by side. quantity is what the store believes it can sell. reserved_quantity holds units tied up by carts or unpaid orders, depending on your settings.
- Quantity plus reserved_quantity should equal your expected physical count, allowing for the reservation behaviour you configured.
- A quantity below zero while the product still sells points to orders that reduced stock without a matching receipt.
- A reserved_quantity that keeps climbing without new carts suggests abandoned orders that were never cleaned up.
Then trace one SKU's history through order states. PrestaShop moves stock when an order reaches the states you configured to deduct inventory, not when the customer clicks buy. Line up the order timestamps against the state changes. A cancellation that never returned the unit, or a manually edited order, shows as a step change.
Finally, time-box the drift. Find the last moment Physical Stock and Stock Available agreed, then work forward through cron windows, module imports and manual edits. Drift almost always has a start time, and finding it turns a mystery into a suspect. Comparing the drift across multiple shops often isolates the culprit to a single context faster than any log.
To run this audit on a schedule rather than by hand, a PrestaShop stock management module from FME Modules can keep the sync visible instead of silent.
What Happens To Customers and Marketplaces While Drift Goes Unfixed?
Drift does not stay inside the back office. The moment PrestaShop passes a wrong quantity to a customer or a marketplace, the cost compounds in places you cannot edit later: order screens, feedback scores, chargeback files and search results.
Picture a listing showing three units left that were really sold on eBay two days ago. The order lands, the picker finds an empty shelf, and you cancel. Consider what follows the cancel button:
- A marketplace metrics hit, where a cancelled order counts against you even though the stock figure was the culprit.
- A refund processed under pressure, often with a goodwill discount attached.
- A chargeback if the refund is late, adding dispute paperwork and a fee you never budgeted.
- A review mentioning the cancellation, sitting on the listing for every future shopper.
- A product page briefly showing "out of stock" on a healthy line, which search engines and AI shopping answers both learn to trust less.
That last point hurts more than most owners expect. PrestaShop sets a product's availability status from the quantity it holds, so a drifted figure can flip a healthy listing to unavailable for hours. Google and marketplace feeds read that flag as a signal. Repeatedly flipping a page in and out of stock teaches them your catalogue is unreliable, and recovery is slower than the outage itself.
None of these costs appear on the invoice. They sit in refund volume, feedback ratings and lost organic visibility, adding up across every cron window the drift survives.
Fixing the Sync, Not the Symptom: A Permanent Repair Plan
Most stores treat stock drift as a bug to patch. It is really an architecture problem: several systems write to the same quantity with no agreed owner. The permanent fix is to decide, once, which system is master of truth for each number, then make everything else read from it or write through a controlled path.
Step 1: Name One Source of Truth Per Stock Type
Pick where Physical Stock is authoritative (usually the warehouse management system or your ERP) and where Stock Available is derived. Everything else, including PrestaShop, becomes a consumer. If you sell in multiple locations, decide whether stock is global or per shop before wiring anything up.
- Warehouse or ERP owns Physical Stock.
- PrestaShop owns reservations and the sellable Stock Available figure, computed from the master.
- Marketplaces and POS read-only, or report sales back as events, never as absolute quantities.
Step 2: Make Every Sync Idempotent
An idempotent operation can run twice without changing the result. Absolute quantity pushes ("set to 42") are idempotent; relative deltas ("subtract 1") are not, which is why retried cron jobs cause drift. Where you must send movements, attach a unique reference per order line so a repeat run is ignored. Test by running the same import twice and confirming the numbers do not move.
Step 3: Reserve on API Writes
If orders arrive through the PrestaShop Webservice, add reservation handling so an incoming order immediately reduces Stock Available, then reconciles with Physical Stock at fulfilment. Without this, the gap between order placement and warehouse pick is where overselling happens.
Step 4: Scope Stock Per Shop
In a multi-store setup, confirm each shop has the correct stock scope (shared or separate). Getting this wrong makes one shop's sales silently drain another's availability, and the drift looks random until you map it to store view.
Step 5: Give Crons Guaranteed Gaps
Schedule each stock job with a clear window and a lock so two runs cannot overlap. A cron that starts before the previous one finishes is the single most common cause of double decrements. A dedicated PrestaShop module for stock synchronisation can manage queues and locks more reliably than ad-hoc scripts.
The repair is not a setting you switch on; it is a decision about who is allowed to write stock, and what happens when they do it twice.
How Do I Stop The Drift Coming Back Next Month?
Drift returns unless something compares the two numbers on a fixed rhythm. You can run all of this from the back office and a spreadsheet, no new module required.
Treat stock reconciliation like a smoke alarm, not a spring clean: small and frequent beats big and rare.
The Daily and Quarterly Checklist
- Morning Drift Check. Pull Physical Stock and Stock Available for your top-selling SKUs and compare the gap against your tolerance band. Flag anything that has drifted further than yesterday.
- Set Alert Thresholds. Decide a band per product type (for example, flag any SKU whose available figure moves beyond a set percentage of its physical figure overnight). Anything inside the band can wait; anything outside gets investigated that day.
- Watch the Cron Windows. Note when your stock imports and order-status updates run, then check the drift log straight after. Drift clustered around a specific window points at that job, not at random shrinkage.
- Quarterly Full Audit. Reconcile every active SKU end to end, including warehouse tables and marketplace feeds, rather than only the fast movers.
Log each flagged SKU with the date, the two figures and the cause you found. Over a couple of months, the log shows whether you are fixing real problems or mopping the same leak.
When to Rebuild Versus When To Reconnect
Not every drift deserves the same response. The decision hinges on one thing: how many systems are writing stock, and whether you can name the one that wins.
If the mismatch traces cleanly to a single connector, the connector is your culprit. One module, one web service account, or one CSV import is mangling the number, and the rest of your architecture is sound. Repair that link, remove the competing job, and verify against a known order. Most stores land here.
A rebuild is the right call when several write paths all claim authority at once. Think of a store running a POS connector, an ERP feed, and a manual back-office edit in the same week. No repair fixes conflicting ownership, because there is no single truth to repair back to. Restructure so exactly one system owns Physical Stock and every other path reads from it or writes through it.
Before inviting another integration into your back office, ask the one question that prevents most of this: will this path write stock, or only read it? If you cannot answer that before switching it on, you are not adding a feature; you are adding a future drift event.
Why PrestaShop Stock Levels Drift in the First Place
PrestaShop is a faithful reporter, not a decision maker. It shows whatever number the last source to write to it said was true. When two sources disagree, the shop displays the one that wrote most recently, and nobody gets told a conflict occurred.
Your ERP, your warehouse scanner, a supplier feed and a fulfilment integration can each write to the same product, and PrestaShop has no built-in referee to stop them overwriting each other. PrestaShop rarely lies by accident; it accurately repeats a number another system got wrong.
The Real Cost of Invisible Inventory Drift
Inventory distortion is expensive, and it compounds quietly. Retailers worldwide lose an estimated $1.7 trillion a year to inventory distortion- the combined cost of out-of-stocks and overstocks.
Drift shows up as a slow leak. A product that should have four units left shows two, so you turn away a sale you could have filled. Another shows twelve when the shelf is empty, so you promise delivery, then apologise and refund. Both erode trust with the same customer.
A significant share of stock records in most retail operations are simply wrong, which in PrestaShop terms means a notable slice of your catalogue you cannot fully trust when a customer clicks Add to cart.
Where the Drift Hides Inside PrestaShop
Drift is not one bug in one place. It moves through a handful of PrestaShop concepts, and each one can disagree with the others without throwing an error.
Order States Change the Number After the Sale
Every status transition can move stock. An order moving from Awaiting payment to Payment accepted reduces available stock. A cancellation should return it. A refund or manual state change may or may not, depending on how the shop is configured.
A sync that runs before the cancellation finishes processing reads the old figure, then writes that stale value back over the correct one. The cancelled order is back in stock on paper but was never physically returned to the shelf.
The Cron Window Race
Most scheduled syncs run on cron. If a warehouse system exports at 02:00 and your PrestaShop import runs at 02:05, any sale between export and import is overwritten. Orders placed in that short window can vanish from stock.
The same applies to two integrations running close together, such as a supplier feed and a marketplace connector. Whichever finishes last wins, and the winner is not necessarily the source with the most accurate data.
How Drift Compounds Across Sources
Drift is easy to diagnose with one data source. With three, it becomes a detective problem. Here is how the damage accumulates.
- A manual edit by a staff member correcting a single product is silently overwritten by the next automated sync.
- A supplier feed zeroes out a product that is temporarily out of their stock, but your warehouse still holds units, so you stop selling what you own.
- A marketplace returns a stock figure for a shared SKU that counts its own pending orders, so your PrestaShop copy inherits reservations that never existed on your side.
- A returns process re-adds a unit that was refunded but not physically inspected, creating phantom inventory that keeps selling.
None of these trigger an alert. Each one repositions Stock Available slightly further from reality, and the next sync locks the drift in place.
Why Overselling Hurts More Than It Used to
The commercial risk is higher now because customers walk away. Across ecommerce, about 70% of shopping carts are abandoned before checkout is completed, so a lost sale after an oversell is a lost customer, not just a lost order. They rarely come back to a shop that promised what it could not ship.
Understocking costs you the same way in reverse. A product that shows "out of stock" when you hold five units in a back room is a payment you never took. Small, repeated errors across hundreds of SKUs add up to a measurable revenue gap by quarter end.
Practical Steps to Close the Gap
You cannot stop drift entirely when multiple systems write to the same records. You can put guardrails in place that catch it before a customer does. You can also find PrestaShop modules built for stock and order sync on the FME Modules PrestaShop store, which is run by an official PrestaShop Partner.
Choose One Owner Per Field
Decide whether Physical Stock is owned by your warehouse system or your PrestaShop back office. Set the other source to read-only. When both sides can write to the same field, drift is guaranteed eventually, no matter how carefully each job is configured.
Schedule Syncs Outside Order Peaks
Run your cron jobs when order flow is slow, and stagger them so two jobs never write to stock within minutes of each other. Then add a reconciliation report to catch anything the automated job missed.
Review Stock, Not Just Orders
Weekly, compare a random sample of PrestaShop stock levels against your physical count. This is where an hour of checking beats a month of refunds.
Conclusion
PrestaShop stock drift is not a glitch to patch but a symptom of too many writers and no agreed owner. Fix the architecture, make every sync idempotent, and check the numbers daily. Done that way, the Tuesday morning of three blue jackets and two refunds becomes a rare story instead of a monthly routine.
FAQ
Why Does PrestaShop Show A Different Stock Number to My Warehouse?
Because it tracks two figures: Physical Stock (the raw count) and Stock Available (physical count minus reservations). The front office sells against Stock Available, so when reservations and physical counts diverge, the product page and the shelf disagree.
What Causes PrestaShop Stock to Drift?
The usual culprits are nightly ERP connectors, Webservice calls that skip reservations, duplicate order-state decrements, cancellations that never restore quantity, shared multistore stock, and overlapping cron jobs. Most stores find two or three running at once.
How Do I Find Which Product is Drifting?
Query ps_stock_available for the SKU, compare quantity and reserved_quantity, then trace the order states and cron windows back to the last moment the two figures agreed.