Why online shops stall after the first busy month
Taking the order is the part that works. Everything after it — stock that stops agreeing, a hundred orders each needing a different action, returns, receipts, the question of what actually sold this year — is where a shop either has a system behind it or does not.
The shop is the easy ten per cent
A storefront does one thing, and modern platforms do it very well: show products, take money, record that an order happened. Launch week feels like success, because for that week the shop *is* the business.
Then the second month arrives. The orders keep coming, and it turns out that taking the order was never the hard part. The hard part is everything the order sets in motion — and almost none of that lives in the storefront.
A storefront is built to take an order. It was never built to run what happens next. Those are two different products, and only one of them gets bought on launch day.
What arrives with the hundredth order
At five orders a day, a person holds the whole business in their head. At a hundred, the same person is holding a list they cannot read, because a list of orders is not a list of *work*.
Look at what a hundred orders on one ordinary day actually contains:
- Sixty need nothing. Pick, pack, send.
- Twelve need confirmation before anything can be picked — a variant, a quantity, an unusual address.
- Nine are waiting on the customer to confirm a colour, and the customer has not replied since yesterday.
- Eight need a tracking number sent, and three of those already generated it — somebody just has not sent it.
- Five have an address that will fail delivery and needs a phone call.
- Four are returns from last week, each at a different stage: requested, in transit, received, refunded.
- Two are partial: one line in stock, one not.
A storefront shows you a hundred rows and a status column. What the business needs is seven queues, each holding the orders that need the *same* action, ordered by which one is running out of time. The difference between those two views is the difference between a team that works and a team that works hard.
This is also where quiet losses start. Nothing is broken. The order that needed a phone call simply sits there for four days, and then it is a refund, a bad review, and a customer who does not come back.
Where the stock number goes wrong
Ask a growing shop how much of an item it has, and you will often get three answers.
The shop says one number, because it subtracts on payment. The warehouse says another, because a box was damaged and nobody told the shop. The person on the floor says a third, because they are looking at the shelf.
The reason is not carelessness. It is that "how many do we have" is four separate questions that a single number cannot answer:
- On hand — physically on the shelf right now.
- Reserved — on hand, but already promised to a paid order.
- Available — on hand minus reserved. This is the only number a shop should ever sell against.
- On order — coming from a supplier, with a date attached.
A storefront usually tracks one number. When that number is the only one, two things follow. You oversell, because the item was on the shelf but already promised to somebody else. And you over-buy, because nothing in the system knows that thirty units are already on their way.
Fixing this is not a bigger spreadsheet. It is a stock ledger: an append-only table where every movement — sale, return, damage, delivery, correction, transfer — is one row carrying a quantity, a reason and a timestamp. Nothing is ever updated in place. The current level is the sum of the rows, and when a count comes out wrong the ledger tells you precisely which movement did it. An overwritten number can never tell you that; it has already forgotten.
Two implementation details decide whether this actually holds under load. The first is the reservation, which needs a lifetime: stock is reserved when a basket enters checkout and released on a timer if payment never completes, or one abandoned cart holds a size 42 hostage for a week. The second is the race, which is the same one that breaks stock counts everywhere — two customers check availability at the same instant, both see one unit, both are allowed to pay. Checking and reserving has to be a single atomic step. In a relational database that is a conditional write — UPDATE ... SET reserved = reserved + 1 WHERE available >= 1, and if it updates zero rows, the item is gone — or the row taken with SELECT ... FOR UPDATE first. Reading availability and then writing it as two statements will oversell, and it will do it on your busiest day, because that is when the two requests finally overlap.
Summing a ledger does get slower as it grows. The usual answer is a periodic snapshot — a nightly row per item holding the balance to that point — so the live query sums the snapshot plus today, not four years of history.
Returns: the process nothing models
Returns are the clearest example of work that lives entirely outside the storefront.
One return is six state changes: requested, approved, in transit, received, inspected, resolved. "Resolved" branches four ways — restock, repair, write off, replace — and each branch does something different to stock and something different to money.
The thing worth building here is not a status field but an explicit state machine: the list of states, and the list of transitions that are legal between them. Write it down and two problems disappear at once. Nobody can move a return from "requested" to "refunded" without it passing through "received", because the transition does not exist. And because every transition is stored with its timestamp and the person who made it, you get the reporting for free — average time from received to refunded, how many sit in inspection for more than three days, which supplier's items come back most. None of that needs a report to be written. It is a query over rows the process was already producing.
Run that by hand across twenty returns a week and things start to disappear. Items come back and never re-enter stock, so you are out of something you actually have. Refunds get issued twice. A customer is told "we received it" by one person and "we did not" by another, because there was no single place to look.
None of that requires a big mistake. It only requires that the process exists in messages and memory rather than in a system.
The three questions that become phone calls
Almost all customer contact in a shop is three questions:
- Where is my order?
- Can you send me the receipt?
- What did I buy last time?
Every one of them has an exact answer already sitting in your data. If the customer cannot reach that answer themselves, each one becomes a phone call, and each phone call takes a person away from the seven queues above.
The fix is unglamorous and enormous: an account area where a customer can see their own orders, tracking, invoices and history. It removes the most common contact reason entirely — not by answering faster, but by removing the need to ask.
One customer, three places
The same person buys from your site, messages you on Instagram, and phones about a delivery. In most shops that is three unconnected records, so nobody can answer "has this customer had a problem before?" — which is the only question that matters when they are annoyed.
A customer record that holds identity, every order across every channel, every conversation, every return and any note a colleague left is what turns a transaction into a relationship. That is all CRM means here. Not a separate product to buy — a table your own systems write to, so whoever picks up the phone already knows who they are talking to.
Getting there is an identity problem, and it is more mechanical than it sounds. Normalise phone numbers to a single international format on the way in, so 0912..., +98912... and the one with spaces in it are the same string. Lowercase and trim emails. Then match on those, and when two records turn out to be one person, merge rather than delete: keep one surviving id, move the orders to it, and leave the old id in an alias table pointing at the survivor. Do it that way and an old link, an old invoice or an old support thread still resolves years later. Delete the loser instead and you spend the next year finding orphaned rows.
It is also what makes the business worth more than its stock. A list of people who bought from you, with what they bought and when, is an asset. A list of orders is a receipt.
The assistant that actually knows the answer
An assistant that answers customers is genuinely useful in a shop — but only when it is connected to the same systems as everyone else. The distinction matters:
An assistant with no access to your data can only describe policies vaguely and guess about availability. Customers spot that in one exchange.
An assistant grounded in your own systems can say that this item has four available, that this order shipped on Tuesday with this tracking number, and that returns are accepted within this window because that is what your written policy says.
Those are two different mechanisms and it is worth knowing which is which, because they fail differently. Policy questions are answered by retrieval: the policy documents are split into passages, indexed by meaning rather than keyword, and the passages closest to the question are put in front of the model as the material it must answer from. Live questions — stock, order status, tracking — are not retrieval at all. They are ordinary authenticated API calls that the model is allowed to make, returning the same number the warehouse screen shows, because it came from the same table.
Three rules keep it honest. Answer only from what was retrieved or returned, and cite it, so a wrong answer can be traced to a wrong source rather than argued about. When retrieval comes back with nothing above the relevance threshold, say so instead of generating something plausible — a confident wrong answer about a refund policy costs more than no answer. And enforce permissions on the tool calls, not in the prompt: an instruction not to reveal other customers' orders is a suggestion, whereas a query scoped to the signed-in customer is a guarantee.
The same knowledge base serves the people on your team, which is the part most shops do not expect. New staff ask it the questions they would otherwise ask a colleague.
Two limits worth stating plainly. It must cite what it is drawing on, so an answer can be checked instead of trusted. And it should never be the only path to a human — an assistant that cannot be escaped is a worse experience than no assistant at all.
The knowledge that leaves on a Thursday
In most shops that have grown past ten orders a day, the real operating manual is one experienced person. They know which supplier is slow, which customers pay late, which courier to use for fragile items, and the exception that applies to that one product.
When that person is on holiday, everything takes twice as long. When they leave, some of it does not come back.
A system that encodes the process — the stages an order passes through, the rule about which courier, the checklist for a return — turns training from an apprenticeship into a week. Not because people stop mattering, but because the routine parts stop depending on memory, and what is left to teach is judgement.
The January problem
Every year the same thing happens. The tax deadline arrives, and somebody spends three weeks assembling from exports and bank statements what the business already knew all along:
- What was sold, by product, by month.
- What was returned, and what that cost.
- Cost of goods against revenue — the actual margin, not the one on the price list.
- Stock on hand at the year end, valued.
This work is only painful because the data was never kept in a shape that could answer it. When every sale, return and stock movement is a ledger entry with a date and a reason, the annual report is a query, not a project.
One field decides whether margin is answerable at all: the cost of each item at the moment it was sold, written onto the order line rather than looked up later. Supplier prices move. Read today's cost against last spring's sales and the margin you calculate is fiction. Capture it at the time and both valuation methods stay open to you — first-in-first-out, which follows the actual batches, or weighted average, which is simpler and usually enough. Either is defensible. Neither is reconstructable from a price list eleven months later. The same data answers the questions an owner should be asking monthly rather than annually: which products actually make money, which stock has not moved in six months, which customers are repeat buyers and which came once during a promotion.
Those are not year-end questions. They are buying decisions, and most shops make them from memory because the numbers take too long to assemble.
What the engine underneath actually is
None of the above needs an exotic architecture. It needs one system of record with four things in it:
- One customer identity, whatever channel the order came through.
- One stock ledger, where every movement is an entry and the count is derived.
- One order lifecycle — the real stages your business has, including the awkward ones, each with the action it is waiting on and who owns it.
- One history, kept forever, because every report you will ever want is a question about the past.
The storefront then becomes what it always was: one channel writing into that system. So does Instagram, so does the phone order, so does the walk-in. The website stops being the business and becomes the shop window — which is what it is.
You do not need all of it on day one
This is not an argument for stopping everything and building a platform. It is an argument for building in the order that hurts least:
- Order lifecycle and action queues first. This is where a busy day currently goes wrong, and it is the cheapest thing on the list.
- The stock ledger next — as soon as overselling has happened twice.
- Customer accounts — self-service tracking, invoices and history, which removes most incoming contact.
- Returns as a real process, once returns are frequent enough to be a category rather than an exception.
- One customer record across channels, when people start arriving from more than one place.
- Reporting, which by this point is mostly free — the data is already in the right shape.
- The assistant last, because it can only be as good as the systems it reads from.
Each stage is useful the day it ships and makes the next one cheaper. None of them requires throwing away the storefront.
Where this is the wrong answer
A shop selling forty orders a month does not need any of this, and building it would be an expensive way to avoid a spreadsheet. The threshold is not a revenue figure — it is the day the same question starts getting different answers depending on who you ask, and the day the routine work stops fitting in one person's head.
Before that day, a storefront and a careful person is the correct architecture. After it, every extra week is paid for in oversold items, lost returns and customers who did not come back — and none of that shows up as a line anybody reads.