context
A school self-management ("cogestione") event requires collecting registrations for dozens of parallel activities, each with limited seats. The historical tool — a shared Google Sheet — inevitably led to overbooking: dozens of students opening the same cell at the same instant, last-write-wins.
A consistency-safe mechanism was needed that wouldn't break the workflow already known to students: Google Forms, no app to install, no external accounts.
approach
- Frontend: Google Form with dynamic questions — a list of activities populated from the sheet, refreshed by Apps Script before each registration window.
-
Backend:
onFormSubmittrigger on a container spreadsheet. The handler runs capacity check and write atomically. -
Concurrency safety: each submit acquires a
document-lock via
LockService.getDocumentLock()with a 30s timeout. Inside the critical section: read current seat count, compare to capacity, write the row or reject with an email to the sender. - Attendance sheets: at the cutoff, a script automatically generates moderator attendance sheets — one tab per activity, participants sorted, cells ready to sign.
- Monitoring: every submit (accepted or rejected) logged with timestamp and reason — useful for the post-event debrief.
outcome
- Zero overbooking on registration day.
- Attendance sheets ready automatically, no manual work for coordinators.
- Add here: total registered students, concurrent-submit peak in the first minute, average trigger response time, optional comparison with the previous edition.
constraints
Apps Script has hard quotas: 6-minute max runtime per execution, daily limits on triggers and email sending. The handler was designed to finish in <2 seconds even under load, delegating attendance sheet generation to a separate scheduled trigger.
Auth limited to Google accounts: sufficient for the school context (everyone has an institutional account) but not generalizable to open-to-the-public scenarios.
If you hit a specific Apps Script limit that required a workaround (e.g., LockService timeout, silent trigger failure, residual race condition), tell that story here.
lessons
LockServiceis the one Apps Script primitive that actually lets you build multi-user consistency-safe flows. Without it, each submit lives in its own world.- Apps Script triggers can be silently re-executed by the runtime (internal retry). Handlers must be idempotent — writing the same registration twice is worse than not writing it at all.
- Keeping logic out of the form and in the script separates UI from domain: when rules change, only the script changes.
- Add your own lesson — maybe about talking to teachers, deploying on event day, or the debrief.