Cross-border Notes

Practical notes for foreign-trade and cross-border sellers

Home/Content Factory

Dev Log #7Ongoing

Devlog 007: Upload Everything, Then Flip One Pointer

2026-11-01 · 4 min readContent Factoryindependent sitereleaserollback
Contents
  1. What goes wrong when files are copied over
  2. One directory per version
  3. The pointer is written last
  4. Retries depend on the status code
  5. Acceptance reads 14 files
  6. An upload gate sits in front
  7. Drills by default
  8. What a small site needs
  9. FAQ

Upload every new file first, then change one pointer at the end, and visitors never see a half-updated page.

On 30 October the release chain pushed real files to object storage for the first time. A probe site went out as 14 files and 113,376 bytes. After the pointer write, a different tool read it back and the content matched.

Before that, the chain only wrote to a local directory. A drill and a live release differed by one switch.

Upload the new release, then flip one pointer

What goes wrong when files are copied over

Publishing with FTP or a sync command makes every file its own event. Halfway through, the homepage can already carry the new template while the stylesheet is still the old one. An image path changes, the new file has not arrived, and the page shows an empty box.

Anyone opening the site during that window gets a page stitched from two versions.

Rollback is worse. The old files were overwritten, so the only option is to find the previous build and upload it again, with the same window open a second time.

One directory per version

Object What it holds
sites/<host>/releases/<12-char hash>/ Every file in that release
sites/<host>/_current.json The release that is live

A release does two things. It uploads the new version into its own directory, then rewrites the pointer with the new 12-character hash.

The old directory stays untouched. A rollback rewrites the pointer, and not one byte is uploaded again.

The directory name comes from the first 12 characters of the content hash. Same content, same name, so a repeated release creates no second copy.

The pointer is written last

The upload loop sends one file at a time. Only when every file has landed does the code write _current.json.

Reverse the order and the pointer arrives first. Files are still missing, and visitors get a 404.

With the current order, a failed pointer write leaves production on the old release. The site is stale, but whole.

Those two steps sit a few lines apart in the code. A single test exists for this alone: a failed pointer write must not leave a mixed state.

Retries depend on the status code

A 4xx raises immediately. A wrong path or a token without write permission returns the same answer ten times.

A 5xx or a timeout gets 2 retries, waiting 1 second and then 2.

The split saves time. A brief network reset clears on the retry. A permission error only repeats itself three times.

Acceptance reads 14 files

The probe release recorded 14 files, 113,376 bytes, release 0c77c4f137ac.

After the pointer write, a second tool read _current.json and confirmed the release. Then index.html and sitemap.xml were opened and compared.

That second check is not optional. The same client writing and reading only proves it agrees with itself.

The probe objects were deleted afterwards. Nothing was left in the bucket.

An upload gate sits in front

One release is capped at 5000 files and 512 MB. Above that the adapter raises, and the job goes to approval.

A typical export site runs a few dozen pages, a few hundred objects. Tens of thousands in one release usually means a dependency folder or a log directory was packaged by mistake.

Drills by default

The adapter defaults to local, writing only to a local directory. A live release requires setting CF_DAG_ADAPTER=r2.

That switch is deliberate. Automation running smoothly while nobody watches deserves more suspicion, not less.

Credentials for a live release come from a file outside the repository. They are not written into code and not printed to logs.

What a small site needs

Sites Update rhythm Approach
1 Once or twice a month Upload by hand, keep one previous copy
2 to 5 Weekly Version directories plus a pointer
More than 5 Something daily Add approvals and a release ledger

Object storage is optional. Keep current and previous directories on the server, upload into the new one, then point a symlink at it.

A symlink swap is atomic. It behaves the same way as a pointer write.

FAQ

Do visitors see the old page during an update

After the pointer flips, new requests read the new version. Browser and CDN caches are a separate layer, so images and stylesheets need their own cache headers or a local browser can still hold old files.

How long does a rollback take

One pointer write, usually under a second. The previous directory is still there and nothing is uploaded again. How many versions you keep depends on storage cost; ten releases is a common choice.

Do release directories pile up

Yes. Prune by count, for example keep the last ten and delete older ones. Check that no rollback is pending before deleting.

Is this worth it for a small site

For a site updated once or twice a month, manual upload and one backup are enough. With weekly edits, or several people editing, version directories and a pointer remove most of the argument about who overwrote what.

Last updated: 2026-11-01