Rolling Deployments
Complete the full lesson to earn 25 points
Work through each section, then tap “Mark as Complete” on the last one.
✦ Skip the page breaks and see fewer ads — read each lesson on a single page with Pro
Implementing Zero-Downtime Deployments: Mastering Rolling Updates
In the modern landscape of software engineering, the ability to deliver updates without interrupting the user experience is no longer a luxury; it is a fundamental requirement. When users expect services to be available twenty-four hours a day, the traditional "maintenance window"—where a system is taken offline to install an update—is effectively dead. This lesson focuses on the rolling deployment strategy, a technique that allows engineers to update applications incrementally, ensuring that at least a portion of the system remains functional and responsive throughout the transition.
Understanding the Rolling Deployment Model
A rolling deployment is a strategy where an application update is applied to instances of a service one by one, or in small batches, until all instances have been updated. Instead of replacing the entire fleet of servers at once, the deployment process gradually replaces old versions with new ones. This approach is inherently safer than a "big bang" deployment because it reduces the blast radius of a failed release. If something goes wrong, only a fraction of the users are affected, and the process can be halted before the entire infrastructure is compromised.
The primary goal of a rolling deployment is to maintain availability while shifting traffic from the old version of the software to the new one. This requires a load balancer or a service mesh to act as a traffic controller, directing incoming requests to the healthy, updated instances while draining connections from the instances that are being phased out. The complexity of this process often lies in the coordination between the infrastructure layer, which manages the servers or containers, and the application layer, which must handle the transition of state and data.
Callout: The Philosophy of Incremental Change Rolling deployments are rooted in the principle that change is most manageable when it is small and predictable. By decoupling the deployment of code from the availability of the service, you shift the focus from "how do we minimize downtime" to "how do we maintain continuous availability." This shift in perspective is the hallmark of mature engineering teams that prioritize reliability over aggressive, risky update cycles.
The Mechanics of a Rolling Update
To understand how a rolling update functions in practice, we must look at the lifecycle of a single instance during the transition. Imagine a service running five identical containers. When a new version is released, the orchestration engine—such as Kubernetes—begins the rolling update process. It starts by spinning up a new container with the updated image. Once that container passes its health checks, the load balancer adds it to the pool of active, traffic-receiving instances.
Simultaneously, the orchestration engine marks one of the old containers for termination. Before it is shut down, the system must ensure that the container is no longer processing active requests—a process known as "connection draining." Once the old container has finished its pending tasks, it is removed, and the process repeats for the remaining instances. This cycle continues until every old container has been replaced by a new one.
Key Phases of the Rollout
- Preparation: The system validates the new image and ensures that the required resources (CPU, memory) are available in the cluster.
- Provisioning: A new instance (or batch of instances) is launched using the updated configuration.
- Health Verification: The system monitors the new instance. It must pass readiness probes before it is allowed to accept traffic.
- Traffic Shifting: The load balancer updates its routing table to include the new instance and remove the old one.
- Decommissioning: The old instance is signaled to stop accepting new requests, completes its remaining work, and is then terminated.
Practical Implementation: Kubernetes Example
Kubernetes has built-in support for rolling updates through its Deployment object. When you update the container image in a deployment manifest, Kubernetes automatically initiates a rolling update. The configuration is defined in the spec.strategy section of your YAML file.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-application
spec:
replicas: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
spec:
containers:
- name: app
image: my-app:v2.0.0
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
In this example, maxSurge determines how many extra pods can be created above the desired number of replicas, while maxUnavailable determines how many pods can be unavailable during the update. By setting maxUnavailable to 0 and maxSurge to 1, we ensure that we always have the full capacity of five pods available, with one extra pod being created before an old one is removed.
Note: Always define a
readinessProbe. Without it, Kubernetes might route traffic to your new container before the application is fully started or before it has established a connection to the database. This would result in "503 Service Unavailable" errors for your users.
Essential Best Practices
Implementing rolling deployments is not just about the technical configuration; it is about the discipline of your development and operations pipeline. If you do not follow these best practices, you risk breaking your system even while using the correct tools.
1. Backward Compatibility is Non-Negotiable
Since you will have two versions of your application running simultaneously during the deployment, your code must be backward compatible. This is particularly important for database schema changes. If your new version changes a column name in the database, the old version will crash. Always perform database migrations in a way that supports both the old and new code versions simultaneously. Usually, this means adding new columns rather than renaming existing ones, and handling the cleanup in a subsequent deployment.
2. Implement Robust Health Checks
A health check is the heartbeat of a rolling deployment. If your application reports that it is "healthy" even when it is failing to connect to its dependencies, the orchestrator will happily route traffic to it, leading to a cascading failure. Ensure your health checks are comprehensive; they should verify connectivity to databases, caches, and third-party APIs.
3. Monitor Your Deployment Metrics
During the rollout, observe your error rates, latency, and resource consumption. If you notice a spike in 5xx errors, you must have an automated way to stop the deployment. Many modern platforms offer "automated rollbacks," which detect performance degradation and revert the cluster to the previous known-good state without human intervention.
4. Optimize Startup Time
If your application takes a long time to boot, your rolling deployment will take significantly longer to complete. In a high-traffic environment, a slow rollout increases the duration of the transition, which extends the period during which you have "mixed" traffic. Focus on optimizing your application's startup sequence to keep the rollout window as short as possible.
Comparing Deployment Strategies
To understand where rolling deployments fit, it is helpful to compare them to other common deployment patterns.
| Strategy | Downtime | Risk | Complexity | Resource Usage |
|---|---|---|---|---|
| Recreate | High | Low | Low | Low |
| Rolling | None | Medium | Medium | Medium |
| Blue/Green | None | Low | High | High |
| Canary | None | Very Low | High | Medium |
- Recreate: You shut down all old instances and then start the new ones. It is simple but causes downtime.
- Rolling: You replace instances incrementally. It is a balanced approach for most standard web applications.
- Blue/Green: You maintain two identical production environments. You switch traffic from one to the other. It is fast but expensive, as it requires double the infrastructure.
- Canary: You route a small percentage of traffic to the new version to test it on real users before a full rollout. It is the safest method but requires sophisticated traffic management.
Callout: The "Big Bang" vs. The "Rolling Wave" The "Recreate" strategy is the equivalent of a "big bang" deployment—everyone feels the impact at once. Rolling deployments function like a "rolling wave," where the change moves through the system. Choosing between them depends entirely on your tolerance for downtime. If you have an internal tool used by five people at 2:00 AM, a "Recreate" strategy is perfectly fine. If you run a global e-commerce site, you must use rolling, blue/green, or canary deployments.
Common Pitfalls and How to Avoid Them
Even with the best tools, rolling deployments can fail. Being aware of these pitfalls allows you to build more resilient processes.
The "Stuck" Deployment
A common issue is a deployment that hangs indefinitely. This usually happens because the new pods fail their readiness probes, preventing the orchestrator from moving to the next step.
- Solution: Set strict timeouts on your deployments. If a deployment does not complete within a specific window (e.g., 10 minutes), the system should automatically fail and trigger an alert.
Database Connection Exhaustion
When you spin up new instances, they all attempt to connect to the database simultaneously. If your database connection pool is small, the new instances might consume all available slots, causing the old instances to lose their connectivity.
- Solution: Use a database connection pooler (like PgBouncer for PostgreSQL) and ensure your application's connection settings are tuned to handle the temporary increase in instances during the rollout.
Inconsistent Configuration
Sometimes, the environment variables or secrets injected into the new pods are slightly different from the old ones. This is often caused by manual changes made to the live environment that were not committed to the configuration repository.
- Solution: Enforce "Infrastructure as Code." Never make manual changes to the production environment. If a change is needed, update the configuration file and trigger a new deployment.
The Problem of "Sticky" Sessions
If your application relies on session affinity (the user is locked to a specific server), a rolling deployment can cause user sessions to drop when their assigned server is terminated.
- Solution: Move session state out of the application memory and into a distributed store like Redis. If the application is stateless, the user will not notice when their request is routed to a different instance.
Step-by-Step: Executing a Rolling Deployment
Let us walk through the process of executing a rolling deployment using a cloud-native approach.
- Code Commit and Build: Developers push code to the repository. The CI/CD pipeline runs unit and integration tests. If successful, it builds a container image and pushes it to a private container registry.
- Manifest Update: The CI/CD pipeline updates the image tag in the Kubernetes deployment file (e.g., changing
v1.0.0tov1.1.0). - Apply Configuration: The pipeline runs
kubectl apply -f deployment.yaml. - Observation: The orchestrator begins the rolling update. You monitor the rollout status using
kubectl rollout status deployment/web-application. - Verification: Once the rollout completes, you perform a "smoke test" or automated functional test against the production environment to ensure that the user-facing features are working as expected.
- Rollback Readiness: If errors appear in the logs, you immediately execute
kubectl rollout undo deployment/web-application. This command instructs the orchestrator to revert the deployment to the previous revision.
Advanced Configuration: Handling Traffic Draining
Properly shutting down an instance is just as important as starting one up. When an instance is marked for termination, it should not simply cut off existing connections. If it does, any user currently in the middle of a transaction will experience a failure.
You should configure your application to handle SIGTERM signals. When Kubernetes terminates a pod, it sends a SIGTERM signal to the process. Your application should catch this signal, stop accepting new requests, and wait a few seconds for existing requests to complete before exiting.
// Example: Node.js graceful shutdown
process.on('SIGTERM', () => {
console.log('SIGTERM received. Closing HTTP server...');
server.close(() => {
console.log('HTTP server closed.');
process.exit(0);
});
});
By adding this logic, you ensure that the rolling deployment is truly "zero-downtime" for the users who are currently interacting with the system. Without graceful shutdown, you are essentially performing a "near-zero" downtime deployment where a small number of users will always experience errors during the transition.
Dealing with Long-Running Tasks
If your application processes long-running jobs (like video transcoding or large report generation), a standard rolling deployment can be problematic. If you kill a pod while it is in the middle of a job, that work is lost.
To solve this, implement a "draining" period. In Kubernetes, you can set the terminationGracePeriodSeconds in your pod spec to a longer value, such as 300 seconds (5 minutes). This gives your application enough time to finish a job before the orchestrator forcefully kills the container.
spec:
terminationGracePeriodSeconds: 300
containers:
- name: app
...
This ensures that even if you have long-running background tasks, your deployment remains clean and your data remains consistent.
The Human Element: Communication and Culture
Deployment strategies are as much about people as they are about technology. A team that is afraid to deploy will deploy less frequently, leading to larger, more dangerous releases. Rolling deployments provide the safety net that allows teams to deploy multiple times a day.
However, this requires a culture where failures are treated as learning opportunities rather than reasons for punishment. If a deployment fails, the focus should be on "why did our health checks not catch this?" or "why did our monitoring not alert us?" rather than "who broke the production environment?"
Key Performance Indicators (KPIs) for Deployments
- Deployment Frequency: How often do you successfully release to production?
- Lead Time for Changes: How long does it take from code commit to running in production?
- Change Failure Rate: What percentage of your deployments require a rollback?
- Mean Time to Recovery (MTTR): How quickly can you restore service after a failure occurs?
By tracking these metrics, you can refine your rolling deployment strategy over time, making it faster, safer, and more predictable.
The Future of Deployments: Beyond Rolling
While rolling deployments are the gold standard for many teams, the industry is moving toward even more sophisticated patterns like "Progressive Delivery." This involves using feature flags to decouple the deployment of code from the release of features. You deploy the code to production in a disabled state, then "turn on" the feature for a small subset of users.
This allows you to test code in the production environment without actually exposing it to the public. If the feature causes issues, you flip the switch off instantly. This is the ultimate evolution of the rolling deployment—combining the safety of incremental infrastructure updates with the precision of feature-level control.
Comprehensive Key Takeaways
- Maintain Availability: The primary goal of a rolling deployment is to ensure the application remains reachable throughout the entire update process by replacing instances incrementally.
- Graceful Shutdowns: Always implement signal handling (
SIGTERM) in your application to allow it to finish ongoing requests before shutting down, which prevents errors during the transition. - Health Checks are Mandatory: A rolling deployment is only as safe as your health checks. Ensure they are thorough and verify the health of all upstream dependencies, not just the application process.
- Database Compatibility: Since old and new versions run simultaneously, database changes must be backward compatible. Avoid destructive changes that would break the older version of your application.
- Automated Rollbacks: Build your pipeline to detect failures automatically and revert to the previous version. Manual intervention is too slow to prevent widespread impact during a bad release.
- Infrastructure as Code: Keep your environment configurations in version control. Never make manual changes to a production environment, as this creates "configuration drift" that complicates rollouts.
- Monitor the Transition: Use observability tools to watch your error rates and performance metrics during the rollout. The period of "mixed" traffic is the most vulnerable time for your service.
By mastering the rolling deployment, you provide your organization with the ability to move quickly without compromising stability. It is a foundational skill that separates high-performing engineering teams from those that are constantly struggling with service outages. Remember that the goal is not just to update the code, but to keep the business running flawlessly while you do it.
Common Questions (FAQ)
Q: Can I use rolling deployments for stateful applications? A: Rolling deployments are designed primarily for stateless applications. If your application stores data locally on the disk, a rolling update will cause data loss or inconsistency. For stateful applications (like databases), you should use specialized operators or patterns like replicas and leader-election to manage data migration safely.
Q: How many instances should I update at once? A: This depends on your traffic and risk tolerance. Updating one instance at a time is the safest, but it takes the longest. Updating in batches (e.g., 20% of your fleet) is faster but riskier. Start with a small batch and increase the size as your confidence in your testing and monitoring grows.
Q: What if I have a dependency on a legacy system that doesn't support concurrent versions?
A: This is a classic challenge. If your backend cannot handle two versions of an API, you must implement a "versioned API" strategy where your backend supports both v1 and v2 simultaneously. If the legacy system cannot be changed, you may be forced to use a "Recreate" strategy or a maintenance window for that specific component.
Q: Is a rolling deployment suitable for mobile applications? A: No. Rolling deployments are a server-side strategy. Mobile applications are updated via the user's device, and you cannot force a user to update their app. You must ensure your server-side APIs remain compatible with older versions of your mobile app, typically by supporting multiple API versions at the same time.
Enjoying the courses?
Everything stays free. Pro shows fewer ads, doubles your daily points limit so you progress twice as fast, and lets you read each lesson on one page.
- ✓ Fewer advertisements
- ✓ 2× daily points limit
- ✓ Distraction-free lessons