When you deploy with zero-downtime enabled in DeployHQ, your site stays live throughout the entire process. But did you know there are actually two different strategies for how files get prepared before the symlink switches? Understanding the difference can save you from unexpected behavior -- especially if your application writes files to the release directory at runtime.
In this article, we'll explain both zero-downtime deployment strategies, how the cache directory option works, when to use each approach, and how to configure them in DeployHQ.
How Zero-Downtime Deployments Work
Before diving into the strategies, here's a quick refresher on how zero-downtime deployments work in DeployHQ:
flowchart TD
A[New Deployment Triggered] --> B[Prepare New Release Directory]
B --> C[Upload Changes to New Release]
C --> D[Run Post-Deployment Commands]
D --> E[Swap Symlink to New Release]
E --> F[Site Live with New Code -- Zero Downtime]
The key concept is the symlink swap. Your web server's document root points to a symlink (typically called current), which in turn points to a release directory. When a new deployment completes, DeployHQ atomically switches the symlink to the new release -- meaning all files change at once, with no inconsistent state.
The directory structure on your server looks like this:
/var/www/myapp/
|-- releases/
| |-- 20260218_001/ (old release)
| |-- 20260218_002/ (previous release)
| +-- 20260219_001/ (current release)
|-- shared/ (persistent files: logs, uploads, etc.)
+-- current -> releases/20260219_001/ (symlink)
Your web server should point to /var/www/myapp/current as the document root. When DeployHQ deploys, it creates a new release directory, prepares the files, then switches the current symlink.
The Two Strategies
DeployHQ offers two strategies for preparing the new release directory. The choice affects what happens to files that exist on your server but aren't in your repository.
Strategy 1: Copy Previous Release (Default)
This is the original strategy that DeployHQ has always provided.
How it works:
- Copy the entire previous release directory to a new release directory
- Upload only the changed files (the Git diff) to the new directory
- Swap the symlink
What this means: Any files that were added to the release directory outside of the deployment process -- like user uploads, cache files, or log files stored within the release folder -- will be carried over to the next release.
This is useful when your application writes to the release directory at runtime and you need those files preserved across deployments. For example, a CMS that stores uploaded media in the same directory tree as the application code.
Strategy 2: Cache Directory (Clean Copy)
This is the newer strategy that gives you a cleaner deployment.
How it works:
- Maintain a cache directory that contains a clean copy of your repository
- Update the cache directory with the latest changes from the deployment
- Copy the cache directory to a new release directory
- Swap the symlink
flowchart LR
A[Git Changes] --> B[Cache Directory<br/>Clean Repo Copy]
B --> C[New Release Directory]
C --> D[Symlink Swap]
What this means: The new release will only contain files from your repository. Any files added to the previous release directory at runtime will not be carried over. This gives you a clean, predictable deployment every time.
This is ideal when:
- You want a pristine deployment matching your repository exactly
- Runtime files (uploads, logs, caches) are stored in a
shared/directory linked via symlinks - You use build pipelines that generate fresh assets each deployment
- You want to avoid accumulating stale files across releases
Which Strategy Should You Choose?
| Consideration | Copy Previous Release | Cache Directory |
|---|---|---|
| Runtime files in release dir | Preserved | Lost |
| Deployment cleanliness | May accumulate stale files | Always clean |
| Build pipeline compatibility | Good | Excellent |
| Predictability | Lower (depends on server state) | Higher (matches repo) |
| Best for | Legacy apps, CMSs with local storage | Modern apps, 12-factor apps |
General recommendation: If your application follows modern best practices and stores persistent data (uploads, caches, sessions) outside the release directory -- in a shared/ folder, external storage, or a database -- use the cache directory strategy. It gives you the most predictable deployments.
If your application needs files that were created at runtime to persist across deployments, stick with the copy previous release strategy.
How to Configure It
When setting up a new server in DeployHQ with zero-downtime enabled:
- Go to your project's Servers page
- Click New Server (or edit an existing server)
- Enable Zero-Downtime Deployments
- Select your preferred strategy:
Copy previous release before uploading changes
(default)Upload changes to a cache directory and copy new release from there
- Save your server settings
Important: At present, the strategy can only be selected when first configuring a new server with zero-downtime enabled. To change the strategy on an existing server, you'll need to remove and re-add the server configuration.
Best Practices for Zero-Downtime Deployments
Regardless of which strategy you choose, these practices will help ensure smooth zero-downtime deployments:
Use shared directories for persistent data. Store uploads, logs, and cache files in a shared/ directory that's symlinked into each release. This works with both strategies and keeps your releases clean.
# Example: Symlink shared directories in a post-deployment command
ln -nfs /var/www/myapp/shared/storage /var/www/myapp/current/storage
ln -nfs /var/www/myapp/shared/logs /var/www/myapp/current/logs
Point your web server to the symlink. Make sure your Nginx or Apache configuration uses the current symlink path, not a specific release directory.
# Nginx example
server {
root /var/www/myapp/current/public;
# ...
}
Set a release retention limit. DeployHQ lets you configure how many old releases to keep. This prevents disk space from growing indefinitely. A retention of 5-10 releases is typical, giving you enough rollback options without wasting storage.
Test with a staging server first. Before switching strategies on production, test on a staging server to confirm your application behaves correctly with the new strategy.
Combining with Other DeployHQ Features
Zero-downtime deployments with a cache directory pair well with other DeployHQ features:
- Turbo Deployments: Bundle files into a compressed archive for faster transfers, then unpack into the cache or release directory.
- Build Pipelines: Compile assets, install dependencies, and run tests before the deployment reaches your server.
- Automatic Deployments: Trigger zero-downtime deployments automatically when you push to your repository.
Frequently Asked Questions
Can I switch strategies on an existing server? Currently, the strategy is set when you first configure zero-downtime on a server. To change it, you'll need to remove and re-add the server. Your deployment history will be preserved.
Will the cache directory strategy delete my shared files? No. The cache directory only affects the release directory contents. Shared directories, symlinks, and files outside the release path are unaffected.
Does this work with all server types? Zero-downtime deployments require SSH access to your server. They work with any Linux/Unix server accessible via SSH, including VPS providers, dedicated servers, and cloud instances.
How many releases are kept? You can configure the number of releases to retain in your server settings. DeployHQ automatically cleans up older releases beyond your retention limit.
Want to deploy without downtime? Sign up for DeployHQ and enable zero-downtime deployments on your servers today, or explore our pricing plans to find the right fit. Questions? Contact us at support@deployhq.com or on Twitter @deployhq.