Imagine a shop with one remaining unit of a popular item. At 10:02 a customer in the shop picks it up and takes it to the counter. At 10:03 someone browsing the online store clicks "buy" on the same item and pays. Both transactions looked fine to whoever was in front of them. Now the shop has one item and two happy customers, which means one unhappy one.
This is overselling. It is not bad luck. It is what happens when two places sell from stock and neither knows what the other just did.
Why it happens
There are usually two causes, and they often appear together.
Two sources of truth. The shop keeps stock in one system and the online store keeps it in another. Each has its own number for the same product. Even if someone updates one from the other, there is always a gap between "something changed here" and "the other system knows".
Delays. If the two are synchronised every fifteen minutes, or every night, there is a window where both can sell the last unit. The window is short for slow items and painful for popular ones, and it gets worse exactly when you most want sales to work, such as during a promotion.
A third, quieter cause is that nobody decided what the stock number means. Is it what is on the shelf? What is on the shelf minus what is in a customer's online basket? What is on the shelf minus orders that have not yet been picked? Without an answer, every system invents its own.
Reservations: separating "on the shelf" from "available to sell"
The most useful idea in this area is that these are two different numbers.
- On hand is what physically exists.
- Available is what you can still promise to someone: on hand, minus everything already promised but not yet shipped.
When an online order is placed, the system does not wait for the item to leave the building to reduce what is available. It reserves one unit immediately. The unit is still on the shelf, but it belongs to that order. The same applies when a shop assistant sets one aside for a customer. Later, when the order is picked and shipped, on hand goes down and the reservation closes.
If an online order is never paid, or checkout is abandoned, the reservation expires and the unit becomes available again. Deciding how long a reservation lasts is a business rule, not a technical detail: too short and customers lose the item during checkout, too long and you block stock nobody will buy.
Two ways to keep systems in step
At a plain level, there are two approaches, and many businesses end up with a mix.
Periodic sync means a job runs every few minutes and copies stock numbers from one system to the other. It is simple to build and easy to understand. Its weakness is exactly the gap between runs. For items with plenty of stock, that gap is harmless. For items with one or two units left, it is where overselling lives.
Event-based sync means every change, such as a sale, a return or a transfer, is sent to the other system as soon as it happens. The window becomes seconds rather than minutes. It takes more care to build, because the system must cope with messages that arrive late, twice or out of order, and with the other side being offline for a while. A well-built version keeps a queue of changes and retries until they are delivered.
A common compromise is events for the moment a sale happens, plus a periodic check that compares both sides and flags any difference. The events keep things fast; the check catches whatever slipped through.
Another protection is a safety buffer: showing online one unit fewer than you have, or hiding the last unit of fast-selling items, so the shop always has something to sell to a walk-in. It costs a few lost online sales and avoids many apologies.
One source of truth, many sales channels
A design that avoids much of the trouble is to decide that one system holds the stock numbers, and everything else, the shop's till, the online store, a marketplace, asks that system or tells it, never keeps its own separate truth. Then synchronisation stops being a copy between equals and becomes a question to one authority.
Custom integration or a plugin?
For a standard online store connected to a standard till, a ready-made plugin or connector is often a reasonable place to start. It is quick, relatively cheap, and maintained by someone else. The trade-offs show up later. You are bound to how the plugin works: how often it syncs, whether it supports reservations, whether it handles several stock locations, bundles or returns the way you do. When something goes wrong, you are depending on the plugin's author to fix it.
A custom integration usually costs more to start and more to maintain, but it can follow your rules: your reservation time, your buffers, your locations, your way of handling returns. It makes sense when overselling is already costing you customers, when your stock logic does not fit the standard connectors, or when several channels must share the same stock.
A practical first step
Take your five fastest-selling products and check what happens when one has a single unit left. Where does each system get its number, how old can it be, and what happens if a shop sale and an online order arrive in the same minute? Write down the answers. They tell you whether you have a small gap that a safety buffer can cover, or a structural one that needs a single source of truth.