- 2026.07.29 What Breaks When Apps Script Projects Sprawl
- 2026.07.16 Why a Daily Apps Script Trigger Suddenly Stops
- 2026.07.15 What Breaks When Customer Data Lives in Browser Storage
- 2026.07.07 When the Browser Throws Your Data Away: The Green Checkmark Lies
- 2026.07.07 Installed ≠ Working: the Backup Trigger Never Ran Once
- 2026.07.07 GAS Has No Gradual Rollout: One 'Correct' Check Locks Out Every User
- 2026.07.07 Sheets Turns Your Text Into a Date: When '2026-06' Blocks Completion Forever
- 2026.06.18 An App Where Many Write to One Sheet: Concurrency, Duplicates, and Export Design
- 2026.06.12 Don't Read Cells One at a Time: Service Calls Are the Real Cost
- 2026.06.11 Stuffing JSON or Images into a Sheet Cell Will Break It
- 2026.06.10 One Deploy Setting Decides Your Security Model: Execute as / Access
- 2026.06.09 The 6-Minute GAS Limit: Chunk and Resume Before It Kills You
- 2026.06.08 PropertiesService Is Not a Database: the 9KB Wall
- 2026.06.07 Why Saving a Screen as an Image Freezes on Mobile
- 2026.06.06 Concurrent Writes to the Same Sheet Break: LockService and the 30-Run Ceiling
- 2026.06.05 Your /exec URL Must Not Change on Every Redeploy You are here
- 2026.06.04 External Calls Fail Sometimes: Exponential Backoff and a Retry Budget
- 2026.06.03 HtmlService Apps: Shell First, Then Async Load and Mobile Back
- 2026.06.02 When to Graduate from GAS: Limit Signals and Moving to an External DB
- 2026.06.01 Adding a Brain and an Engine Room to GAS: Vertex AI and Cloud Run
Your /exec URL Must Not Change on Every Redeploy
Reuse the deployment ID when you push a new version with clasp and the /exec URL stays fixed. Guard shared sheet writes with LockService.
Redeploy by reusing the deployment ID so the /exec URL stays fixed. If the web app address changes every time you create a new deployment, customer-saved links and external webhook integrations break that day.
# Bad: a new deployment every time -> a new URL
clasp deploy
# Good: reuse the same deployment ID -> URL stays fixed
clasp deploy -i <deploymentId> -d "v12 $(git rev-parse --short HEAD)"
Why it matters
A deploy URL is a contracted interface. Customer bookmarks, QR codes, and other systems’ webhooks point at that address. If it changes on every redeploy, you have to re-announce every integration: and a missed one becomes a “it worked yesterday” outage.
push and deploy are different
clasp pushoverwrites the HEAD of the Apps Script project with your current code. That’s “save,” not “deploy.”- Users run a version-pinned deployment, not HEAD.
- So do dev verification on the
/devURL (always the latest saved code), and delivery/ops smoke tests on the version-pinned/execURL.
clasp push overwrites the entire remote. If someone edited a file in the web editor, it can be lost: check remote changes before redeploying.
Concurrent writes to the same asset need LockService
When several users or triggers write to the same sheet at once, numbers collide or rows get overwritten. Wrap read-modify-write operations (append, number issuance, status change) in a lock.
function appendWithLock(row) {
const lock = LockService.getScriptLock();
if (!lock.tryLock(10000)) throw new Error("could not acquire lock");
try {
const sheet = SpreadsheetApp.getActive().getSheetByName("AuditLog");
sheet.appendRow(row);
SpreadsheetApp.flush(); // commit before release
} finally {
lock.releaseLock(); // always in finally
}
}
Rules: prefer tryLock(timeout), and always put releaseLock() in finally. Call SpreadsheetApp.flush() to commit the write before releasing the lock, so the next run doesn’t read a stale value. Don’t make network calls or run long computations inside the lock.
Deeper: the concurrency ceiling
Concurrent executions cap at about 30 per user. Counting LockService waiting, design for roughly 60 lossless concurrent users; beyond that, consider an external DB or a queue.
One line to keep: pin the address with the deployment ID, and protect shared writes with lock + flush.
Frequently asked questions
- Why does the web app URL change every time I run clasp deploy?
- Running the command without options creates a new deployment each time, which issues a new URL. Pass the -i flag with an existing deployment ID to reuse it and keep the /exec URL fixed.
- What is the difference between clasp push and clasp deploy?
- clasp push saves your code to the HEAD of the Apps Script project but does not create a new deployment. Users run a version-pinned deployment, so production changes require clasp deploy as well.
- How should LockService be used when multiple users write to the same sheet?
- Acquire the lock with tryLock(timeout), commit the write with SpreadsheetApp.flush() before releasing, and always call releaseLock() in a finally block. Avoid network calls or long computations inside the lock.
- 2026.07.29 What Breaks When Apps Script Projects Sprawl
- 2026.07.16 Why a Daily Apps Script Trigger Suddenly Stops
- 2026.07.15 What Breaks When Customer Data Lives in Browser Storage
- 2026.07.07 When the Browser Throws Your Data Away: The Green Checkmark Lies
- 2026.07.07 Installed ≠ Working: the Backup Trigger Never Ran Once
- 2026.07.07 GAS Has No Gradual Rollout: One 'Correct' Check Locks Out Every User
- 2026.07.07 Sheets Turns Your Text Into a Date: When '2026-06' Blocks Completion Forever
- 2026.06.18 An App Where Many Write to One Sheet: Concurrency, Duplicates, and Export Design
- 2026.06.12 Don't Read Cells One at a Time: Service Calls Are the Real Cost
- 2026.06.11 Stuffing JSON or Images into a Sheet Cell Will Break It
- 2026.06.10 One Deploy Setting Decides Your Security Model: Execute as / Access
- 2026.06.09 The 6-Minute GAS Limit: Chunk and Resume Before It Kills You
- 2026.06.08 PropertiesService Is Not a Database: the 9KB Wall
- 2026.06.07 Why Saving a Screen as an Image Freezes on Mobile
- 2026.06.06 Concurrent Writes to the Same Sheet Break: LockService and the 30-Run Ceiling
- 2026.06.05 Your /exec URL Must Not Change on Every Redeploy You are here
- 2026.06.04 External Calls Fail Sometimes: Exponential Backoff and a Retry Budget
- 2026.06.03 HtmlService Apps: Shell First, Then Async Load and Mobile Back
- 2026.06.02 When to Graduate from GAS: Limit Signals and Moving to an External DB
- 2026.06.01 Adding a Brain and an Engine Room to GAS: Vertex AI and Cloud Run