CD vs Deployment

Master the difference between continuous delivery and continuous deployment, and know when each fits your pipeline.

Focus: continuous delivery vs deployment

Sponsored

You've automated your tests, your builds are green, and every commit to main produces a shiny new artifact. But then what? If a human still has to click a button to push that artifact to production, you've only solved half the problem. The real fork in the road is what happens after the build: do you stop and wait for approval, or do you let the pipeline drive all the way to production? That's the difference between continuous delivery and continuous deployment — two terms that get thrown around interchangeably, but which represent very different levels of automation, risk, and organizational maturity. By the end of this lesson, you'll not only know the difference, but you'll be able to look at any pipeline and instantly classify it, and you'll know which approach is right for your team.

The problem this lesson solves

Every team I've worked with has had the same argument at some point: "Our CI/CD is fully automated!" — and then you look at the pipeline and see a manual approval gate before production. That's not continuous deployment, and sometimes it's not even continuous delivery. The confusion isn't academic; it causes real problems:

  • Miscommunication: Stakeholders think features ship immediately; developers think there's a review process. Someone's expectations are wrong.
  • False automation: You've automated the build, but the hardest part — getting code to users — is still manual, so you haven't actually saved much time.
  • Risk miscalculation: If you think you're doing continuous deployment but you have a manual gate, you're carrying unnecessary risk (or unnecessary delay).

If you can't clearly articulate the difference, you can't make deliberate choices about your release process. You'll end up with a pipeline that's neither fish nor fowl — too automated for careful staging, too manual for true speed.

Core concept / mental model

Think of your software delivery process as a pipeline with a final gate. The gate can be a person or a button. The key distinction is who — or what — controls the last step.

  • Continuous delivery means every change is automatically built, tested, and prepared for release to production. A human then decides when to release. The pipeline stops at the "ready to ship" stage.
  • Continuous deployment means every change that passes all automated tests is automatically released to production. No human in the loop at the final stage.

A useful analogy: think of a restaurant kitchen. Continuous delivery is the kitchen that plates every dish perfectly and leaves it at the pass for the server to pick up. The server decides when it goes to the table. Continuous deployment is the kitchen that uses a conveyor belt — dishes zoom straight from the chef to the customer's table with no one checking them.

Pro tip: If there's a "Deploy to Production" button that a human clicks, it's continuous delivery. If there's no button — only automation — it's continuous deployment. That's the 10-second test.

The mental model breaks down into three layers:

  1. Continuous integration (CI): Code is automatically built and tested on every push.
  2. Continuous delivery (CD): Code is automatically ready for release — packaged, deployed to staging, and validated.
  3. Continuous deployment (also CD, confusingly): Code is automatically released to production.

So, yes, both are abbreviated "CD" — which is why the confusion persists. The words matter: delivery is about being able to release; deployment is about actually releasing.

How it works step by step

Let's trace a typical pipeline and see where the two approaches diverge.

The common pipeline (up to the staging gate)

  1. Push — A developer pushes a commit to the shared repository.
  2. Build — The CI server compiles the code, runs unit tests, and packages the artifact.
  3. Test — The artifact is deployed to a staging environment, and integration tests, smoke tests, and sometimes user-acceptance tests run automatically.
  4. Artifact store — The tested artifact is versioned and stored (e.g., in a container registry or artifact repository).

Continuous delivery: the human gate

  1. Approval — A human (release manager, or via a ticketing system) reviews the artifact and decides to release.
  2. Production deploy — The approved artifact is deployed to production, potentially through a scripted process, but the trigger is human.

Continuous deployment: the automatic gate

  1. Automatic release — If all tests pass, the pipeline automatically deploys the artifact to production.
  2. Monitoring — A rollback might be triggered automatically if metrics (e.g., error rate) exceed thresholds, but the initial deploy is fully automated.

The cause-and-effect chain is the same until step 4. The fork is: human decision vs. automated decision.

Hands-on walkthrough

Let's make this concrete with a GitHub Actions example. We'll create a simple Python app and show two pipeline variants.

Continuous delivery pipeline (with manual approval)

Here's a snippet that builds and tests, then stops for a human before a "production" deploy:

name: CI - Delivery
on: [push]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      - run: pip install -r requirements.txt
      - run: pytest

  deploy-to-prod:
    needs: build-and-test
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - run: echo "Deploying to production..."

Notice the environment: production — if you set required reviewers on that environment in GitHub, it creates a manual approval gate. Without reviewers, it would auto-deploy.

Continuous deployment pipeline (fully automated)

For continuous deployment, we simply remove the manual gate. We can also add automatic rollback logic:

name: CI - Deployment
on:
  push:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      - run: pip install -r requirements.txt
      - run: pytest

  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: echo "Deploying automatically to production!"
      - run: echo "Run smoke tests here"

To simulate a rollback, you could add a step that watches metrics and reverts if needed:

# rollback.py - pseudo-code
import requests

def check_health(url):
    try:
        r = requests.get(url, timeout=5)
        return r.status_code == 200
    except:
        return False

if not check_health("https://prod.example.com/healthz"):
    print("Health check failed - rolling back...")
    # trigger rollback via API or script
else:
    print("Health check passed")

Both pipelines build, test, and deploy. The difference: in the first, a human must approve; in the second, it happens automatically.

Compare options / when to choose what

Aspect Continuous Delivery Continuous Deployment
Human in the loop Yes, at final stage No
Speed to production Fast, but gated Instant
Risk Lower, human reviews Higher, fully automated
Suitability Regulated industries, larger teams Startups, mature DevOps cultures
For example Finance, healthcare SaaS, internal tools
Rollback pressure Lower Higher – must be automated

Choose continuous delivery when:

  • You are in a regulated industry (finance, healthcare) where compliance requires a human sign-off.
  • You have a release train or schedule (e.g., only deploy on weekdays).
  • Your team loves automation but values the final human check.

Choose continuous deployment when:

  • Your tests are rock-solid and you have good monitoring.
  • Your organization is ready for rapid, frequent releases.
  • You want to eliminate the bottleneck of release managers.

Pro tip: You can start with continuous delivery and evolve to continuous deployment later. They're not mutually exclusive — they're points on a maturity spectrum.

Troubleshooting & edge cases

  • The "accidental" continuous deployment: You removed the manual gate but didn't add robust automated rollback. Fix: implement health checks and automatic rollback before going full continuous deployment.
  • Compliance conflicts: Some regulations require a human to approve production releases. In that case, continuous deployment is off the table. Work within the constraint (e.g., automate everything else but keep the final sign-off).
  • Flaky tests: If your test suite is flaky, continuous deployment will deploy broken changes. Fix: invest in test stability before turning on full automation.
  • "Environment" confusion: In GitHub Actions, environment: production alone doesn't create a gate — you must configure required reviewers. I've seen pipelines that looked like continuous deployment but were actually continuous delivery because of that default.

What you learned & what's next

You now can explain the core idea behind continuous delivery vs deployment: continuous delivery makes every change releasable, while continuous deployment actually releases it. You've completed a practical exercise (the GitHub Actions snippets) and you can identify which approach any pipeline uses. Next, you'll build on this foundation by learning about deployment strategies (blue-green, canary, rolling) in the next lesson — because once you've decided when to deploy, you need to choose how to deploy safely.

Practice recap

Take one of your existing pipelines and classify it: is it continuous delivery or deployment? If it's the former, try removing the manual approval gate and adding an automated rollback script. If it's the latter, add a health check that triggers a rollback on failure. Run it on a feature branch to see it in action.

Common mistakes

  • Treating the two as synonyms — they're not; a manual approval gate is the distinguishing factor.
  • Assuming environment: production creates a manual gate automatically; in GitHub Actions you must explicitly add required reviewers.
  • Moving to continuous deployment without automated rollback and health checks — you'll quickly learn the value of those.
  • Choosing continuous deployment in a regulated environment without checking compliance rules.

Variations

  1. Some teams use 'continuous delivery' to mean 'everything up to but not including production' — clarify internally.
  2. GitLab has an 'environments' feature that lets you set up manual approval at the environment level, similar to GitHub Actions' required reviewers.
  3. You can blend both: use continuous deployment to staging, and continuous delivery to production.

Real-world use cases

  • A fintech startup uses continuous delivery with a manual sign-off for every production release to meet PCI DSS compliance requirements.
  • A SaaS company with a mature testing suite and automated rollback uses continuous deployment to push feature flags to production several times per day.
  • A healthcare platform uses continuous delivery to staging for automated integration tests, but requires a human release manager for production go-lives due to HIPAA audits.

Key takeaways

  • Continuous delivery = automated build/test and ready for release, but a human clicks the final deploy button.
  • Continuous deployment = fully automated release to production after passing tests, with no human gate.
  • Both are abbreviated 'CD', but they're fundamentally different release philosophies.
  • Your choice depends on risk tolerance, compliance, and test maturity.
  • You can start with continuous delivery and evolve toward continuous deployment as your pipeline matures.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.