appscript.dev
Automation Beginner Drive

Move stale files to cold storage

Archive Northwind Drive files untouched for a year into a `cold storage` folder.

Published Aug 1, 2025

Northwind’s working Drive fills up the way every shared Drive does: project folders never get cleared, and a year later you are scrolling past finished work to find the file you actually need. Nothing is wrong with the old files — they just do not belong in the active workspace any more.

This script sweeps the active area for files nobody has touched in a year and moves them into a single cold storage folder. The files are still in Drive, still searchable, still one click away — they are simply out of the daily line of sight. Run it monthly and the working folders stay lean on their own.

What you’ll need

  • The ID of your active root folder — the top of the area to sweep — and the ID of a cold storage folder to move stale files into. Keep cold storage outside the active root so the sweep never re-scans it.
  • Edit access to both folders. Moving files needs nothing more than DriveApp.
  • A clear idea of what “stale” means for Northwind. The default is 365 days since last update; adjust STALE_DAYS to taste.

The script

// Top of the area to sweep for stale files.
const ACTIVE_ROOT = '1abcActiveRootId';

// Folder that stale files are moved into. Keep it OUTSIDE the
// active root, or the sweep will re-scan its own archive.
const COLD = '1abcColdStorageId';

// A file is stale if it has not been updated in this many days.
const STALE_DAYS = 365;

// Milliseconds in a day — used to turn STALE_DAYS into a cutoff time.
const MS_PER_DAY = 86400000;

/**
 * Sweeps the active root for files untouched for STALE_DAYS and moves
 * each one into the cold storage folder.
 */
function archiveStaleFiles() {
  // 1. Work out the cutoff: anything last updated before this is stale.
  const cutoff = Date.now() - STALE_DAYS * MS_PER_DAY;
  const cold = DriveApp.getFolderById(COLD);

  // 2. Walk the whole folder tree from the active root.
  const moved = walk(DriveApp.getFolderById(ACTIVE_ROOT), cold, cutoff);
  Logger.log('Moved ' + moved + ' stale file(s) to cold storage.');
}

/**
 * Recursively walks a folder, moving stale files into cold storage and
 * descending into every subfolder.
 *
 * @param {Folder} folder The folder currently being scanned.
 * @param {Folder} cold The cold storage folder to move stale files into.
 * @param {number} cutoff Files last updated before this timestamp are stale.
 * @return {number} How many files this branch moved.
 */
function walk(folder, cold, cutoff) {
  let moved = 0;

  // 3. Check every file in this folder against the cutoff.
  const files = folder.getFiles();
  while (files.hasNext()) {
    const f = files.next();
    if (f.getLastUpdated().getTime() < cutoff) {
      f.moveTo(cold);
      moved++;
    }
  }

  // 4. Descend into each subfolder and add up what they move too.
  const subs = folder.getFolders();
  while (subs.hasNext()) {
    moved += walk(subs.next(), cold, cutoff);
  }

  return moved;
}

How it works

  1. archiveStaleFiles turns STALE_DAYS into a cutoff timestamp — the moment before which a file counts as stale.
  2. It opens the cold storage folder once and hands it down, so every move targets the same destination.
  3. walk is called on the active root and recurses through the whole tree.
  4. For each file, getLastUpdated() returns when it was last modified. If that is older than the cutoff, moveTo relocates the file into cold storage.
  5. walk then loops over every subfolder and calls itself, so nested project folders are swept just as thoroughly as the top level.
  6. Each call returns how many files its branch moved; the totals bubble up so archiveStaleFiles can log a single figure for the whole run.

Example run

Say the active root contains these files in mid-2026, with the cutoff at 365 days before today:

FileLast updatedAction
Q1 plan.gdoc2026-04-12Stays — recently updated
2024 audit.xlsx2024-11-03Moved to cold storage
Old logo drafts.zip2023-08-19Moved to cold storage
Client brief.gdoc2026-02-01Stays

After the run, the log reads Moved 2 stale file(s) to cold storage. The two old files are now in the cold storage folder, and the active root holds only work from the last year.

Trigger it

This is a tidy-up job that suits a monthly schedule:

  1. Set ACTIVE_ROOT, COLD, and STALE_DAYS for your Drive.
  2. In the Apps Script editor, open Triggers (the clock icon).
  3. Add a trigger: choose archiveStaleFiles, Time-driven, Month timer, and a day early in the month.
  4. Save. From then on, stale files drift into cold storage on their own.

Run archiveStaleFiles by hand once first and check the log, so you can see what the first sweep would move before you trust it to a schedule.

Watch out for

  • “Last updated” is not “last opened”. A file someone reads weekly but never edits still counts as stale. If that matters, this date-based rule is too blunt — Drive does not expose a reliable last-viewed time to Apps Script.
  • Keep COLD outside ACTIVE_ROOT. If cold storage sits inside the swept tree, the walk will re-scan it every run — harmless, but wasteful.
  • moveTo changes a file’s location, which can surprise collaborators who had it bookmarked by folder. The file keeps its ID, so direct links still work.
  • A file in several folders is moved out of all of them at once. Shared files with multiple parents can vanish from places you did not expect — sweep a test folder first.
  • A very large Drive can exceed the script runtime limit in one pass. If the run times out, sweep one subtree per run or raise STALE_DAYS so each sweep has less to move.

Related