Why downtime is not acceptable
The days of planned maintenance windows are over. Users of SaaS applications expect 24/7 availability. Not as a luxury, but as a baseline. They log in when it suits them — at 9:00 AM on a Monday morning, but equally at 10:30 PM on a Sunday. An application that is unreachable at that moment does not just lose a session, it loses trust.
"Just five minutes of downtime" sounds harmless until it coincides with a traffic spike. A web shop that goes offline during a campaign. A scheduling system that is unreachable at the busiest moment of the day. A customer portal that goes down exactly when someone has a deadline. The damage is not just missed revenue — it is reputational damage that is hard to recover from.
Maintenance pages were once normal. "We are performing an update, please try again later." In 2026, that is no longer an acceptable answer. Users have alternatives, and they do not hesitate to use them. Every deployment that causes downtime is a risk you do not need to take — because the tooling to avoid it has existed for years.
How zero-downtime works
The principle behind zero-downtime deployments is straightforward: the old version keeps running until the new version is proven healthy. Only then is traffic switched over. There are multiple strategies to achieve this.
Blue-green deployments
With a blue-green deployment, you run two identical environments: blue (the current production version) and green (the new version). You deploy the update to green, verify everything works, and then switch traffic. Something goes wrong? You switch back to blue. Both environments stand ready; the switch is nearly instant.
Rolling deployments
With rolling deployments, you replace servers one at a time. While the first server is being updated, the remaining servers handle traffic. Once the first server is healthy, the second follows. This is more memory-efficient than blue-green because you do not need a complete duplicate environment, but it is more complex to implement correctly.
Atomic deployments with Laravel Vapor
Laravel Vapor takes it a step further. Every deployment creates a new version of your Lambda function. The old version remains active until the new version is fully provisioned — including warmed-up containers. The switch is atomic: one moment the old version serves your traffic, the next moment the new version does. There is no transition period where your application runs in a half-deployed state.
A deployment that causes your team stress is a deployment that is not properly set up. Releases should be routine, not an event.
Database migrations without downtime
Replacing application code is the easy part. The hard part is the database. Schema changes on a live database are where most zero-downtime strategies fail — unless you handle them deliberately.
Additive migrations
The golden rule: add, do not remove. Adding a new column to a table is safe. The existing code simply does not use that column until the new version goes live. Removing or renaming a column while the old code is still running is asking for trouble.
Two-phase migrations
Complex schema changes are split into multiple steps. Say you want to rename a column. Do not do this in one step. Instead:
- Phase 1: Add the new column. Deploy code that writes to both columns but reads from the old one. The old version of your code still works because the original column is unchanged.
- Phase 2: Migrate the data. Copy values from the old to the new column. Switch the code to read from the new column.
- Phase 3: Clean up. Remove the old column and the code that references it. This can happen in a subsequent release, when you are confident everything runs stably.
This feels cumbersome, but it is the only way to make schema changes without your application ending up in an inconsistent state. Every step is backward-compatible: the previous version of your code continues to function after each migration.
CI/CD pipeline
Zero-downtime deployments are only reliable when the entire process is automated. Manual steps introduce human errors — and that is exactly what you are trying to eliminate. A solid CI/CD pipeline is not a luxury but a requirement.
The steps
A typical pipeline for a Laravel application looks like this:
- Build — Install dependencies, compile assets, validate environment configuration.
- Test — Run unit tests, feature tests, and optionally integration tests. If a test fails, the deployment stops here. No exceptions.
- Deploy — The new version is rolled out to the target environment. With Vapor, this is a single command.
- Verify — Smoke tests on the live environment. Does the application respond? Are critical endpoints reachable? Do health checks pass?
If verification fails, automatic rollback follows. No Slack message to a developer who has to manually intervene. The pipeline recovers on its own and sends a notification that something went wrong. The team can investigate the problem without users being affected.
GitHub Actions is a strong choice for this: it integrates seamlessly with your repository, supports matrix testing for multiple PHP versions, and has native support for secrets and environment variables. The workflow definition lives in your repository, next to your code, under version control.
Laravel Vapor specifics
Vapor does not just make zero-downtime deployments possible — it makes them the default. Every deployment is zero-downtime by definition. That is not something you configure; it is how the platform works.
Atomic function versioning
With every deployment, Vapor creates a new version of your Lambda function. The old version remains available and serves traffic until the new version is fully configured. The switch happens via AWS API Gateway and is atomic: there is no moment when traffic goes to a half-deployed version.
Queue workers
Queue workers restart gracefully. Running jobs are completed before the worker switches to the new code version. No jobs are lost and no jobs are aborted mid-execution. SQS queues guarantee delivery, so even if a worker stops unexpectedly, the job is picked up again.
Asset versioning
Static assets (CSS, JavaScript, images) are served via CloudFront with unique hashes in the filenames. The new version of your application points to new asset URLs. Users who still have the old page open continue loading the old assets — no 404s or broken stylesheets. As soon as they reload the page, they get the new version.
No filesystem problems
Traditional deployments often struggle with shared filesystems: uploads that disappear, cache that becomes corrupt, session files that no longer match. Vapor eliminates this problem entirely. Files go to S3, cache to DynamoDB or Redis, sessions to an external store. Every Lambda invocation is stateless — there is nothing to lose.
When your team deploys on a Friday afternoon without hesitation, you know your deployment strategy is right.
Conclusion
Zero-downtime deployments are not rocket science. They require discipline in how you write migrations, an automated pipeline you trust, and tooling that facilitates atomic deployments. Laravel Vapor makes this trivial for Laravel applications, but the principles — additive migrations, automated testing, automatic rollback — apply regardless of your hosting environment.
The goal is not just eliminating downtime. The goal is creating a deployment culture where releases are routine. Where your team deploys with confidence, knowing there are automatic safety nets. Where a release on Tuesday at 2:00 PM is as normal as pushing a commit.
Want to professionalize your deployment process or switch to zero-downtime deployments? Coding Agency Meppel is happy to help you set up a pipeline that lets your team deploy faster and with more confidence.