Google Drive shared drives written by service accounts (the SA chain, corrected)
developers.google.com/workspace/drive/api/guides/about-shareCloud drivestorage/google-drive-shared-drives-written-by-service-accountsJSONcomparereport an errorprovider JSON
- Free allowance
- Service accounts now report storageQuota limit '0' — they cannot own files at all.
- Verdict
- caveatusable, with a named limit or an unprobed read path
- Cost
- free tier
- Identity
- institutionno card, no phone
- Binding limit
- per-ip-shaping750 GB/day; 1 TB/day
- Evidence
- reported4 sources; a third party said so
- Freshness
- stale on 2026-11-05checked 2026-10-21 (inherited); stale on 2026-11-05
| Free tier | Service accounts now report storageQuota limit '0' — they cannot own files at all. Real quota comes from the parent tenant: Education/Nonprofit 100 TB pooled, Business Standard 2 TB x users, Business Plus 5 TB x users. The '15 GB per SA x 100 SA x 30 projects = 45 TB' claim in the reference repo is DEAD. unit objects; metered on stored-bytes |
|---|---|
| Price | none stated |
| Limits |
SA quota limit = 0 (hard); shared drive 500,000 items / 100 nesting levels; 750 GB/day upload per user; 5 TB max file; Drive API 400,000,000 quota units/day/project before charges and a 1 TB/day egress cap; 1,000,000 units/min/project. |
| Binding | per-ip-shaping one stream is shaped, and a user's throughput is the shaped rate times the number of streams |
| Identity | institution not published |
| Egress | No per-GB egress charge for Drive file downloads; drive.usercontent.google.com serves direct bytes. New ceiling: Drive API 1 TB/day per project egress. |
| Per-object cap | not stated |
| Retention | not stated |
| Interface | rest, rclone rest |
| Tooling | rclone drive backend with service_account_file + shared drive config (rclone docs still document the SA + shared-drive path and warn its shared client_id is being retired during 2026 — make your own). gclone (156 stars, archived), AutoRcloneV2, 88lex/sa-gen (71 stars, last push 2023-05) automate SA creation but not the new shared-drive target. |
| Composes with | The chain inverted. Old: unlimited free SAs x 15 GB each. New: SAs are free and unlimited but hold zero bytes, so they become pure WRITE THROUGHPUT/multiplexer against one tenant's pooled shared drive. 750 GB/day is per acting identity, and each SA is a distinct identity, so N SAs lifting into one shared drive gives N x 750 GB/day ingest; the 100 TB pool is the actual ceiling. |
| Reliability | The widely-copied 45 TB recipe now returns 403 storageQuotaExceeded on every upload; every SA-based rclone tutorial written before ~2024 is wrong unless it targets a shared drive. Also reported: a hard ~16 GB SA limit when uploading into a *My Drive* folder shared with the SA (2024 SO thread) — shared drives are the only working target. |
| Parsed numbers |
|
Evidence 4
| date | source | what it proved |
|---|---|---|
| 2026-10-21 | developers.google.com/workspace/drive/api/guides/about-share | 'Service accounts don't have storage quota and can't own files. Instead, they must upload files and folders into shared drives, or use OAuth 2.0 to upload items on behalf of a human user.' |
| 2026-10-21 | discuss.google.dev/t/error-403-storagequotaexceeded-when-the | live API response quoted: {'storageQuota': {'limit': '0', 'usage': '0', 'usageInDrive': '0'}}; Google staff reply confirms SAs 'don't have storage quota and can't own any files' |
| 2026-10-21 | developers.google.com/workspace/drive/api/guides/limits | 'Per day per project | 1 TB' egress; 750 GB/day upload; 'maximum file size that users can upload is 5 TB'; 'Per day per project | 400,000,000 quota units' billing threshold |
| 2026-10-21 | www.googleapis.com/drive/v3/about | probe: GET -> 401 (unauthenticated; confirms no anonymous quota/metadata surface) |
Unknown values 5
$.identity_cost.detailboilerplate$.per_object_cap.notesthe field may be stated in a source that was not read$.per_object_cap.statedthe field may be stated in a source that was not read$.retention.notesthe field may be stated in a source that was not read$.retention.statedthe field may be stated in a source that was not read