DEV Community

tom-takeru
tom-takeru

Posted on

Server Monitoring using GAS (Google Apps Script) within the Free Usage Limits

When using Google Apps Script (GAS), one common concern is how much you can achieve within the free usage limits. In this article, we'll summarize these limits and demonstrate a practical example of how to prevent your backend server from sleeping by regularly pinging its health-check API.

Main Limits of GAS Free Tier

Below are the primary limitations of GAS’s free usage:

Item Limit
Maximum execution time per script run 6 minutes (360 seconds)
Total daily execution time 90 minutes (5400 seconds)
Number of triggers Maximum 20 triggers per script
URL Fetch calls 20,000 requests per day
Emails sent 100 emails per day

For detailed information, please refer to the official documentation: Quotas for Google Services (Official)

How to Use GAS for Regular Server Health-Check to Prevent Sleep

In this practical example, we demonstrate how to prevent a backend server running on a free plan from sleeping by pinging its health-check API every 5 minutes using GAS.

Implementation Steps

Follow these detailed steps to set up the GAS:

  1. Create a new Google Spreadsheet.
  2. Create a sheet named ServerCheckURLs.
  3. Enter the URLs you want to monitor into column A of this sheet.
  4. Open the GAS editor by clicking on "Extensions" → "Apps Script" from the spreadsheet.
  5. Copy and paste the GAS script provided below and save it.

GAS Implementation Example

function main() {
  const urls = getUrlsFromSheet('ServerCheckURLs');
  Logger.log('===== HTTP Status of URLs =====');
  urls.forEach((url, index) => {
    const statusCode = fetchHttpStatusCodeWithRetry(url, 3, 30000);
    Logger.log(`${index + 1}. URL: ${url}\n   HTTP Status: ${statusCode}`);
  });
  Logger.log('================================');
}

// Fetch URLs from column A of the specified sheet
function getUrlsFromSheet(sheetName) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  const lastRow = sheet.getLastRow();

  if (lastRow < 1) return [];

  const urlRange = sheet.getRange(`A1:A${lastRow}`);
  const urls = urlRange.getValues()
    .flat()
    .filter(url => url); // remove empty cells

  return urls;
}

// Fetch HTTP status code with retry mechanism
function fetchHttpStatusCodeWithRetry(url, retryCount, intervalMs) {
  let statusCode = fetchHttpStatusCode(url);
  let attempts = 1;

  while (statusCode !== 200 && attempts <= retryCount) {
    Logger.log(`Retrying ${url} (${attempts}/${retryCount}) in ${intervalMs / 1000}s...`);
    Utilities.sleep(intervalMs);
    statusCode = fetchHttpStatusCode(url);
    attempts++;
  }

  return statusCode;
}

// Fetch HTTP status code for a given URL
function fetchHttpStatusCode(url) {
  const options = { muteHttpExceptions: true };
  try {
    const response = UrlFetchApp.fetch(url, options);
    return response.getResponseCode();
  } catch (e) {
    Logger.log(`Error accessing ${url}: ${e}`);
    return 'Error';
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. Set up a trigger following the steps below:

Trigger Setup

  1. In the GAS editor, select "Triggers" from the left-hand menu.
  2. Click on "Add Trigger" button at the bottom-right.
  3. Select the main function to execute.
  4. Set the trigger type to "Time-driven".
  5. Choose the timer frequency, such as every 5 minutes, and save the trigger.

Practical Example: Evaluating a 5-Minute Interval Trigger

Here's a concrete example scenario:

  • Script execution frequency: Every 5 minutes
  • Daily execution count: 24 hours × (60 minutes ÷ 5 minutes) = 288 times/day
  • Maximum execution time per run: approximately 6.5 seconds
    • Note: The 6.5 seconds represents the longest observed runtime, not the average.

Calculating total daily execution time:

  • About 6.5 seconds × 288 runs ≈ 1883 seconds (~31 minutes)

Result: Within Free Tier Limits

Note: Depending on your setup, you may hit either the execution time limit or URL Fetch limit first. It is advisable to calculate based on your specific number of monitored URLs and their response times.

Evaluating URL Fetch Limit

Here's a quick reference table to ensure you're within the daily URL Fetch limit (20,000 requests per day):

Number of URLs Requests per Run Runs per Day (every 5 mins) Total Requests per Day Within Limit?
1 1 288 288 ✅ Yes
5 5 288 1,440 ✅ Yes
10 10 288 2,880 ✅ Yes
50 50 288 14,400 ✅ Yes
69 69 288 19,872 ✅ Yes
70 70 288 20,160 ❌ No (exceeds limit)

As shown, you can safely monitor up to 69 URLs at a 5-minute interval without exceeding the free URL Fetch quota.

Comparing with GAS’s free limits (6 minutes per run, 90 minutes per day), the current scenario (maximum ~6.5 seconds per run, ~31 minutes per day) is comfortably within the allowed limits.

Therefore, such regular health checks every 5 minutes can safely and effectively operate within GAS’s free usage tier.

Heroku

Deploy with ease. Manage efficiently. Scale faster.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

DEV shines when you're signed in, unlocking a customized experience with features like dark mode!

Okay