Repository navigation
Cleanup and compression
A cleanup rule belongs to a bucket and deletes objects past a certain age. Each rule has:
- an age, such as 7 days or 12 hours;
- a basis: either the time of the last upload to that key (
created) or the time of the last access (last-access); - an optional prefix, so the rule only applies under a folder such as
tmp/; - an option to keep any object that still has an active public link.
A bucket can have several rules, and an object is deleted when any of them matches. Creating a bucket with --ttl 7d adds a created rule for the whole bucket.
An upload can also carry its own expiry (ttl in the API and in put_text). Such an object is deleted when that time passes, regardless of the bucket's rules.
Last access is recorded when an object is read through the API or MCP or opened through a public link, at most once an hour per object. Viewing it in the panel does not count. An object never accessed falls back to its upload time.
Rules are evaluated when cleanup runs, not when a file is uploaded, so adding or changing a rule affects files that already exist. Preview the effect before it happens with tralha gc --dry-run, the System page of the panel or GET /api/cleanup.
Cleanup runs every TRALHA_GC_INTERVAL seconds (an hour by default), and on demand with tralha gc or from the panel. It:
- deletes the objects matched by an expiry or a rule, together with their links and search index entries;
- removes expired links and upload tokens that expired more than a day ago;
- deletes blobs, thumbnails and temporary files that nothing references any more and that are older than an hour.
A bucket can have a quota in bytes. Usage counts every stored object, including originals kept by compression.
When an upload would exceed the quota, the bucket either refuses it (reject, the default) or deletes the oldest objects until it fits (evict-oldest). Eviction never deletes an object with an active link, so images already pasted into PRs survive. If the remaining objects all have links and there is still not enough room, the upload is refused.
Compression is off until an administrator turns it on. The system setting applies to every bucket unless a bucket sets its own mode.
| Mode | Converts | Result |
|---|---|---|
off |
nothing | files are stored exactly as uploaded |
lossless |
PNG, GIF | pixel-identical WebP, usually 25 to 40% smaller for screenshots |
lossy |
PNG, JPEG, GIF | WebP at the configured quality (80 by default), much smaller |
JPEG is left alone in lossless mode because it has already lost information and usually grows as lossless WebP. Animated GIFs become animated WebP, which GitHub displays inline, unlike MP4.
A compressed version only replaces the upload when it is at least 5% smaller. The object keeps its key, so login.png may be served as image/webp; browsers and GitHub care about the content type, not the extension. The original type and size stay in the object's details so the panel can show the savings.
With "keep original" on, the uploaded file is stored too and can be downloaded from the panel or with GET /api/buckets/<bucket>/objects/<key>?original=1. It counts toward the quota.
Changing the compression setting only affects future uploads. Compression runs in the sandboxed image worker, and if it fails for any reason the original is kept.
Video is stored as uploaded. Compressing it would need ffmpeg and a background queue, which tralha does not have yet.