Cloudflare Workers
The whole app (every route, template, extension and setting) compiled to WebAssembly and run on Cloudflare Workers, Cloudflare's serverless platform. Nothing runs at home, and it costs $5 a month on the Workers Paid plan. workers/ is the deployment; the platform code is in src/workers.
Deploy
With the button
The button copies the repo to your GitHub, deploys it to your Cloudflare account and redeploys on every push. It uses the root wrangler.toml.
- Wait for the first build, which takes several minutes: Cloudflare's builders have no Rust, so
build-worker.shinstalls it. - From a clone of your copy, apply the account database migration:
npx wrangler d1 migrations apply AUTH_DB --remote. - Open
threadshift.<your subdomain>.workers.dev/setupand create your admin. - Optionally, add a custom domain under Worker > Settings > Domains & Routes. Caching needs one (see Limits).
From a checkout
make worker # local dev server (wrangler dev), http://localhost:8080
make worker-deploy # deploy to your Cloudflare account
Both install the wasm32-unknown-unknown target and worker-build if they're missing, and use Wrangler from your PATH or npx. The build needs Rust 1.91 or newer. Before the first deploy, change the custom domain in workers/wrangler.toml to one on your account.
Configure
| What | Where |
|---|---|
| Settings file | redlib.toml at the repo root, embedded at build time |
| Environment variables | [vars] in workers/wrangler.toml, which override redlib.toml as they would natively |
| Secrets | npx wrangler secret put REDLIB_ADMIN_PASSWORD, run from workers/, if you want an admin without the installer |
| Log level | RUST_LOG (default warn); read the logs with wrangler tail |
Storage
| Binding | Holds | Without it | Set it up |
|---|---|---|---|
SETTINGS (KV) | Instance settings saved at /settings/instance | That page is read-only | From workers/, run npx wrangler kv namespace create SETTINGS, then uncomment [[kv_namespaces]] in wrangler.toml and paste the id it prints |
AUTH_DB (D1) | Accounts and sessions | Setup and sign-in fail | See Accounts |
Saved settings reach every copy of the Worker within two minutes.
How it works
What replaces the OS
A Worker has no sockets, threads, filesystem or environment variables. src/workers provides each of those under the names Redlib's code already uses, so upstream files only gain a few cfg lines:
| Native | On Workers |
|---|---|
wreq, which imitates browser TLS fingerprints | The runtime's fetch() (wreq.rs) |
| tokio tasks and timers | waitUntil and setTimeout (tokio.rs) |
| An in-memory cache of Reddit responses | The same, plus the data center's cache (cache.rs) |
| Environment variables | The Worker's vars and secrets (env.rs) |
redlib.toml and overrides.toml on disk | The embedded file and KV (fs.rs) |
| A hyper server with compression | The fetch handler; Cloudflare compresses |
| A background loop that refreshes Reddit's token | A refresh on the first request after 23 hours |
Isolates
Cloudflare runs the Worker in many isolates, small sandboxes that each start fresh. Each one logs in to Reddit on its first request, which adds a few hundred milliseconds, and keeps its own in-memory cache and rate-limit count.
Caching
Pages spend 0.5 to 1.5 seconds waiting on Reddit, so API responses also go into the data center's Cache API, which every isolate there shares:
| Content | Fresh for | Served stale for up to |
|---|---|---|
| Listings, comments, search | 30 s | 5 min |
| Subreddit and user info, wikis, the directory | 10 min | 1 day |
A stale copy goes out immediately while a new one loads in the background. Proxied images stay in Cloudflare's cache for a week, so each data center fetches an image from Reddit once. Videos don't, since they're large and fetched in ranges. The constants are at the top of cache.rs.
Rules for shared code
- The runtime cancels a request that only waits on another request's work, and drops whatever a finished request leaves running. So never share a future between requests; anything shared code spawns runs under the spawning request's
waitUntil. - If shared code starts using more of wreq's or tokio's API, the Workers build won't compile until
src/workerscovers it. The native build is unaffected.
Limits
- Reddit fingerprints TLS handshakes to block scrapers, which is why native Redlib imitates browsers (redlib#544). A Worker can't, but Reddit accepts its requests anyway (checked 2026-10-17). If that changes and Reddit returns 403s, use the native build or Docker.
- It needs Workers Paid. CPU per request is about 5 ms at the median, 100 to 400 ms for listings and comments, and up to 1.5 s for
/subreddits/popular; the Free plan allows 10 ms. - Proxied images and videos stream through the Worker and count as requests.
workers.devaddresses have no cache, so none of the caching above applies until you add a custom domain.