Zero-Downtime Deployment on AWS for Warehouse Software
How to deploy warehouse software updates on AWS without downtime: blue-green, rolling, and canary patterns, plus safe database migration discipline.

On this page15 sections
Part of the Scalable WMS Architecture guide. This deep-dive expands on the deployment section of the pillar.
A warehouse does not have a maintenance window. Pickers are working a late shift in one timezone while another site is just starting, trucks are loading, and an order placed online thirty seconds ago is already being allocated. Taking a WMS offline to ship an update is not an inconvenience, it is lost throughput and missed shipments. So zero-downtime deployment is not a nice-to-have for warehouse software, it is a baseline requirement. This guide covers the deployment patterns that deliver it on AWS, and the database discipline that is the real hard part.
We deploy our own systems on AWS, with the API running on EC2, PostgreSQL on RDS, and object storage on S3, so the patterns below are described in that context. They are not unique to AWS, but the AWS building blocks make them concrete.
Zero-downtime is mostly a database problem
Here is the truth that surprises people: swapping application servers without downtime is largely a solved problem with the right pattern. The part that actually breaks deployments is the database, because the database is shared state that both the old and new versions of your code touch at the same time during a rollout. Get the app-server choreography right and a bad migration will still take you down. So we will cover the deployment patterns, but the section that matters most is the one on migrations.
This is also where our experience is most concrete. On Lorecs, our five-year supply chain engagement, we migrated the platform from .NET Core 2.1 all the way to .NET 9 without disrupting live operations, on a system running real orders, shipments, and multi-currency invoicing the whole time. On Kragworks, our AgTech modernization, we took the stack from Angular 7 and .NET Core 2.1 to Angular 17 and .NET 8 while keeping production stable for fruit growers depending on it daily. Neither of those was possible by taking the system down. They were possible because every change was made backward-compatible first, which is the same discipline a routine zero-downtime deploy depends on.
The deployment patterns
Rolling deployment
The default for most services. Instead of replacing all instances at once, you replace them a few at a time. On AWS, an Application Load Balancer sits in front of a group of instances, and during a rollout new instances come up, pass health checks, start receiving traffic, and old ones are drained and retired in batches. At every moment there is a healthy pool serving requests.
Rolling is simple and resource-efficient, and it is what we reach for first. Its one demand is that the old and new versions must coexist, because for the duration of the rollout both are live and serving real users at the same time. That coexistence requirement is the thread running through this entire post.
Blue-green deployment
Two complete environments: blue (current, live) and green (the new version). You deploy and fully test green while blue serves all production traffic, then cut traffic over from blue to green in one switch, usually at the load balancer. If something is wrong, you switch back to blue instantly, which makes rollback close to free.
Blue-green gives the cleanest rollback story and the most confidence, at the cost of running two environments during the deploy. It shines for higher-risk releases where the ability to revert in seconds is worth the extra capacity. The same coexistence rule applies with a twist: blue and green often share one database, so that database has to be compatible with both versions across the cutover.
Canary release
A refinement of either pattern: instead of sending all traffic to the new version at once, you send a small slice, say five percent, watch error rates and latency, and ramp up only if the metrics stay healthy. Canary catches the bug that only shows up under real traffic before it reaches everyone. It needs good monitoring to be meaningful, because the whole point is to make the promotion decision on live signals, not hope.
| Pattern | Rollback speed | Resource cost | Best for |
|---|---|---|---|
| Rolling | Moderate (roll forward or back in batches) | Low | Routine releases |
| Blue-green | Instant (flip back to blue) | Higher (two environments) | Higher-risk releases needing fast revert |
| Canary | Fast (stop the ramp) | Low to moderate | Validating risky changes under real traffic |
The hard part: backward-compatible migrations
Every pattern above shares one non-negotiable rule, and it is the rule teams break: during a deployment, the old and new code run against the same database simultaneously. A migration that the old code cannot tolerate will break the old version the instant it runs, and a migration the new code needs but that has not run yet will break the new version. The only safe path is to make every schema change backward-compatible, and the technique for that is expand and contract.
Take the common case of renaming a column from qty to quantity. The destructive version, rename it in one migration, breaks the running old code the moment it deploys. The expand-and-contract version is a sequence across releases:
- Expand. Add the new
quantitycolumn. Do not touchqty. Both old and new code still work; old readsqty, and nothing yet readsquantity. - Migrate and dual-write. Deploy code that writes to both
qtyandquantityand backfill existing rows. Now the two columns agree, and either version of the code is safe. - Switch reads. Deploy code that reads from
quantity. The old column is still written but no longer read. - Contract. Once no running code references
qty, a later release drops it.
It is more steps, and that is the point. Each step is independently safe to deploy and to roll back, so a schema change never requires both the migration and the code to land in the same instant. This is precisely the discipline that let us move Lorecs across eight major framework versions and Kragworks across a full stack upgrade without a maintenance window: change the data layer in compatible increments, never in a single breaking leap. The same rule covers adding a non-null column (add it nullable with a default first, backfill, then tighten) and removing one (stop reading, then stop writing, then drop).
We run our migrations through a reviewed, ordered process rather than ad hoc schema edits, and the workspace rule is firm: migrations are never destructive in a single step and are inspected before they touch a live database. That review is what keeps the expand-and-contract sequence honest.
The other things that quietly cause downtime
Servers and schema are the headline, but a few supporting details cause real outages when ignored.
- Health checks must mean something. The load balancer decides an instance is ready based on a health endpoint, so that endpoint must verify the instance can actually serve, including reaching its database, not just return
200 OKbecause the process started. A shallow health check sends traffic to a broken instance. - Drain connections gracefully. When retiring an instance, let in-flight requests finish before killing it. For a real-time WebSocket layer, that also means clients reconnect to a healthy instance cleanly, which is one more reason the server, not the socket, must own state.
- Keep long jobs out of the request path. Scheduled and background work should run where it will not be interrupted by an instance cycling, and should itself be safe to retry.
- Make releases idempotent and reversible. Every deploy should have a known rollback, and every data change should be safe to repeat, the same idempotency principle that governs ERP integration.
A pragmatic default
For most warehouse software, the combination that works is rolling deployments behind an Application Load Balancer with meaningful health checks, expand-and-contract migrations for every schema change, and a canary step for anything risky, with blue-green reserved for the high-stakes releases where instant rollback justifies running two environments. The exotic tooling matters far less than the discipline. We have delivered zero-downtime upgrades, including multi-year framework migrations on live systems, by being relentless about backward compatibility, not by owning a fancy pipeline.
From the author. "People think zero-downtime is about deployment tooling. It is mostly about the database. If every schema change is backward-compatible, so the old and new code can both run against it during the rollout, then almost any deployment pattern works and rollback is safe. We migrated Lorecs across eight major .NET versions on a live system that never stopped taking orders, and the secret was boring: expand, migrate, switch, contract, every single time. Get that right and downtime stops being something you schedule."
Nirmal J, Team Lead, WMS and Inventory Systems at Rorix Technologies
Where this fits
Deployment is the last mile of a scalable warehouse system, and it depends on the choices upstream. Backward-compatible migrations are easier when your data model is well-structured, and graceful instance cycling is safer when your real-time layer keeps the server authoritative. For how deployment fits with the data, real-time, and integration decisions in a system designed to scale, see the Scalable WMS Architecture guide. The takeaway: treat zero-downtime as a database discipline first, pick the deployment pattern that matches the risk, and make every change safe for the old and new versions to run side by side.
Frequently Asked Questions
How do you deploy a WMS update without taking it offline?
You use a deployment pattern that keeps a healthy pool serving traffic throughout the rollout, most commonly a rolling deployment behind a load balancer where new instances come up and pass health checks before old ones are drained. The harder requirement is the database: every schema change must be backward-compatible so the old and new versions of the code can both run against it during the rollout. With those two things in place, updates ship continuously without a maintenance window.
What is the difference between blue-green and rolling deployment?
A rolling deployment replaces instances a few at a time within one environment, which is resource-efficient and good for routine releases. Blue-green runs two complete environments, deploys and tests the new one while the current one serves traffic, then cuts over in a single switch, which makes rollback nearly instant at the cost of running two environments. Rolling is the everyday default; blue-green is worth the extra capacity for higher-risk releases where fast revert matters most.
Why are database migrations the hard part of zero-downtime deployment?
Because during a rollout the old and new code run against the same database at the same time, so any schema change that one version cannot tolerate breaks it immediately. A column renamed in a single step breaks the still-running old code the moment the migration applies. The solution is the expand-and-contract pattern, where you add the new structure, dual-write and backfill, switch reads, and only later remove the old structure, so every step is independently safe to deploy and roll back.
Can you do zero-downtime deployment on AWS specifically?
Yes. On AWS the common building blocks are an Application Load Balancer distributing traffic across instances with health checks that gate readiness, target groups for shifting traffic in a blue-green cutover, and RDS for the database where the migration discipline applies. We deploy our own systems this way, with the API on EC2, PostgreSQL on RDS, and storage on S3. The patterns are not AWS-specific, but these services make them straightforward to implement.
How do you roll back a deployment safely if something goes wrong?
The safest rollback comes from designing for it up front. Blue-green gives near-instant rollback by switching traffic back to the previous environment, and a canary release lets you stop the ramp before a bad version reaches everyone. The deeper safeguard is that every schema change is backward-compatible and every data change is idempotent, so reverting the application code never leaves the database in a state the old version cannot handle. Rollback should be a known, tested path, not an improvisation.
Building this into a live warehouse system?
Bring the constraint you keep hitting and a named engineer will walk the design with you.
Continue learning
Written by
Nirmal JTeam Lead, WMS & Inventory Systems, Rorix Technologies
Nirmal leads WMS and inventory software delivery at Rorix, from warehouse picking and stock control to real-time inventory tracking and fulfilment workflows. He manages project timelines, stakeholder alignment, and sprint execution, ensuring production-ready systems are delivered on time and keep operations running without disruption.
View full profileRelated articles

Barcode and RFID Integration Patterns in React
A practical guide to integrating barcode scanners and RFID readers with a React warehouse app: the four real connection patterns and when to use each.
Read article
WMS to ERP Integration: REST vs Message Queue
When to connect a WMS to an ERP over REST and when a message queue wins: the trade-offs, failure modes, and a pragmatic hybrid from a team that ships both.
Read article
PostgreSQL vs MongoDB for Warehouse Management: A 2026 Comparison from Engineers Who've Used Both
An honest, project-grounded comparison of PostgreSQL and MongoDB for warehouse management systems, from a team that runs both in production.
Read article