Over the past three years, Alpray has completed 120+ Make.com to Google Apps Script migrations. This playbook is a distillation of everything we've learned — costs, timelines, what works, and what fails.
The single most important finding: 94% of businesses spending more than $100/month on Make.com would save money migrating to Apps Script, and most break even within 6–8 weeks.
Who this is for:
These numbers come from actual client projects, not estimates. All costs are in USD. "Make.com cost" reflects the tier each client was on before migration.
| Workflow Type | Make.com Cost | Apps Script Dev Time | Break-Even | Sample Size |
|---|---|---|---|---|
| Simple (1–5 steps) | $29/mo ($348/yr) | 3–5 hours | 8 weeks | 45 projects |
| Medium (6–15 steps) | $149/mo ($1,788/yr) | 8–12 hours | 6 weeks | 52 projects |
| Complex (16+ steps) | $899/mo ($10,788/yr) | 20–40 hours | 4 weeks | 23 projects |
| Scenario | Make.com (5yr) | Apps Script (5yr) | Net Savings |
|---|---|---|---|
| Simple workflow | $1,740 | ~$200 (dev time) | $1,540 |
| Medium workflow | $8,940 | ~$600 (dev time) | $8,340 |
| Complex workflow | $53,940 | ~$2,500 (dev time) | $51,440 |
Dev time cost calculated at $75/hr average. Apps Script ongoing cost is $0/month.
This is the framework I use on every initial client call. It's blunt because being honest about when NOT to migrate builds more trust than overselling.
Use Make for rapid prototyping and flows that need 20+ external connectors. Migrate to Apps Script when a workflow has stabilized and its monthly cost justifies development. Many of our clients run both in parallel permanently.
Every successful migration follows these six phases. Skipping any phase correlates directly with the 6% failure rate.
| Before | Make.com — $149/month |
| Workflow | Google Sheets → validate → update CRM → send notifications (12 steps) |
| Complexity | Medium |
| Migration time | 10 hours |
| After | Apps Script — $0/month |
| ROI | Break-even in 6 weeks |
function syncCRMData() {
const sheet = SpreadsheetApp.getActiveSheet();
const data = sheet.getDataRange().getValues();
data.forEach((row, index) => {
if (index === 0) return; // skip header
const validated = validateRow_(row);
if (!validated.isValid) {
logError_(row, validated.errors);
return;
}
updateCRM_(validated.data);
sendNotification_(validated.data);
});
}
| Before | Make.com — $299/month |
| Workflow | Gmail trigger → parse PDF → extract data → update Sheets → generate invoice → send email (18 steps) |
| Complexity | Complex |
| Migration time | 28 hours |
| After | Apps Script — $0/month |
| ROI | Break-even in 4 weeks. Saved $3,588/year. |
| Before | Make.com — $899/month (high operation volume) |
| Workflow | Shopify webhook → update inventory Sheets → sync to 3PL API → alert on low stock (8 steps, 50k+ ops/month) |
| Complexity | Medium steps, High volume |
| Migration time | 16 hours |
| After | Apps Script — $0/month |
| ROI | Break-even in 2 weeks. Saved $10,788/year. |
function robustApiCall_(url, options) {
const maxRetries = 3;
let lastError;
for (let i = 0; i < maxRetries; i++) {
try {
const response = UrlFetchApp.fetch(url, {
...options,
muteHttpExceptions: true
});
if (response.getResponseCode() === 200) {
return JSON.parse(response.getContentText());
}
lastError = `HTTP ${response.getResponseCode()}`;
} catch (e) {
lastError = e.message;
}
Utilities.sleep(Math.pow(2, i) * 1000); // 1s, 2s, 4s
}
throw new Error(`API call failed after ${maxRetries} retries: ${lastError}`);
}
function processBatch_() {
const props = PropertiesService.getScriptProperties();
const lastRow = parseInt(props.getProperty('lastProcessedRow') || '1');
const batchSize = 100;
const sheet = SpreadsheetApp.getActiveSheet();
const data = sheet.getRange(lastRow + 1, 1, batchSize, sheet.getLastColumn()).getValues();
data.forEach((row, i) => {
if (!row[0]) return;
processRow_(row);
props.setProperty('lastProcessedRow', String(lastRow + i + 1));
});
if (data.length === batchSize) {
// Schedule next batch in 1 minute
ScriptApp.newTrigger('processBatch_')
.timeBased().after(60000).create();
} else {
props.deleteProperty('lastProcessedRow');
}
}
function log_(level, message, data) {
const logSheet = SpreadsheetApp.openById('YOUR_LOG_SHEET_ID')
.getSheetByName('Logs');
logSheet.appendRow([
new Date(),
level,
message,
data ? JSON.stringify(data) : ''
]);
if (level === 'ERROR') {
MailApp.sendEmail('hello@alpray.com', `Script Error: ${message}`, message);
}
}
function rateLimitedProcess_(items, delayMs) {
items.forEach((item, index) => {
processItem_(item);
// Pause every 10 items to respect API rate limits
if (index % 10 === 9) {
Utilities.sleep(delayMs || 1000);
}
});
}
| Pitfall | Problem | Solution |
|---|---|---|
| Execution time limits | Apps Script cuts off at 6 minutes | Use batch processing pattern + continuation triggers |
| API rate limits | Too many calls in quick succession | Batch requests, add Utilities.sleep(), implement caching |
| OAuth scope creep | Script requests too many permissions | Request only the minimum scopes needed; document each one |
| No error visibility | Script fails silently | Log all errors to Sheets + email alerts on ERROR level |
| Quota exhaustion | Daily Gmail/Drive quotas exceeded | Check quotas at script start; queue excess items for next day |
| No rollback plan | Can't go back if migration fails | Keep Make scenario paused (not deleted) for 30 days post-migration |
| Hard-coded values | Script breaks when IDs or URLs change | Store all configurable values in PropertiesService or a config sheet |
Use this formula to estimate your break-even before committing to migration:
Break-even (weeks) = Development cost ÷ (Monthly Make.com cost × 0.25)
Example: 10 hours × $75/hr = $750 dev cost. Monthly Make cost = $149. Break-even = $750 ÷ ($149 × 0.25) ≈ 20 weeks. Worth it for any workflow you plan to run 6+ months.
| Current Make.com Plan | Est. Dev Time | Break-Even | 1-Year Savings | 5-Year Savings |
|---|---|---|---|---|
| Core ($29/mo) | 3–5 hrs | ~8 weeks | $200 | $1,540 |
| Pro ($149/mo) | 8–12 hrs | ~6 weeks | $1,200 | $8,340 |
| Teams ($299/mo) | 12–20 hrs | ~5 weeks | $2,600 | $16,400 |
| Enterprise ($899/mo) | 20–40 hrs | ~4 weeks | $8,800 | $51,440 |
Based on 120+ projects: 3–5 hours (simple, 1–5 steps), 8–12 hours (medium, 6–15 steps), 20–40 hours (complex, 16+ steps).
We implement error handling, logging, and email alerts. The original Make.com scenario stays paused (not deleted) for 30 days as a rollback option. Our 94% success rate means breakages are rare — and when they happen, the logging system catches them immediately.
Basic JavaScript understanding helps for minor edits. Most clients manage their scripts independently after a 1-hour walkthrough. For anything complex, maintenance support is available.
Yes — this is often the best approach. Migrate your highest-cost workflow first, validate it over a few weeks, then migrate the next. Many clients permanently run a mix: Make for quick external integrations, Apps Script for core business logic.
Yes, for standard Google Workspace users. There are daily quotas (email sends, API calls, execution time) that apply, but 95%+ of typical business workflows stay well within them. Heavy-volume pipelines (1M+ ops/month) may need Google Cloud alternatives.
Apps Script can call any external API via UrlFetchApp. We've integrated Salesforce, HubSpot, Shopify, Stripe, Slack, and 50+ other services this way. If Make.com uses a pre-built connector, we replicate it with a direct API call.
Send us a description or screenshot of your Make.com scenario. We'll give you a free 15-minute assessment: can it be migrated, estimated time, and expected savings.
We offer a free 15-minute assessment. Share your Make.com setup and we'll give you an honest answer: migrate, stay, or hybrid.
90
120
5
240