Skip to content

Instantly share code, notes, and snippets.

@vonNiklasson
Last active January 13, 2026 00:03
Show Gist options
  • Select an option

  • Save vonNiklasson/b9d3c64ec8beb6a13a42e647012d4815 to your computer and use it in GitHub Desktop.

Select an option

Save vonNiklasson/b9d3c64ec8beb6a13a42e647012d4815 to your computer and use it in GitHub Desktop.
Remove old Google App Engine versions
#!/bin/bash
# A bash script to remove old versions of a Google App Engine instance.
#
# Inspiration of script taken from:
# https://almcc.me/blog/2017/05/04/removing-older-versions-on-google-app-engine/
# Original code by Alastair McClelland and Marty Číž.
# Assembled and modified by Johan Niklasson.
#
# To run this script, execute
# sh remove_old_gcloud_versions.sh <instance> <versions to keep>
# where <instance> is the instance type to filter (usuaylly default)
# and <versions to keep> is the number of versions to keep.
# The type of instance to filter on (usually default)
INSTANCE_TYPE=$1
# How many versions to keep, and throw away the rest
VERSIONS_TO_KEEP=$(($2 + 1))
# If you run a flexible environment, run this script instead as it will make sure that the instances are stopped before trying to remove them
#VERSIONS=$(gcloud app versions list --service $INSTANCE_TYPE --sort-by '~version' --filter="version.servingStatus='STOPPED'" --format 'value(version.id)' | sort -r | tail -n +$VERSIONS_TO_KEEP | paste -sd " " -)
# If you run the standard environment, you can't stop services and will always get an empty result if you run the command above.
VERSIONS=$(gcloud app versions list --service $INSTANCE_TYPE --sort-by '~version' --format 'value(version.id)' | sort -r | tail -n +$VERSIONS_TO_KEEP | paste -sd " " -)
# Don't try to delete old versions if there were no from the filtering.
if [ ${#VERSIONS} -gt 0 ]
then
# If you want to confirm before deletion, remove the -q
gcloud app versions delete --service $INSTANCE_TYPE $VERSIONS -q
fi
@evanvin
Copy link

evanvin commented Sep 17, 2020

LOVE THIS ❤️ thanks

@blakegearin
Copy link

Creating VERSIONS_TO_KEEP can be avoided by doing the addition operation inside VERSIONS, though the line gets so long it's not very readable.

VERSIONS=`gcloud app versions list --service $INSTANCE_TYPE --sort-by '~version' --format 'value(version.id)' | sort -r | tail -n +$(($2 + 1)) | paste -sd " " -`

@ajguyot
Copy link

ajguyot commented Jan 10, 2026

Update from 2026 where deleting old GAE versions manually from the CLI is still somehow required...

GCP keeps old versions of Flex environment GAE apps around in a non-stopped state for a while after a successful deploy (I'm guessing this is in case an automatic rollback is required). Since Flex is probably more common now, the commented out version of the script above is needed (NOTE: if you are not running Flex environment GAE instances then you should not use the scripts in this comment).

I set it up as a one-liner for our CI pipeline -- just add your GAE service name into the SERVICE_NAME variable (if it isn't "default") and set the number of versions you want to keep and it should work:

SERVICE_NAME=default; VERSIONS_TO_KEEP=3; VERSIONS_TO_DELETE=$(gcloud app versions list --service "$SERVICE_NAME" --filter="version.servingStatus='STOPPED'" --sort-by '~version' --format 'value(version.id)' | sort -r | tail -n +$VERSIONS_TO_KEEP | paste -sd " " -); if [ -n "$VERSIONS_TO_DELETE" ]; then gcloud app versions delete --service "$SERVICE_NAME" $VERSIONS_TO_DELETE --quiet; fi

I'd also recommend testing this script from your local command line first to make sure nothing has changed and that the action will still work. This just drops the delete command from the script above and echo's the expected output instead:

SERVICE_NAME=default; VERSIONS_TO_KEEP=3; VERSIONS_TO_DELETE=$(gcloud app versions list --service "$SERVICE_NAME" --filter="version.servingStatus='STOPPED'" --sort-by '~version' --format 'value(version.id)' | sort -r | tail -n +$VERSIONS_TO_KEEP | paste -sd " " -); echo $VERSIONS_TO_DELETE

Note one important caveat: I removed the + 1 from the tail -n command, which will result in it leaving one count fewer versions than the number you specify. This is on purpose as long as you're running this script from your CI pipeline. Since this script ignores the just-replaced version of your service after a deploy, the number of remaining versions that this script deletes from will already be one shorter than your target count, thus we let the tail command be "off by one" which should result in a correct final number once the just-shutdown version gets moved to full stopped status. The echo version of this script will likely have an off-by-one output because it is not running directly after a deploy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment