Template reload modes
When you run PDF Server as the base for your own PDF service, its templates live in a directory you control. Reload mode decides whether — and how — the server notices edits to that directory after it has started. It is set with a single flag:
--templates-reload-mode <none|always|watch> # env TEMPLATES_RELOAD_MODE
The default is none. There are three modes.
At a glance
| Mode | Picks up edits without restart | New/removed templates in listings | Tester UI auto-refreshes | Per-request overhead | Run it for |
|---|---|---|---|---|---|
none (default) | ✗ | ✗ | ✗ | none | Production — templates baked into your image |
always | ✓ | ✓ | ✗ (re-render to see changes) | disk read per render | Templates that change out of band (a mounted volume) |
watch | ✓ | ✓ | ✓ (over SSE) | none between rebuilds | Interactive authoring with the tester UI |
none — static snapshot (production default)
Templates are read once at startup into an immutable store and never re-read. Changing a file on disk has no effect until you restart the server.
This is the right mode for a deployed service: your templates are baked into your image (see Build your image), so they never change under a running process, and every render serves from memory with no disk access.
always — re-read on every render
Each render re-reads its template from disk, and template listings (the tester menu, the OpenAPI spec) re-scan the directory — so files you add, edit, or remove after startup are reflected without a restart. Nothing is pushed to the browser, so an open tester UI does not refresh on its own: re-render (or reload the page) to pick up a change.
Use always when the templates directory changes independently of the process —
for example a volume you mount and update, or a filesystem where the watch
mode's change notifications don't work (some network and overlay filesystems).
The cost is a disk read per render; on local SSDs it is negligible, but it is not
free at high throughput, which is why production uses none.
watch — live reload with the tester UI
The server watches the template and composition directories for filesystem changes, rebuilds the whole store when it sees one, and atomically swaps the new store in. A rebuild that fails (for example a half-written file mid-save) keeps the previous store, so a bad intermediate edit never takes the service down.
On top of that, watch mounts GET /_events and pushes a change event to
connected tester UIs over Server-Sent Events. The tester refreshes its template
menu and re-renders the current preview automatically — edit a file, and the
preview updates with no click. Between rebuilds, renders serve from the built
store just like none, so there is no per-render disk cost.
A burst of file events (an editor rewriting several files) is collapsed into one
rebuild by a debounce window, --templates-reload-debounce (default 250ms).
Two caveats:
- A top-level templates or compositions directory that does not exist at startup is not watched if you create it later — restart the server once after creating it. Existing directories and any nesting beneath them are picked up live.
- If change notifications are unreliable on your filesystem (some network/overlay
mounts), use
alwaysinstead.
Choosing a mode
- Production:
none. Templates are fixed in your image; take the fast path. - Authoring locally with the tester UI:
watch, for hands-off live preview. - Templates change under a running server (mounted/synced volume) or
watchcan't see changes on your filesystem:always.
See also
- Template author workflow — the full edit → preview → validate → ship loop these modes support.
- Tester UI — the live-reload consumer of
watch. - CLI & configuration —
--templates-reload-mode,--templates-reload-debounce, and--sse-subscriber-buffer. - Template store & hot reload — how the store, the swap, and the watcher work internally.