AI & Data

Coffee Shop Sales Patterns by Day of the Week

Mark, founder of Parly·July 24, 2026·6 min read

Saturday is busy, Monday is not, and that barely tells you what to order

It is 4:30 on a Friday and you are at the reach-in with your phone out, about to send the dairy order before the 4:50 cutoff. You know Saturday is your biggest day. So you take a rough sense of Saturday, pad it, and send. That habit, sizing the whole order off your busiest day, is how you end up with three extra cartons of oat milk sitting there Tuesday and no whole milk left by Sunday afternoon.

The busiest-day fact is true. It is also close to useless for the order you are about to place. Knowing Saturday beats Monday tells you how many people walked in. It does not tell you which shelf they emptied. And the shelf is the only thing a supplier order is actually about.

Every ranking article on this keyword hands you the same shape: here is the busy day, here is the slow day, staff up for the rush. That is a staffing answer wearing an ordering hat. Finding your real peak hour genuinely changes who you put on the schedule Saturday morning. It does almost nothing for how much matcha to order Thursday, because a busy day and a heavy day on one ingredient are not the same day.

Same transaction count, different shelves

Picture two weekdays that ring up the same number of tickets. Say 200 each, to keep it simple (these counts are illustrative, not measured).

Your Monday 200 is a commuter morning. Drip coffee, cortados, oat flat whites, people in and out before 9. Whole milk and beans take the hit; oat milk moves but not hard; matcha barely moves.

Your Saturday 200, at the same ticket count, is a different room. Iced matcha with oat, cold brew, bigger sizes, a slower crowd that customizes. Now matcha and oat milk are carrying the day and whole milk is coasting.

Two identical transaction counts, two completely different depletion patterns. If you had treated Monday as "0.6 times Saturday" and scaled every item down by the same factor, you would have under-ordered whole milk for the commuters and over-ordered matcha for a day nobody drinks it. A single busy-day multiplier makes you over-order one shelf and under-order another at the same time, which is the worst of both mistakes in one order.

This is why the mix matters more than the volume. A cafe's real weekday signal is not how much money came in. It is which drinks rotated through, because the drinks are what map to what left your shelves.

Disaggregate usage by ingredient, not sales by day

The unit you actually want is not "Saturday revenue." It is a per-ingredient, per-weekday depletion curve: how much oat milk a Tuesday burns, how much matcha a Saturday burns, each item on its own line, each weekday on its own column.

You do not have to guess at it. The data is already in your Square, one layer down from the number you usually read. Every ticket carries the drink, the size, and the modifiers. Map each ticket to its recipe and you turn a sale into ingredients. Forty-seven iced matcha lattes with oat stop being a revenue line and become 94g of matcha, 564 oz of oat milk, and 47 cups (that translation is straight recipe math, run it on your own pours). Do that across 28 days of sales, then sort the result by weekday instead of totaling it, and the curve draws itself: one line per ingredient, seven points across the week.

That 28-day, modifier-accurate, day-of-week split is exactly how the forecasting engine reads your week before it suggests an order. The point worth stealing whether or not you run any tool: the useful weekday number is per ingredient, computed from the mix, not one revenue multiplier applied to everything.

Match each order to the days it covers

Once usage is split by weekday, an order stops being "a week of stuff" and becomes "the specific days between this delivery and the next one."

Your dairy supplier delivers Monday through Saturday, no Sunday. So the Friday order has to cover Saturday and Sunday, two of your heaviest, most oat-and-matcha-skewed days back to back. The Monday order might only have to cover Wednesday. Same supplier, wildly different math, and the difference is entirely in which weekdays sit inside each gap.

Add up the per-weekday usage for exactly the days a delivery has to span, and the order quantity falls out of the arithmetic. No pad, because you are not hedging against a week-shaped average anymore, you are covering named days you can see. This is also why the cutoff itself is load-bearing: miss Friday's 4:50 and the next dairy delivery is Monday, so a two-day gap becomes a three-day gap that lands on your busiest weekend.

Turn the weekday curve into a per-weekday par

The curve is worth more than one order. It is the raw material for a par level that respects the week.

A flat par ("keep six cartons of oat milk on hand") ignores that Saturday eats through far more oat milk than Tuesday does. A weekday-aware par asks a better question: enough to cover the specific days until the next delivery, sized to those days' actual usage. Friday's target is higher than Wednesday's, on purpose, because Friday has to carry the weekend. Par levels built this way stop being a single number you second-guess and start being a small schedule the order writes itself against.

This is the whole reason to do the split. Not to admire a chart, but to replace a gut number with a computed one at the exact moment you are placing an order. Ordering is the decision that costs you the most when you get it wrong, and the weekday curve is what makes it arithmetic instead of a guess.

Where the weekday pattern lies to you

Two cautions, because a curve read carelessly is its own trap.

First, the curve is only as honest as the recipe map underneath it. We once watched our own computed Whole Milk usage read 0.70 bottles a day when the real rate was 9.716, a 14x miss (our own operating record). No weekday model caused that and no smarter model would have caught it. A set of Square modifiers had been deleted, so the milk swaps stopped subtracting, and the mix the curve was built from was quietly wrong. If a weekday number looks impossible, check the modifier mapping before you trust the shape. The pattern is downstream of the mapping, always.

Second, the weekday curve describes a normal week, and not every week is normal. A holiday, a street fair two doors down, a matcha promotion you are running Thursday: those are days the average has never seen. The curve should propose the order; you still place it, with the one thing the data cannot hold, which is that you know what is happening in the neighborhood this Saturday and the last 28 days do not.

Build one ingredient's curve this week and you will feel the difference immediately. Pick the item that hurts most when you get it wrong, usually oat milk or your matcha. Pull 28 days of its sales-mapped usage, sort by weekday, and read the seven numbers. Counting the item to check the curve is cheap now, a recent full count of 58 items took about 8.5 minutes from a phone (our own record). One ingredient, seven numbers, and the next order you send is sized to the days it has to cover instead of the day that felt busy.