Operations
Process model
- One
flootypst serve(the default subcommand) is the long-running HTTP server. - One short-lived
flootypst workeris spawned per/renderor/render-urirequest. The worker reads its bundle from stdin (bincode), writes the PDF to stdout, and exits. - Workers inherit
PR_SET_PDEATHSIG = SIGKILLon Linux so they cannot outlive the parent. - The parent uses
kill_on_dropon the child handle, so a client disconnect or request cancellation kills the worker too.
Health checks
GET /health returns 200 ok. It does not touch any state or spawn workers, so it’s safe to hit at any rate.
Concurrency
Each in-flight render holds one slot of a semaphore sized by FLOOTYPST_MAX_CONCURRENT_COMPILES. The semaphore is acquired with try_acquire — overflow returns 503 server busy immediately rather than queueing. Put rate limiting / queueing in the upstream layer if you need it.
Sizing
A single worker peaks at one CPU during compile and roughly 100–300 MB resident, scaling with document complexity. Memory falls back to ~0 between requests (the worker exits). For sustained throughput, the concurrent-compile cap should match CPU count; for headroom, run at cpu_count - 1.
Logs
Logs go to stdout via tracing. Set RUST_LOG=flootypst=debug,tower_http=info for request-level detail.
What doesn’t exist yet
- Metrics endpoint (Prometheus or otherwise).
- Per-tenant accounting / quotas.
- Async job mode with callbacks. Today every request blocks until the PDF is uploaded.
Open an issue against the repo if you need any of these.