Deploy GraphQL Federation with Confidence - WunderGraph

What You’ll Learn

This tutorial will teach you how to safely deploy subgraphs in a federated GraphQL architecture. We’ll start with the basics and build up to advanced deployment strategies, focusing on preventing production issues and maintaining system reliability.

Federation Basics

Understanding the core components and how they work together.

Safety First

Schema validation and preventing breaking changes.

Deployment Strategies

From simple deployments to advanced canary releases.

Production Ready

Monitoring, rollbacks, and operational best practices.


Understanding Federation Basics

Before diving into deployment strategies, let’s understand what we’re working with. GraphQL Federation allows you to split your API into independent services (subgraphs) while presenting a single, unified API to clients.

The Key Players

Subgraph
Your independent GraphQL service. Each subgraph owns a specific domain (like users, products, or orders) and can be developed, tested, and deployed independently by different teams.

Supergraph
The unified API clients see. This is the combined schema from all your subgraphs. Clients query this unified API without knowing about the underlying subgraph structure.

Router
The traffic director. The router receives client queries, figures out which subgraphs need to handle each part, and combines the results. It’s your single point of entry.

Schema Registry
Your safety net. The registry stores all schema versions, validates changes, and ensures your supergraph stays healthy. Think of it as your schema’s guardian.

Why This Matters for Deployment

Unlike deploying a single service, federated GraphQL requires coordination. When you change a subgraph:

  1. Schema compatibility - Your changes must work with other subgraphs.
  2. Timing matters - Deploy code first, then publish the schema.
  3. Router updates - The router needs the new schema to route correctly.
  4. Rollback complexity - Issues can affect the entire graph.

The Foundation: Schema Safety

Most production issues in federated GraphQL come from schema problems. Before learning deployment strategies, you need to master schema safety.

The Critical Rule: Validate Before Deploy

Never deploy schema changes without validation. The wgc subgraph check command is your first line of defense.

# Always run this before deploying
wgc subgraph check my-products-subgraph \
  --schema ./schema.graphql \
  --namespace production

What Gets Checked

Breaking Changes

Will this break existing clients? Removing fields, changing types, or modifying required arguments can break client applications.

Composition Validity

Can schemas merge successfully? Your schema must combine properly with all other subgraphs to create a valid supergraph.

Operations Analysis

Smart safety checks. Analyzes real client usage data to determine if a “breaking” change is actually safe in practice.

Schema Linting

Enforces best practices. Validates your schema follows GraphQL federation principles and your organization’s conventions.

Failed validation = Don’t deploy. If wgc subgraph check fails, fix the issues before proceeding. A failed check means your changes could break the entire graph or existing client applications. In rare cases, you can overwrite the check in the Cosmo Studio to proceed with the deployment. This can be useful when removing unused fields or types.

Environment Isolation

Use separate namespaces for complete isolation between environments:

dev namespace
├── Products Subgraph
├── Users Subgraph
├── Orders Subgraph
└── Federated Graph

For trying new features and schema changes without risk

stage namespace
├── Products Subgraph
├── Users Subgraph
├── Orders Subgraph
└── Federated Graph

Final validation before production - mirrors your live setup

prod namespace
├── Products Subgraph
├── Users Subgraph
├── Orders Subgraph
└── Federated Graph

Your live system serving real customers - requires maximum safety


Your First Safe Deployment

Let’s walk through a basic deployment that follows safety best practices.

Step-by-Step Process

  1. Validate Your Schema
    Before touching any infrastructure

    # Check against your target environment
    wgc subgraph check my-products-subgraph \
      --schema ./schema.graphql \
      --namespace development
    

    Only proceed if this passes without errors.

  2. Deploy Your Application Code
    Deploy the subgraph service first

    # Deploy to your infrastructure (example: Kubernetes)
    kubectl apply -f k8s/development/
    kubectl rollout status deployment/my-products-subgraph-dev
    

    Critical: Verify your service is healthy before the next step.

  3. Publish Your Schema
    Only after the service is running

    # Verify service health first.
    curl -f http://my-products-subgraph-dev.internal/health
    

Then publish the schema

wgc subgraph publish my-products-subgraph
--schema ./schema.graphql
--namespace development


4. **Verify Everything Works**  
**Test the complete integration**. Query your router to ensure the new schema is active and working correctly.

### Why This Order Matters

**Deploy Code → Publish Schema (Never the reverse)**  
If you publish the schema first, the router will try to send queries to resolvers that don’t exist yet. This causes immediate errors for your users.

---

## Router Configuration Strategies

The router needs to know about your schema changes. You have two main approaches:

### Dynamic Configuration

**Router fetches automatically.** The router polls Cosmo’s CDN for the latest schema. Simple setup with automatic updates.

**Best for**: Most deployments, especially when you want zero-downtime schema updates.

### Static Configuration

**Pre-built configuration.** Build the router config in CI and deploy it with your router. Full control but requires router redeployment.

**Best for**: Air-gapped environments or when you need strict control over when schema changes apply.

---

## Automated CI/CD Integration

Manual deployments don’t scale. Let’s automate the safety checks and deployment process.

### Basic CI/CD Pipeline

```yaml
name: Safe Subgraph Deployment

on:
  push:
 branches: [main]

jobs:
  deploy:
 runs-on: ubuntu-latest
 steps:
   - uses: actions/checkout@v4

# Step 1: Validate schema safety
   - name: Schema Safety Check
     run: |
       npm install -g wgc@latest
       wgc subgraph check my-products-subgraph \
         --schema ./schema.graphql \
         --namespace production
     env:
       COSMO_API_KEY: ${{ secrets.COSMO_API_KEY }}

# Step 2: Deploy application code
   - name: Deploy Service
     run: |
       kubectl apply -f k8s/production/
       kubectl rollout status deployment/my-products-subgraph --timeout=300s

# Step 3: Health check
   - name: Verify Service Health
     run: |
       curl -f http://my-products-subgraph.internal/health
     timeout-minutes: 2

# Step 4: Publish schema
   - name: Publish Schema
     run: |
       wgc subgraph publish my-products-subgraph \
         --schema ./schema.graphql \
         --namespace production
     env:
       COSMO_API_KEY: ${{ secrets.COSMO_API_KEY }}

Environment Promotion Strategy

Promote through environments in order: Remember: Always deploy your service code first, verify that it’s healthy, then publish the schema.

# Development first
wgc subgraph check my-subgraph --schema ./schema.graphql --namespace dev
# Deploy service to dev environment, then:
wgc subgraph publish my-subgraph --schema ./schema.graphql --namespace dev

# Then staging
wgc subgraph check my-subgraph --schema ./schema.graphql --namespace stage
# Deploy service to staging environment, then:
wgc subgraph publish my-subgraph --schema ./schema.graphql --namespace stage

# Finally production
wgc subgraph check my-subgraph --schema ./schema.graphql --namespace prod
# Deploy service to production environment, then:
wgc subgraph publish my-subgraph --schema ./schema.graphql --namespace prod

Advanced: Canary Deployments

Once you’ve mastered basic deployments, canary releases let you deploy with even greater safety by gradually shifting traffic to the new version.

Breaking Changes: This strategy is not suitable for releasing breaking changes. In general, you should avoid breaking your production graph (e.g., by removing/renaming a field or changing a type). Fields should be marked as @deprecated instead. Always use the wgc subgraph check command to validate your schema changes before deploying to production. The output of the check command will help you understand the impact of your changes and decide if you can release them safely.

Understanding Canary in Federation

A canary deployment in federated GraphQL is more complex than with typical services because:

Safe Canary Strategy

The safest approach uses separate environments for canary subgraph deployments:

Production Environment (90% traffic)
├── Products Subgraph v1.0
├── Users Subgraph v2.1
└── Orders Subgraph v1.5

Canary Environment (10% traffic)
├── Products Subgraph v1.1  ← New version being tested
├── Users Subgraph v2.1
└── Orders Subgraph v1.5

Benefits:

Implementing with Argo Rollouts

Here’s a production-ready canary setup:

# This resource defines the reusable job for publishing the subgraph schema.
# It is defined once and can be referenced by multiple Rollouts.
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: publish-subgraph-schema
spec:
  # This argument will be supplied by the Rollout during the analysis run.
  args:
    - name: image
    - name: namespace
    - name: subgraph-name
  jobs:
    - name: publish-schema
      template:
        spec:
          containers:
            - name: publisher
              # The image uses the specific tag of the version that was just promoted.
              image: "{{args.image}}"
              command: ["/bin/sh", "-c"]
              args:
                - |
                  # Best Practice: The 'wgc' CLI should be pre-installed in the Docker image.
                  # This command assumes 'wgc' is already in the PATH.
                  wgc subgraph publish {{args.subgraph-name}} \
                    --namespace {{args.namespace}} \
                    --schema /path/to/my/schema.graphql
              env:
                - name: COSMO_API_KEY
                  valueFrom:
                    secretKeyRef:
                      name: cosmo-secrets
                      key: COSMO_API_KEY
          restartPolicy: Never
      backoffLimit: 1
# This is the Rollout resource that orchestrates the deployment.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: my-products-subgraph
spec:
  # REQUIRED: This selector links the Rollout to the pods it manages.
  selector:
    matchLabels:
      app: my-products-subgraph
  replicas: 5
  strategy:
    canary:
            steps:
  - pause: {duration: 30s}  # Wait for router to poll new config (default: 10s)
  - setWeight: 10    # Increase to 10%
  - pause: {duration: 30s}
  - setWeight: 25    # Increase to 25%
  - pause: {duration: 1m}
  - setWeight: 50    # Increase to 50%
  - pause: {duration: 1m}
  - setWeight: 100   # Full rollout

# This hook runs AFTER the rollout is fully promoted to 100%.
      postPromotionAnalysis:
        templates:
          # Reference the AnalysisTemplate defined above.
          - templateName: publish-subgraph-schema
        args:
          # Pass the information to the AnalysisTemplate.
          - name: image
            value: "{{.spec.template.spec.containers[0].image}}"
          - name: namespace
            value: production
          - name: subgraph-name
            value: my-products-subgraph
  template:
    metadata:
      # REQUIRED: Pod labels must match the selector.
      labels:
        app: my-products-subgraph
    spec:
      containers:
      - name: app
        image: my-products-subgraph:1.2.0
        ports:
        - containerPort: 8080

Automated Rollback

If the postPromotionAnalysis step fails (for example, the health check or publish step fails), Argo Rollouts will automatically roll back the deployment to the previous stable version. This ensures that:

This automatic rollback mechanism protects your federation from broken deployments while maintaining the integrity of your overall graph.

Manual Validation Control: You can configure the rollout to pause at any step and perform complex health checks before proceeding. Use kubectl argo rollouts promote my-products-subgraph to continue with the post-promotion analysis. This gives you full control over when traffic shifts to the new version.

Timing Consideration: When using dynamic configuration, allow at least 20 seconds for the initial canary evaluation. The router polls for schema updates every 10 seconds by default ( configurable via poll_interval), so you need to account for this delay when the new schema is published. The example respects this already.


Monitoring and Observability

You can’t manage what you can’t measure. Proper monitoring is essential for safe deployments.

Essential Metrics

Error Rates

Track failures across the graph. Monitor both GraphQL errors and HTTP errors at the router and subgraph levels.

Latency

Measure performance impact. Track P50, P95, and P99 latencies to detect performance regressions.

Schema Usage

Understand client behavior. See which fields are used to make safe deprecation decisions.

Composition Health

Monitor graph integrity. Track schema composition success and supergraph generation.

Setting Up Observability

Router observability:
The Cosmo Router exports comprehensive metrics automatically through OpenTelemetry and Prometheus endpoints. For detailed setup and best practices, see:

# Router metrics are available at:
curl http://router:8088/metrics

Subgraph instrumentation: Each subgraph should be instrumented with OpenTelemetry to provide end-to-end observability across your federation. Subgraphs can:

The specific instrumentation approach depends on your subgraph’s technology stack (Node.js, Python, Go, etc.). Refer to the OpenTelemetry documentation for language-specific setup guides.


Best Practices Summary

Schema First

Always validate before deploy. Use wgc subgraph check on every change. Never skip validation.

Code Then Schema

Deploy in the right order. Deploy service code first, verify health, then publish schema.

Environment Isolation

Use separate namespaces. Keep dev, staging, and production completely isolated.

Automate Safety

Build checks into CI/CD. Make safety checks automatic, not manual processes.

Monitor Everything

Comprehensive observability. Track errors, latency, and schema usage across the entire graph.

Plan for Problems

Prepare for issues. Have rollback procedures and incident response plans ready.


What’s Next?

You now have the foundation for safely deploying federated GraphQL. As you gain experience:

  1. Experiment with advanced features like feature flags.
  2. Optimize your monitoring and alerting based on real usage patterns.
  3. Refine your canary deployment strategy for your specific needs.
  4. Share your learnings with other teams adopting federation.

Remember: Safety first, speed second. A robust deployment process might seem slower initially, but it prevents the much larger costs of production incidents and helps you move faster in the long run. Your federated GraphQL architecture is now ready to scale safely with your business needs.