CI/CD Pipelines — Intermediate
Pipeline caching — the single biggest speed lever most teams underuse
A pipeline that reinstalls every dependency from scratch on every single run is slow by choice, not necessity. Every major CI/CD platform supports caching dependency directories (node_modules, .m2, ~/.cache/pip, Docker layer caches) keyed by a hash of the relevant lockfile — if the lockfile hasn't changed, the cache is reused and the install step drops from minutes to seconds. The practical impact compounds: a team running 50 pipeline executions a day with a 3-minute unnecessary reinstall each time is burning over 2 hours of pipeline time daily for nothing.
Parallelizing test suites
Once a test suite takes more than a few minutes, running it as one serial job is the wrong default. Most CI platforms support matrix builds — splitting a test suite across multiple parallel runners by test file, by shard index, or by browser/OS combination for cross-platform testing — turning a 20-minute serial run into a 4-minute parallel one across 5 runners. This is where "fast feedback" (the actual point of CI) starts requiring deliberate pipeline design, not just more automation.
Environment promotion: dev → staging → production
A mature pipeline doesn't deploy straight to production from a merge — it promotes the same, already-built artifact through a sequence of environments, with increasing confidence gates at each stage:
The critical detail people get wrong: it should be the same built artifact promoted through each stage, not a fresh build per environment — rebuilding per environment reintroduces the exact "it worked in staging but not prod" risk that environment promotion exists to eliminate (different dependency resolution, different build-time environment variables baked in, etc.).
Secrets management beyond "just use the platform's secrets store"
Basic secrets usage (GitHub Secrets, GitLab CI/CD variables) is fine for a single team on a single platform. It gets harder at intermediate scale:
Rollback strategy — the part most beginner pipelines skip entirely
Deploying is only half the pipeline design problem; "how do we undo this in under 2 minutes if it's bad" is the other half, and it needs to be designed before you need it, not improvised during an incident. Two common approaches: keep the previous artifact version available and support a one-click "redeploy previous artifact" pipeline (not a rebuild — a redeploy of something already known-good), or use a deployment strategy (blue-green, canary) where rollback is just "route traffic back to the previous, still-running version" rather than a redeploy at all.

