Google Drive as a NAS Backup Target: The 750 GB/day Wall and rclone

Why we dropped Google Drive as offsite target for a 5.8 TB NAS backup: shared-client throttling, the 750 GB daily cap, and an rclone flag that quit early.

By the ailog editors · Published Oct 1, 2026 · 8 min read · How we work
In short
  • We tried to back up a 5.8 TB Synology NAS to Google Drive with rclone before wiping it. Our own speed tests were fine. The daily upload cap was the problem: about 750 GB a day means at least 8 days for the full set.
  • rclone’s shared OAuth client gave us 1.5–3 MB/s per stream and stalled badly at one point. With our own OAuth client (published to Production), one stream went to about 23 MB/s and the NAS uploaded at about 63 MB/s.
  • Our first full run stopped after about 4 minutes and 5.0 GB. The 403 userRateLimitExceeded it hit was a per-second rate limit, but --drive-stop-on-upload-limit treated it as the daily cap and exited fatally.
  • A backup server on the same LAN does the copy in about 15 hours at gigabit speed, with no daily cap. We switched to that, and see cloud upload as a slow, later second copy.

What we were trying to do

The NAS had two disks in RAID0, so nothing protected it from a single disk failure. It held about 5.83 TB: roughly 2.8 TB of MP4 video, 1.4 TB of camera RAW files, 1.1 TB of MKV, and smaller amounts of music, JPEG and HEIC. We wanted to rebuild it with redundancy, and that meant formatting it. Before that we needed a complete copy elsewhere, with checksums proving it matched.

The Google account involved already had plenty of unused paid Drive storage. Using space we were already paying for looked like the obvious move, and rclone supports Drive well, including MD5 checksums to verify uploads. So we started there.

Step 1: the shared rclone client is not for bulk uploads

Our first tests used an existing rclone remote that relied on rclone’s built-in OAuth client ID. rclone prints a warning about this on every run: the shared client ID “is being retired and will stop working during 2026”. The rclone docs also note that the default quota allows about 10 transactions per second, and that quota is split across everyone using that client.

What we measured from a machine on a wired line that tested at about 870 Mbit/s each way:

Test Result
1 GiB file, one stream, shared client 366 s (about 2.9 MB/s). MD5 matched.
8 × 128 MiB files, --transfers 8, shared client 55 s (about 19.5 MB/s). 8/8 files matched.
8 × 256 MiB files, same settings, a bit later Only 2 files (512 MB) uploaded in 11 minutes. We killed it.
512 MiB, one stream, own client ID 22 s (about 23 MB/s)

The third row is why we stopped testing on the shared client. It isn’t consistently slow. It’s unpredictable, which is worse for a job meant to run every night for more than a week.

Creating our own client takes about ten minutes in the Google Cloud console: make a project, enable the Drive API, configure the OAuth consent screen, create a Desktop app client ID, and pass the ID and secret to rclone config (or rclone authorize drive <id> <secret> on a machine with a browser). One setting matters a lot here. The rclone docs warn that if the app stays in Testing, “any grants will expire after a week”. An eight-day upload would lose its token partway through. We published the app to Production. It’s unverified, so Google shows an “unverified app” warning on the consent screen. That’s expected when you’re the only user of your own app.

rclone config create gdrive-backup drive \
  client_id="<your-client-id>" client_secret="<your-client-secret>" \
  scope=drive token='<token-json-from-rclone-authorize>' --non-interactive
rclone about gdrive-backup:

We then installed the static rclone binary directly on the NAS (after checking its SHA256 against the published sums). That way the upload didn’t pass through a laptop, a VPN, or an SMB mount that might rewrite Unicode filenames. A 62 GB test folder (641 files) uploaded in 999 seconds, about 63 MB/s, and rclone check --one-way reported 0 differences and 641 matching files.

Step 2: the 750 GB/day limit decides the timeline

This is where the plan really broke down. There are two different limits on uploads, and they behave differently:

Limit Where it’s documented What hitting it looks like
Daily upload volume, about 750 GB per user per day Google’s Drive API limits page says Workspace users “can only upload 750 GB per day between My Drive and all shared drives”. rclone’s docs describe the same 750 GiB/day as “an undocumented limit”. Uploads get refused until the window resets, roughly a day later.
Request rate, per user per project per minute The same Google page lists per-minute quotas and returns 403: User rate limit exceeded or 429 when you exceed them. It recommends exponential backoff. Short bursts of 403s that go away when you slow down.

The daily cap is a fixed cost, whatever your bandwidth. Our earlier test with 8 parallel uploads already ran at 19.5 MB/s, more than double the 8.7 MB/s that 750 GB spread over 24 hours works out to. A faster line doesn’t help, and neither does a different upload tool. Drive for desktop, rclone mount and NAS sync apps all write through the same API, so they hit the same per-user cap.

The arithmetic:

5.83 TB / 0.75 TB per day  = 7.8 days minimum, if every day is used perfectly
5.83 TB / 650 GiB per day  ≈ 8.4 days with the safety margin we actually set

We set the nightly budget to 650 GiB with --max-transfer 650G --cutoff-mode soft, a bit under the cap, so a run could never trigger a 24-hour lockout. The plan also needed the NAS to keep reading for eight-plus days while still unprotected RAID0, with irreplaceable photos first in the queue.

Step 3: the flag that stopped our first run after five gigabytes

The nightly script ran rclone copy per share with these relevant flags:

rclone copy "/volume1/$share" "gdrive-backup:NAS-backup/$share" \
  --exclude "@eaDir/**" --exclude ".DS_Store" \
  --transfers 8 --checkers 16 --drive-chunk-size 64M \
  --max-transfer "$LEFT" --cutoff-mode soft --drive-stop-on-upload-limit \
  --create-empty-src-dirs --links --retries 5 --low-level-retries 20 \
  --use-json-log --stats 5m --log-file "$LOG"

The first full run started at 01:42. Its summary line, written at 01:46:52:

photos rc=7 bytes=4961574912
Failed to copy with 24 errors: last error was: googleapi: Error 403:
  User rate limit exceeded., userRateLimitExceeded

That’s 4.96 GB (4.6 GiB), nowhere near 650 GiB. Exit code 7 is rclone’s code for a fatal error that retrying won’t fix. That’s exactly what --drive-stop-on-upload-limit is supposed to produce when the daily cap is reached. But this wasn’t the daily cap. With 8 transfers and 16 checkers hitting the API at once, we had run into the per-minute request rate. Normally rclone would back off and retry.

The rclone source explains why it didn’t. In the Drive backend’s retry logic, a rateLimitExceeded or userRateLimitExceeded error is normally retried. But when --drive-stop-on-upload-limit is set and the error message is exactly User rate limit exceeded., rclone treats it as the upload-limit signal and makes it fatal. The docs warn about this too: the detection relies “on error message strings which Google don’t document so it may break in the future”. In our case Google used the same message for an ordinary rate limit, so the flag made a temporary 403 fatal.

We wrote a fix: drop the flag, lower to --transfers 6 --checkers 8, and add --tpslimit 8 --tpslimit-burst 16 to stay under the request quota, with --max-transfer still enforcing the daily budget. We never ran it. That same morning we decided to stop using Drive for this job altogether and reverted the script. If you’re using Drive for a large first upload, those are the changes we’d test. Just keep in mind that without the stop flag, a real daily-cap hit will keep retrying until the run ends or --max-transfer is reached.

The time math that made a local server the better choice

Compare the two options side by side, with the figures we had that morning:

Google Drive (own client) Backup server on the LAN
Bottleneck 750 GB/day per user 1 GbE NIC, about 110 MB/s
Full 5.83 TB copy 8–9 days of nightly runs about 15 hours (estimate)
Verification pass rclone check reads everything back through the API a local checksum pass, about another 15 hours
Restore after the NAS rebuild Download quota was not the limit in our tests (about 40 MB/s on a small sample); 1–2 days estimated same LAN speed as the copy
NAS at risk while copying 8+ days under a day

The deciding factor wasn’t cost. It was how long the NAS would sit on RAID0 with nothing behind it. One disk failure during a nine-day upload would lose whatever hadn’t been uploaded yet. A LAN copy shrinks that window to an overnight run. We’d already set up a rack server with RAID6 for other reasons, so we used it. The copy itself is written up in pulling a Synology NAS onto a Linux server with rsync. For context, the first rsync pass ran at about 110 MB/s from the start.

Drive’s paid storage is still useful, just not for this deadline. Once the NAS is rebuilt and restored, a slow nightly upload can trickle a second, off-site copy into Drive over a week or two without anyone waiting on it. The 66 GiB already uploaded (the 62 GB test folder plus the 5 GB from the failed run) stays where it is.

Checklist if you’re still going to use Drive

  • Make your own OAuth client and publish it to Production. Don’t rely on rclone’s shared client for anything big.
  • Upload from the machine that holds the data. A laptop over VPN or SMB adds hops, sleep problems and filename normalisation issues.
  • Budget per day below 750 GB with --max-transfer and --cutoff-mode soft, and schedule it to resume every night.
  • Be careful with --drive-stop-on-upload-limit at high concurrency. A per-minute 403 can carry the same message as the daily cap. Lower --transfers/--checkers and add --tpslimit, or leave the flag out and rely on --max-transfer.
  • Treat exit code 7 as “read the log”, not “the daily cap is reached”.
  • Do the timeline math before you start. If the source is at risk now, a local copy first and the cloud second is almost always the faster route to safety.
Sources
  1. rclone — Google Drive backend (upload limit, --drive-stop-on-upload-limit, own client_id)
  2. rclone source — backend/drive/drive.go (shouldRetry)
  3. Google Drive API — Usage limits
  4. rclone — Global flags and exit codes

Related