Every time you deploy code the traditional way, there's a brief window where your site is unavailable — files are being overwritten, caches are being cleared, and your users are hitting errors. For a personal blog, that's a minor inconvenience. For an eCommerce store processing orders or a SaaS application with paying customers, it can mean lost revenue and frustrated users.
Zero-downtime deployments eliminate this problem entirely. Instead of overwriting files in place, DeployHQ uses an atomic deployment strategy that keeps your current version running while preparing the new one, then switches over instantly.
In this guide, we'll walk you through how zero-downtime deployments work in DeployHQ, how to set them up, and which strategy is right for your project.
How Traditional Deployments Cause Downtime
In a standard deployment, files are uploaded directly to your live web root. During this process:
- Some files belong to the old version, some to the new
- Your application is in an inconsistent state
- Users may see errors, broken pages, or partial content
- If the deployment fails midway, you're left with a broken site
flowchart LR
A[Push Code] --> B[Upload Files to /var/www/html]
B --> C[Overwrite Old Files]
C --> D[Site in Mixed State]
D --> E[Users See Errors]
style D fill:#ff6b6b,color:#fff
style E fill:#ff6b6b,color:#fff
How Zero-Downtime Deployments Work
DeployHQ's atomic deployments use a completely different approach. Instead of overwriting your live directory, each deployment creates a new release directory and uses a symlink to switch between versions instantly.
Here's the directory structure DeployHQ creates on your server:
flowchart TD
ROOT["/var/www/mysite"] --> REL["releases/"]
ROOT --> SHARED["shared/"]
ROOT --> CACHE["cache/ (optional)"]
ROOT --> CURRENT["current → releases/20250731120000"]
REL --> R1["20250730080000/"]
REL --> R2["20250730150000/"]
REL --> R3["20250731120000/ (active)"]
style CURRENT fill:#28a745,color:#fff
style R3 fill:#28a745,color:#fff
releases/— Each deployment creates a new timestamped directoryshared/— Persistent files (uploads, logs,.env) that survive across releasescache/— Created when using the cache-based strategycurrent— A symlink pointing to the active release
The deployment flow looks like this:
sequenceDiagram
participant Dev as Developer
participant DHQ as DeployHQ
participant Srv as Server
participant Web as Web Server
Dev->>DHQ: Push to repository
DHQ->>Srv: Create new release directory
DHQ->>Srv: Upload changed files
DHQ->>Srv: Run post-deployment commands
DHQ->>Srv: Switch symlink to new release
Srv->>Web: Serve new version instantly
Note over Srv,Web: Zero downtime — old version<br/>served until symlink switches
The key insight is that your web server points to the current symlink. When the symlink switches, the transition is instantaneous — there's no window where files are in a mixed state.
Setting Up Zero-Downtime Deployments
Step 1: Create a New SSH Server
Zero-downtime deployments require an SSH server. When creating a new server in DeployHQ:
- Go to your project → Servers & Groups → New Server
- Select SSH/SFTP as the protocol
- Enter your server hostname, port, and credentials
- Enable Zero-downtime deployments
- Choose your deployment strategy (see below)
- Set how many releases to keep (default: 3)
Step 2: Choose Your Strategy
DeployHQ offers two atomic deployment strategies:
Strategy 1: Copy Previous Release
The previous release directory is duplicated, and only changed files are uploaded on top. This is faster for projects with many files since unchanged files don't need to be transferred again.
Best for: Large projects with many static assets, WordPress sites, content-heavy applications.
Strategy 2: Cache-Based
A clean cache directory is maintained with a copy of your repository. On each deployment, the cache is updated with the latest changes, then copied to a new release directory.
Best for: Projects where you want a clean copy every time, applications with complex build pipelines.
Step 3: Configure Your Web Server
Point your web server to the current symlink rather than a static directory.
Nginx example:
server {
root /var/www/mysite/current/public;
# ... rest of your configuration
}
Apache example:
DocumentRoot /var/www/mysite/current/public
<Directory /var/www/mysite/current/public>
AllowOverride All
</Directory>
Step 4: Set Up Shared Paths
Files that should persist across deployments (uploads, logs, environment files) should be placed in the shared/ directory. Configure shared paths in your server settings so DeployHQ automatically symlinks them into each new release.
Common shared paths include:
.envorconfig/database.yml— Environment configurationstorage/oruploads/— User-uploaded fileslogs/— Application logs
Step 5: Deploy
Run your first deployment. The initial deployment will be a full file transfer to establish the directory structure. Subsequent deployments will be incremental, only transferring changed files.
Server Group Deployments
If you're deploying to multiple servers (load-balanced environments, staging + production), DeployHQ supports parallel server group deployments for up to 3 servers at once.
With parallel deployments enabled, DeployHQ ensures all servers in a group complete each stage before moving to the next. This prevents a situation where some servers are running the new version while others are still on the old one.
For parallel deployments, the atomic strategy is recommended to ensure consistency across all servers.
Rollback Made Simple
One of the biggest advantages of zero-downtime deployments is instant rollbacks. Since previous releases are preserved on disk, rolling back is as simple as switching the symlink back to a previous release directory.
In DeployHQ:
- Go to your deployment history
- Find the last successful deployment
- Click Rollback
The symlink switches back instantly — no re-uploading files, no waiting. For more details on rollback strategies, see our guide on how DeployHQ empowers you to rollback deployments.
Best Practices
- Keep 3-5 releases — Enough for quick rollbacks without wasting disk space
- Use shared paths for persistent data — Never store uploads or environment files inside the release directory
- Run database migrations in post-deployment commands — See our guide on database migration strategies for zero-downtime deployments
- Test in staging first — Set up multiple environments (dev, staging, production) to validate deployments before they hit production
- Enable deployment notifications — Get alerts via Slack, email, or webhook so your team knows when deployments complete
- Secure your servers — Follow our security checklist to lock down your deployment pipeline
When to Use Zero-Downtime Deployments
| Scenario | Recommendation |
|---|---|
| eCommerce stores | Always — lost sales during downtime |
| SaaS applications | Always — users expect 24/7 availability |
| Marketing sites | Recommended — avoid SEO penalties from downtime |
| Internal tools | Optional — brief downtime may be acceptable |
| Development/staging | Optional — convenience over necessity |
Learn More
For the full technical documentation on configuring atomic deployments, visit our support documentation.
If you're new to DeployHQ, start with our beginner's guide to deploying your code, then come back here to enable zero-downtime deployments.
Looking to build a complete CI/CD pipeline? Check out our guide on building a CI/CD pipeline from scratch with DeployHQ.
Have questions about zero-downtime deployments? Reach out to us at support@deployhq.com or connect with us on Twitter.