Apps Script 할당량 오류는 반복 호출 구조와 트리거 실행 간격을 함께 확인해야 합니다.
Google Apps Script에서 Service invoked too many times 오류가 발생했다면 먼저 같은 서비스를 너무 자주 호출하고 있는지 확인해야 합니다. 코드 문법이 틀렸다기보다 SpreadsheetApp, GmailApp, DriveApp, UrlFetchApp 같은 서비스를 반복문 안에서 과도하게 실행하거나, 시간 기반 트리거가 너무 자주 돌면서 할당량 제한에 걸릴 때 자주 발생합니다.
해결 순서는 실행 로그 확인, 오류가 난 서비스 확인, 트리거 중복 점검, getValue()·setValue() 반복 호출을 getValues()·setValues() 방식으로 바꾸기, 한 번에 처리하는 데이터 수 줄이기 순서로 보면 됩니다. 최신 할당량 수치와 정책은 계정 유형과 Google 정책에 따라 달라질 수 있으므로 발행 전 Google Apps Script 공식 Quotas 문서를 확인하는 것이 안전합니다.
📑목차[보기]
오류 메시지 원문
Apps Script 할당량 관련 오류는 메시지 문구가 조금씩 다르게 표시될 수 있습니다. 특히 아래 문구가 보이면 특정 서비스 호출량, 하루 실행량, 트리거 실행량을 함께 확인해야 합니다.
Service invoked too many times
Service invoked too many times for one day
Service using too much computer time for one day
핵심 구분
Service invoked too many times는 특정 서비스 호출이 너무 많은 경우에 가깝고, Service using too much computer time for one day는 하루 동안 트리거 등으로 사용한 총 실행 시간이 많을 때 나타날 수 있습니다. 정확한 제한 수치는 바뀔 수 있으므로 공식 Quotas 문서에서 최신 기준을 확인해야 합니다.
Service invoked too many times 오류가 발생하는 이유
이 오류는 Google Apps Script가 연결된 Google 서비스나 외부 요청을 너무 많이 호출할 때 발생합니다. 구글시트 자동화라면 SpreadsheetApp, 메일 자동 발송이라면 GmailApp, 파일 정리 자동화라면 DriveApp, RSS나 외부 API 수집이라면 UrlFetchApp 호출이 원인이 되는 경우가 많습니다.
| 상황 | 자주 보이는 원인 | 처리 방향 |
|---|---|---|
| 구글시트 데이터 정리 | 셀마다 getValue(), setValue() 실행 |
getValues(), setValues()로 일괄 처리 |
| Gmail 자동 발송 | GmailApp.sendEmail() 반복 실행 |
발송 대상 분할, 발송 완료 표시 컬럼 추가 |
| RSS·API 수집 | UrlFetchApp을 짧은 간격으로 반복 호출 |
수집 간격 늘리기, 캐시·중복 확인 로직 추가 |
| 시간 기반 트리거 | 트리거가 너무 자주 실행되거나 중복 등록됨 | 트리거 목록 점검, 실행 간격 조정 |
먼저 확인할 것
오류를 고치기 전에 어느 서비스에서 제한에 걸렸는지부터 확인해야 합니다. 같은 메시지라도 원인이 구글시트 호출인지, Gmail 발송인지, 외부 API 호출인지에 따라 수정 위치가 달라집니다.
- Apps Script 편집기에서 실행 기록 또는 로그를 확인합니다.
- 오류가 발생한 함수 이름과 줄 번호를 확인합니다.
SpreadsheetApp,GmailApp,DriveApp,UrlFetchApp중 어느 서비스 호출 직후 멈췄는지 봅니다.- 트리거 메뉴에서 같은 함수가 여러 번 등록되어 있는지 확인합니다.
- 최근에 데이터 행 수, 발송 대상 수, API 요청 수가 늘었는지 확인합니다.
- 실행 시간 초과 오류인지, 서비스 호출량 초과 오류인지 메시지를 구분합니다.
주의할 점
트리거를 삭제하거나 코드를 크게 바꾸기 전에는 현재 트리거 이름, 실행 주기, 연결된 함수 이름을 먼저 메모해 두는 것이 좋습니다. 자동 발송이나 데이터 수정 스크립트는 잘못 수정하면 중복 발송 또는 중복 입력이 생길 수 있습니다.
구글시트 자동화에서 자주 나는 잘못된 코드
구글시트 자동화에서 가장 흔한 실수는 반복문 안에서 셀을 하나씩 읽고 하나씩 쓰는 구조입니다. 데이터가 10행일 때는 문제가 없어 보이지만, 1,000행·5,000행으로 늘어나면 SpreadsheetApp 호출 횟수가 급격히 많아집니다.
아래 코드는 행마다 getValue()와 setValue()를 반복합니다. 작은 테스트에서는 통과해도 실제 데이터가 많아지면 느려지고 할당량 오류가 날 수 있습니다.
function badExample() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
const lastRow = sheet.getLastRow();
for (let row = 2; row <= lastRow; row++) {
const name = sheet.getRange(row, 1).getValue();
const score = sheet.getRange(row, 2).getValue();
if (score >= 80) {
sheet.getRange(row, 3).setValue(name + ' 통과');
} else {
sheet.getRange(row, 3).setValue(name + ' 확인 필요');
}
}
}
문제는 반복 횟수 자체보다 “반복문 안에서 Apps Script 서비스 호출이 계속 발생한다”는 점입니다. getRange(), getValue(), setValue()가 매 행마다 실행되면 호출 수가 빠르게 늘어납니다.
getValues와 setValues로 호출 횟수 줄이는 방법
구글시트 자동화는 데이터를 한 번에 읽고, 배열에서 계산한 뒤, 결과를 한 번에 쓰는 방식으로 바꾸는 것이 좋습니다. 이렇게 하면 시트 서비스 호출 횟수가 크게 줄어들고 실행 속도도 안정됩니다.
function goodExample() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
const lastRow = sheet.getLastRow();
if (lastRow < 2) return;
const values = sheet.getRange(2, 1, lastRow - 1, 2).getValues();
const results = values.map(function(row) {
const name = row[0];
const score = row[1];
if (score >= 80) {
return [name + ' 통과'];
}
return [name + ' 확인 필요'];
});
sheet.getRange(2, 3, results.length, 1).setValues(results);
}
위 방식은 시트에서 데이터를 한 번에 가져오고, 결과도 한 번에 입력합니다. 데이터가 많을수록 셀 단위 처리보다 배열 단위 처리가 유리합니다.
자동화가 중간에 끊기거나 다시 실행될 수 있다면 처리 완료 표시 컬럼을 두는 것도 좋습니다. 이미 처리된 행을 다시 처리하지 않으면 중복 발송, 중복 입력, 불필요한 서비스 호출을 줄일 수 있습니다.
function processWithStatusColumn() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
const lastRow = sheet.getLastRow();
if (lastRow < 2) return;
const values = sheet.getRange(2, 1, lastRow - 1, 4).getValues();
const output = [];
values.forEach(function(row) {
const email = row[0];
const name = row[1];
const status = row[3];
if (status === '완료') {
output.push(['완료']);
return;
}
// 실제 발송 전에는 테스트 대상 1~2개로 먼저 확인하세요.
// GmailApp.sendEmail(email, '안내 메일', name + '님, 안내드립니다.');
output.push(['완료']);
});
sheet.getRange(2, 4, output.length, 1).setValues(output);
}
GmailApp, DriveApp, UrlFetchApp 사용 시 주의할 점
Service invoked too many times 오류는 구글시트에서만 생기지 않습니다. Gmail 자동 발송, Drive 파일 정리, RSS 수집, 외부 API 호출 자동화에서도 자주 발생합니다.
GmailApp.sendEmail은 발송 완료 표시가 중요합니다
Gmail 자동 발송은 같은 대상에게 여러 번 보내지 않도록 발송 완료 컬럼을 두는 것이 좋습니다. 스크립트가 중간에 실패한 뒤 다시 실행되면 이미 보낸 대상에게 메일이 다시 갈 수 있기 때문입니다. 발송 대상 수가 많다면 하루에 한 번에 처리하기보다 일정 수씩 나눠 처리하는 방식도 검토할 수 있습니다.
UrlFetchApp은 외부 API 제한도 함께 봐야 합니다
UrlFetchApp은 Apps Script 할당량뿐 아니라 호출 대상 API의 제한도 함께 영향을 받습니다. RSS, 뉴스 API, 사내 API를 반복 호출한다면 같은 URL을 짧은 시간에 계속 요청하고 있지 않은지 확인해야 합니다. 응답을 캐시하거나 이미 수집한 항목은 건너뛰는 구조가 도움이 됩니다.
DriveApp은 파일 목록 전체 스캔을 줄여야 합니다
Drive 자동화에서 폴더 전체 파일을 매번 처음부터 끝까지 훑는 방식은 비효율적입니다. 파일명, 수정일, 처리 상태를 저장해 두고 새로 처리할 대상만 좁히면 호출량을 줄일 수 있습니다.
트리거 중복과 실행 간격 점검
시간 기반 트리거가 중복 등록되어 있으면 같은 함수가 예상보다 여러 번 실행됩니다. 예를 들어 10분마다 실행되는 트리거를 실수로 3개 등록하면 실제로는 같은 자동화가 더 자주 실행되는 것처럼 동작할 수 있습니다.
□ Apps Script 편집기에서 트리거 메뉴를 엽니다.
□ 같은 함수가 여러 개 등록되어 있는지 확인합니다.
□ 시간 기반 트리거 실행 간격이 너무 짧지 않은지 확인합니다.
□ 테스트용 트리거가 남아 있지 않은지 확인합니다.
□ 실패 후 재시도 구조가 중복 실행을 만들고 있지 않은지 확인합니다.
□ 자동 발송 함수는 처리 완료 컬럼을 먼저 확인하도록 구성합니다.
트리거를 조정할 때는 바로 삭제하기보다 어떤 함수가 어떤 주기로 실행되는지 먼저 기록해 두는 것이 좋습니다. 운영 중인 자동화라면 트리거 변경 후 한두 번 실행 로그를 확인해 예상한 간격으로 실행되는지 점검합니다.
실행 시간 초과 오류와 할당량 초과 오류의 차이
Exceeded maximum execution time과 Service invoked too many times는 비슷해 보이지만 원인이 다릅니다. 전자는 한 번의 실행이 너무 오래 걸리는 문제이고, 후자는 특정 서비스 호출량이 너무 많은 문제입니다.
| 구분 | 주요 의미 | 우선 조치 |
|---|---|---|
Exceeded maximum execution time |
한 번의 실행 시간이 너무 김 | 처리량 분할, 다음 실행으로 이어서 처리 |
Service invoked too many times |
특정 서비스 호출이 너무 많음 | 반복 호출 제거, 배치 처리, 트리거 간격 조정 |
Service using too much computer time for one day |
하루 동안 사용한 총 실행 시간이 많음 | 트리거 실행 횟수와 처리량 줄이기 |
두 오류는 함께 발생할 수 있습니다. 예를 들어 반복문 안에서 API를 계속 호출하면 실행도 오래 걸리고 호출량도 많아집니다. 이 경우에는 실행 시간을 줄이는 것과 서비스 호출 횟수를 줄이는 작업을 함께 해야 합니다.
재발 방지 체크리스트
한 번 오류를 해결했더라도 데이터가 늘어나면 같은 문제가 다시 생길 수 있습니다. 자동화는 처음부터 많은 데이터를 처리한다고 가정하고 구조를 잡는 것이 좋습니다.
□ 셀 단위 처리보다 배열 단위 처리로 바꿉니다.
□ getValue()·setValue() 반복을 getValues()·setValues()로 줄입니다.
□ 한 번에 처리할 행 수를 제한합니다.
□ 처리 완료 상태를 시트에 저장합니다.
□ 시간 기반 트리거 간격을 너무 짧게 잡지 않습니다.
□ 테스트할 때는 전체 데이터가 아니라 일부 데이터로 먼저 확인합니다.
□ Gmail 자동 발송은 발송 완료 컬럼을 둡니다.
□ 외부 API 호출은 중복 요청을 줄이고 응답 캐시를 검토합니다.
□ 공식 Quotas 문서에서 최신 제한 기준을 확인합니다.
가장 중요한 기준은 “반복문 안에서 외부 서비스 호출을 얼마나 줄였는가”입니다. 계산은 자바스크립트 배열 안에서 처리하고, Google 서비스와 통신하는 횟수는 최소화하는 방향으로 바꾸면 대부분의 할당량 오류를 줄일 수 있습니다.
공식 자료로 더 확인하기
Apps Script 할당량과 서비스별 제한은 변경될 수 있습니다. 숫자를 외워서 처리하기보다 오류가 발생한 서비스에 맞춰 공식 문서에서 최신 기준을 확인하는 것이 좋습니다.
Apps Script 서비스별 할당량, 오류 메시지 예시, 하루 사용량 제한 관련 기준을 확인할 수 있습니다.
Apps Script Quotas 문서 확인하기시간 기반 트리거, 설치형 트리거, 자동 실행 구조를 확인할 수 있습니다. 트리거 중복이나 실행 간격을 점검할 때 함께 보면 좋습니다.
Apps Script Triggers 문서 확인하기
Range, Sheet, SpreadsheetApp 관련 메서드를 확인할 수 있습니다. getValues(), setValues() 구조를 점검할 때 참고하기 좋습니다.
GmailApp으로 메일을 작성·발송·관리하는 메서드를 확인할 수 있습니다. 자동 발송 스크립트의 호출 방식과 제한을 점검할 때 참고할 수 있습니다.
Gmail service 문서 확인하기함께 보면 좋은 글
자주 묻는 질문
Google Apps Script의 Service invoked too many times 오류는 반복문 안의 서비스 호출을 줄이고, 트리거 간격과 처리 완료 상태를 함께 점검하는 것이 핵심입니다.
댓글