Introduction
After running flutter clean, a full rebuild can be extremely slow because it re-downloads all Dart packages from pub.dev, re-resolves Gradle dependencies, and potentially re-downloads CocoaPods. This is especially problematic on slow networks or in CI/CD pipelines. Understanding the caching layers involved and how to preserve them can dramatically reduce build times.
Symptoms
flutter pub gettakes several minutes afterflutter clean- Gradle downloads all dependencies from scratch:
`- Downloading https://services.gradle.org/distributions/gradle-8.4-all.zip
- ...
- > Task :app:compileDebugJavaWithJavac
`- CocoaPods re-installs all native dependencies:
`- Installing Firebase (10.18.0)
- Installing FirebaseCore (10.18.0)
- ...
`- CI builds taking 10+ minutes instead of 2-3 minutes
Common Causes
flutter cleanremoves.dart_tool/which triggers full pub get- Gradle cache cleared or not shared across builds
- CI/CD pipeline not caching dependency directories
PUB_CACHEenvironment variable pointing to non-persistent storage- Network issues causing repeated download failures
Step-by-Step Fix
- 1.Avoid flutter clean unless necessary:
- 2.```bash
- 3.# Instead of flutter clean, try:
- 4.flutter pub get # Usually sufficient after dependency changes
# Only use flutter clean when: # - Generated files are corrupted # - Switching between Flutter SDK major versions # - Experiencing mysterious build errors ```
- 1.Use PUB_CACHE for persistent package caching:
- 2.```bash
- 3.# Set persistent cache location
- 4.export PUB_CACHE=$HOME/.pub-cache
# Verify cache exists ls $PUB_CACHE/hosted/pub.dev/ | head -20 ```
- 1.Cache Gradle dependencies:
- 2.```bash
- 3.# Gradle caches to ~/.gradle/caches/ by default
- 4.# Ensure this is not cleaned between builds
- 5.ls ~/.gradle/caches/modules-2/files-2.1/ | head -10
# For CI/CD, cache these directories: # - ~/.gradle/caches/ # - ~/.gradle/wrapper/ ```
- 1.Cache CocoaPods on macOS:
- 2.```bash
- 3.# CocoaPods caches to ~/.cocoapods/
- 4.ls ~/.cocoapods/repos/
# Pre-install pods before CI build cd ios && pod repo-update && cd .. ```
- 1.For CI/CD pipelines (GitHub Actions example):
- 2.```yaml
- 3.- name: Cache Flutter dependencies
- 4.uses: actions/cache@v4
- 5.with:
- 6.path: /opt/hostedtoolcache/flutter
- 7.key: flutter-${{ hashFiles('**/pubspec.lock') }}
- name: Cache Gradle
- uses: actions/cache@v4
- with:
- path: |
- ~/.gradle/caches
- ~/.gradle/wrapper
- key: gradle-${{ hashFiles('/*.gradle*', '/gradle-wrapper.properties') }}
- name: Cache CocoaPods
- uses: actions/cache@v4
- with:
- path: ~/.cocoapods
- key: pods-${{ hashFiles('**/Podfile.lock') }}
`
- 1.Speed up pub get with offline mode when possible:
- 2.```bash
- 3.# If all packages are already cached:
- 4.flutter pub get --offline
# This fails if any package is not in cache, # which tells you exactly what is missing ```
Prevention
- Only run
flutter cleanwhen absolutely necessary - Set up CI/CD caching for pub cache, Gradle, and CocoaPods
- Use
--offlineflag for local builds when cache is complete - Keep
pubspec.lockin version control for deterministic resolution - Monitor dependency count with
flutter pub deps | wc -l - Use
flutter pub cache cleansparingly - only when cache is corrupted