There is nothing more frustrating than pushing a critical hotfix only to realize your CI pipeline takes 15 minutes to run. When I first started scaling my Flutter apps, I treated the CI pipeline as a ‘black box’—I just waited for the green checkmark. But as the project grew, the wait became a productivity killer. If you’re wondering how to speed up flutter build times in ci, you’re not alone. The secret isn’t just ‘bigger runners’; it’s about smart caching and avoiding redundant work.
1. Implement Robust Dependency Caching
By default, most CI runners start with a clean slate. This means flutter pub get downloads every single package from scratch every time. I found that caching the .pub-cache folder can shave minutes off the initial setup.
# Example for GitHub Actions
- name: Cache Pub dependencies
uses: actions/cache@v3
with:
path: |
~/.pub-cache
.dart_tool
key: ${{ runner.os }}-pub-${{ hashFiles('**/pubspec.lock') }}
restore-keys: |
${{ runner.os }}-pub-
2. Leverage Remote Build Caching for iOS
iOS builds are notoriously slow because of CocoaPods and Xcode’s derived data. If you’re using a distributed team, look into remote build caching for ios. By sharing the build artifacts across different CI nodes, you avoid recompiling the same pods over and over again.
3. Split Your Pipeline into Parallel Jobs
Don’t run your tests, linting, and builds in a single linear sequence. I recommend splitting these into parallel jobs. For example, run flutter analyze and flutter test simultaneously while the build process starts in a separate container. This doesn’t reduce the total compute time, but it drastically reduces the ‘wall clock’ time you spend waiting.
4. Use Targeted Build Flavors
Stop building every flavor on every PR. I’ve set up my pipelines to only build the development flavor for feature branches and the production flavor only when merging into the main branch. This prevents the CI from wasting resources on heavy obfuscation and shrinking processes during routine development.
5. Optimize Docker Image Layers
If you’re using custom Docker images for your builds, ensure the Flutter SDK is installed in a separate layer from your application code. This ensures that unless you change the Flutter version, the SDK layer is cached and skipped during the build process. As shown in the image below, optimizing your layer sequence is key to fast startup.
6. Avoid ‘flutter clean’ in CI
Many developers add flutter clean to their CI scripts to ensure a ‘fresh’ build. In a local environment, this is great. In CI, it’s often redundant because the runner is already fresh, or worse, it destroys the very caches you worked so hard to set up. Remove it unless you are experiencing specific build ghosting issues.
7. Use a Specialized CI Tool for Flutter
While GitHub Actions and GitLab CI are great, they are generalists. I’ve had significantly better out-of-the-box performance using dedicated tools. If you want a more streamlined experience, I highly recommend following a Codemagic Flutter tutorial to see how their environment is specifically tuned for Dart and Flutter.
8. Optimize Android Build Gradle Settings
Android builds can be slowed down by excessive dexing. I’ve found that enabling the Gradle build cache and increasing the JVM heap size in gradle.properties makes a noticeable difference:
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m
org.gradle.caching=true
org.gradle.parallel=true
9. Implement Shorebird for Instant Updates
Sometimes the best way to speed up build times is to avoid the build pipeline entirely for small fixes. Instead of waiting for a full CI cycle and an App Store review, you can use Shorebird flutter push updates to push patches directly to users in seconds.
10. Use a Faster Runner Instance
It sounds simple, but sometimes the bottleneck is the CPU. Standard GitHub-hosted runners are often underpowered for heavy Flutter builds. Switching to a larger self-hosted runner or a ‘large’ instance on your CI provider can cut build times by 30-50% simply through raw compute power.
Common Mistakes to Avoid
- Caching too much: Caching the entire
build/folder can actually slow down your CI because the time it takes to zip/unzip a massive folder outweighs the time saved by the cache. - Ignoring warnings: If your
flutter analyzeis taking 3 minutes, you likely have circular dependencies or overly complex types that are slowing down the compiler. - Over-testing: Running the full integration test suite on every single commit. Move heavy tests to a nightly build.
Measuring Your Success
You can’t optimize what you don’t measure. I suggest adding a timing step to your CI logs. Most modern CI tools provide a ‘Job Duration’ graph. I track my P90 build time—the time under which 90% of my builds finish. If that number creeps up, it’s time to re-evaluate the cache keys.
Want more automation tips? Check out my other guides on productivity tools for developers and how to optimize CI/CD pipelines across different frameworks.