Free operator sheet · Stays in your browser

Daypart Traffic
Map.

Day by hour grid — covers, sales, labor hours. Reveals where you are paying for staff that has nothing to serve.

Pack: Conversions & Reservations Cadence: Monthly Private — runs in your browser

Fill it in

Daypart Traffic Map

Type your numbers — the math runs in your browser. Print it, save it as a CSV, or save it to your Workshop.

Period
Daypart × hour grid (covers per shift)
Hour Mon Tue Wed Thu Fri Sat Sun Avg covers Labor hrs Sales/$ labor
11a–12p
12p–1p
1p–2p
2p–3p
3p–4p
4p–5p
5p–6p
6p–7p
7p–8p
8p–9p
9p–10p
Avg covers = mean of the 7 day cells. Sales/$ labor = (avg covers × your avg check) / (labor hours × loaded rate). Above 3 is healthy; below 1 is a cut candidate.
Reference
Slowest hour (cut candidate)
Best sales-per-labor-dollar hour

Fill in covers + labor hours. The map will name the hour to cut and the hour you might be under-staffing. Cut by trend, not one bad day.

+ bestEff.toFixed(1) + ' sales / $1 labor)') : '—'; var c = document.querySelector('[data-output="callout"]'); if (!c) return; if (slowest == null) { c.textContent = 'Fill in covers + labor hours. The map will name the hour to cut and the hour you might be under-staffing. Cut by trend, not one bad day.'; } else if (bestEff > 4 && slowestVal < 4) { c.textContent = 'Big spread between best and slowest hours. The slowest hour is the cut candidate; the best hour is where to add a server before turning tables faster becomes hard.'; } else { c.textContent = 'Slowest hour: ' + slowest + '. Best hour: ' + best + '. Pull next month and compare — three months of the same shape is signal.'; } } function collect() { var f = document.getElementById('sheet-fields'); if (!f) return [['Field', 'Value']]; var rows = [ ['Field', 'Value'], ['Period', f.period.value || ''], ['Labor rate', f.labor_rate.value || ''], ['Avg check', f.avg_check.value || ''], [], ['Hour', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun', 'Avg', 'Labor hrs', 'Sales/$ labor'], ]; for (var i = 1; i <= 11; i++) { rows.push([ HOURS[i - 1], f['h' + i + '_mon'].value || '', f['h' + i + '_tue'].value || '', f['h' + i + '_wed'].value || '', f['h' + i + '_thu'].value || '', f['h' + i + '_fri'].value || '', f['h' + i + '_sat'].value || '', f['h' + i + '_sun'].value || '', (f['h' + i + '_avg'].value || '').replace(/^—$/, ''), f['h' + i + '_lab'].value || '', (f['h' + i + '_eff'].value || '').replace(/^—$/, ''), ]); } rows.push([]); rows.push(['Slowest hour', document.querySelector('[data-output="slowest"]').textContent]); rows.push(['Best $/labor', document.querySelector('[data-output="best"]').textContent]); return rows; } if (window.SheetPage) window.SheetPage.register({ slug: 'daypart-traffic-map', collect: collect, recalc: recalc }); })();

Keyboard: ⌘P print · ⌘S download CSV · ⌘↵ save to Workshop

When to use it

Pull this sheet out when —

  • Monthly — pull POS reports for covers, sales, and labor hours by hour-of-day.
  • Before a schedule rewrite. The map names the cuts that don't hurt service.
  • When considering a new daypart (lunch launch, Sunday brunch, late-night) — the heatmap shows whether the demand is there.
Common mistakes

What operators get wrong

  • Mixing dine-in and to-go in one cell. The labor cost of each daypart differs by channel; combining hides the truth.
  • Cutting labor on the slowest hour without checking the trend. One slow Wednesday at 4pm is noise; eight slow Wednesdays is signal.
  • Forgetting opening labor (prep cooks, BOH setup) — they don't show in covers but they are real.
Pairs with

The tools, terms, and articles this sheet sits next to.

Tools

Glossary

Reading

  • None yet.

Free, no signup. Your numbers never leave this page.