Free operator sheet · Stays in your browser

Reservation & No-Show
Log.

Booking source, party size, deposit yes or no, showed or no-show or late-cancel, revenue lost. Names what each empty seat actually cost.

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

Fill it in

Reservation & No-Show Log

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

Worked example 32-seat tasting-menu spot, Fri+Sat only See what a Tuesday-morning fill-in looks like
Reservations logged (two-week period)48
Late-cancels (≤24h)3
No-shows5
Average check$145
Of the 5 no-shows, deposit-protected0
No-show rate10.4% · red
Estimated lost revenue$725
No-show rate among deposit-holders0%

Every single no-show came from a non-deposit reservation. The pattern decides the next move: a two-week test on deposit-required for Fri/Sat parties of 4 or more. The window table at 8pm is what hurts — it's the one nobody walks in for at the last minute.

Composite-typical numbers — not a real shop. Use the rhythm, not the figures.

Period
Reservations this period
Date Source Party size Deposit? Outcome Lost $ Notes
Lost $ = party size × average per-cover spend, automatically computed for no-shows and late-cancels.
No-show rate 0%
Late-cancel rate 0%
Lost revenue this period $0
Highest-no-show source

Log every reservation. The fix is by SOURCE — if one platform's no-show rate runs 3× another's, the deposit policy goes there first.

+ Math.round(v).toLocaleString('en-US'); } function fmtPct(v) { return Math.round(v * 10) / 10 + '%'; } function recalc() { var f = document.getElementById('sheet-fields'); if (!f) return; var avg = n(f.avg_check.value); var total = 0, ns = 0, lc = 0; var lost = 0; var sourceNs = {}; for (var i = 1; i <= 8; i++) { var out = f['r' + i + '_out'].value; var party = n(f['r' + i + '_party'].value); if (!out || out === '—' || !party) { f['r' + i + '_lost'].value = '—'; continue; } total++; var src = f['r' + i + '_src'].value; var lostThisRow = 0; if (out === 'No-show') { ns++; lostThisRow = party * avg; sourceNs[src] = (sourceNs[src] || 0) + 1; } else if (out.indexOf('Late') === 0) { lc++; lostThisRow = party * avg * 0.5; } f['r' + i + '_lost'].value = lostThisRow > 0 ? fmt$(lostThisRow) : '—'; lost += lostThisRow; } var nsRate = total > 0 ? (ns / total) * 100 : 0; var lcRate = total > 0 ? (lc / total) * 100 : 0; var nsEl = document.querySelector('[data-output="ns_rate"]'); nsEl.textContent = fmtPct(nsRate); // D9 — band via centralized benchmarks. if (window.Bench && window.Bench.evaluate) { var bn = window.Bench.evaluate('noshow_rate_pct', nsRate); if (bn && bn.band) nsEl.dataset.band = bn.band; } else { nsEl.dataset.band = nsRate < 5 ? 'good' : (nsRate < 10 ? 'warn' : 'bad'); } var lcEl = document.querySelector('[data-output="lc_rate"]'); lcEl.textContent = fmtPct(lcRate); lcEl.dataset.band = lcRate < 8 ? 'good' : (lcRate < 15 ? 'warn' : 'bad'); var ltEl = document.querySelector('[data-output="lost_total"]'); ltEl.textContent = fmt$(lost); ltEl.dataset.band = lost === 0 ? 'good' : (lost < 200 ? 'warn' : 'bad'); var topSrc = null, topCount = 0; for (var k in sourceNs) if (sourceNs[k] > topCount) { topSrc = k; topCount = sourceNs[k]; } document.querySelector('[data-output="top_source"]').textContent = topSrc ? (topSrc + ' (' + topCount + ' no-shows)') : '—'; var c = document.querySelector('[data-output="callout"]'); if (!c) return; if (total === 0) { c.textContent = 'Log every reservation. The fix is by SOURCE — if one platform’s no-show rate runs 3× another’s, the deposit policy goes there first.'; } else if (lost === 0) { c.textContent = total + ' reservation(s) logged, all showed. Clean period.'; } else if (topSrc && topCount >= 3) { c.textContent = topSrc + ' is the recurring no-show source — ' + topCount + ' this period. Deposit / hold policy goes here first.'; } else { c.textContent = fmt$(lost) + ' lost across ' + (ns + lc) + ' missed reservation(s). Tally by source over a month before changing policy.'; } } function collect() { var f = document.getElementById('sheet-fields'); if (!f) return [['Field', 'Value']]; var rows = [ ['Field', 'Value'], ['Date', f.date.value || ''], ['Avg per-cover', f.avg_check.value || ''], [], ['Date', 'Source', 'Party', 'Deposit', 'Outcome', 'Lost

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

When to use it

Pull this sheet out when —

  • Daily — log every confirmed reservation as it cancels, no-shows, or sits.
  • End of week, when you price the empty seats. The number lands different than the feeling.
  • Before deciding whether to require a deposit or a credit-card hold by booking source.
Common mistakes

What operators get wrong

  • Treating late-cancels and no-shows as the same row. Late-cancel had a chance to refill; no-show didn’t.
  • Not pricing the empty seat. "Two no-shows tonight" sounds small; "$140 in lost revenue" doesn’t.
  • Logging only direct reservations. The booking source is the lever — if Resy no-shows are 3× OpenTable, the policy is by source, not blanket.
Pairs with

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

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

, 'Notes'], ]; for (var i = 1; i <= 8; i++) { if (!f['r' + i + '_date'].value && !f['r' + i + '_party'].value) continue; rows.push([ f['r' + i + '_date'].value || '', f['r' + i + '_src'].value || '', f['r' + i + '_party'].value || '', f['r' + i + '_dep'].checked ? 'yes' : 'no', f['r' + i + '_out'].value || '', (f['r' + i + '_lost'].value || '').replace(/^—$/, ''), f['r' + i + '_notes'].value || '', ]); } rows.push([]); rows.push(['No-show rate', document.querySelector('[data-output="ns_rate"]').textContent]); rows.push(['Late-cancel rate', document.querySelector('[data-output="lc_rate"]').textContent]); rows.push(['Lost revenue', document.querySelector('[data-output="lost_total"]').textContent]); rows.push(['Top no-show src', document.querySelector('[data-output="top_source"]').textContent]); return rows; } if (window.SheetPage) window.SheetPage.register({ slug: 'reservation-no-show-log', collect: collect, recalc: recalc }); })();

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

When to use it

Pull this sheet out when —

Common mistakes

What operators get wrong

Pairs with

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

Tools

  • None yet.

Glossary

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