Current & Trusted
Software

A Design Guide to Zero-Downtime Deployment with Symlinks and OPcache Reset

A technique for updating production web applications smoothly without disrupting user sessions that are actively transacting.

Budi Santoso
Budi Santoso
• • 2 min read
Share:
GTechUpdate Tech Banner
Foto: GTechUpdate Tech Banner

Copying new code files straight into the production folder is a recipe for disaster for an application with constant traffic. Visitors can hit errors when one file executes while a related file has not finished copying.

Why incremental copying is always risky

The problem is not how long the copy takes, but the absence of a consistent state while it runs. For several seconds, the application runs on a mix of old and new code — a class expecting a new method signature meets an old implementation.

A dated-release pattern joined by symlinks removes that window. The entire new version is prepared in a separate directory, and the switch is a single symlink move that is atomic at the filesystem level.

OPcache and the realpath trap

After the symlink moves, PHP still holds the old version's bytecode in OPcache. Worse, PHP also caches path mappings — the realpath cache — so old processes keep pointing at the previous release directory even though the symlink has changed.

Clearing OPcache alone is often not enough. The most reliable approach is to reload PHP-FPM with a reload signal that lets in-flight requests finish before workers are replaced. If reload access is unavailable, use absolute paths to the release directory instead of going through the symlink.

The parts that are not atomic

Symlinks solve the code problem, not the database problem. Schema migrations cannot be undone in an instant, and this is the part that truly determines whether a rollback is possible.

The rule: split schema changes into steps that are safe for both versions of the code at once. Add the new column first, let old and new code run side by side, and drop the old column only once the old version is genuinely retired. Dropping a column in the same release as the code that uses it makes rollback impossible.

What to test before you need it

A rollback that has never been tried is not a rollback, it is a hope. Running it once in a staging environment surfaces the things you did not think of — caches holding old structures, incompatible session files, missing compiled assets.

Keeping the last few releases and providing a one-line command to go back gives real peace of mind: not the confidence that a release will not fail, but the certainty that a failure can be recovered from in seconds.

Tag Terkait: #Linux #DevOps
Budi Santoso

Budi Santoso

Contributing Editor

Senior Software Architect dan pemerhati ekosistem PHP, cloud computing, dan performa web skala besar.

Related Articles

Lihat Semua →