Web publishingState as of: 2026-10
Incremental upload over FTP
How an FTP upload can send only the files that changed when FTP offers no content hash, and what a static site build has to do for it.
Research question: How can an FTP upload send only changed files when FTP provides no content hash?
Project requirement
Shared hosting with FTP access only, no SSH or rsync. The build rewrote the whole output on every run, so the FTP client saw every file as new and uploaded everything each time.
Method and validation
- Change detection options compared: modification time (mtime), file size and content hash.
- The build writes to a temporary folder and syncs into the output by comparing size and then bytes, so only differing files are written and files missing from the source are removed.
- A SHA-256 manifest and a change list relative to the previous build (files to upload and to delete).
- pytest for the sync and the manifest diff; after two builds without changes the second change list is empty.
Findings
- FTP tools can only decide from file size and mtime.
- Size is unreliable: replacing a version parameter of the same length (?v= plus 8 characters) does not change the HTML size.
- mtime is reliable once the build keeps it for unchanged files; then FileZilla's "overwrite if newer" and lftp mirror --only-newer work correctly.
- The hash manifest compares with the previous build, not with the server: after two builds without an upload, the second list is incomplete.
- Mirroring with delete would also remove files on the server that are not part of the build, so it needs an exclude list.
Decision
Two layers: an mtime-preserving sync, so any FTP client decides correctly, and a hash-based change list for checking and manual uploads. No upload script for now.
Limits and open questions
- An own FTPS upload script with a local state file, or a CI-based upload, is still open; the host firewall may block foreign CI IP addresses (unverified).
- The change list does not know the actual state of the server.