QueueRoom docs
Set up, run and review a sale.
How QueueRoom handles each request, how to add it to your site, and what to check when something looks wrong.
-
Launch checklist
Seven checkpoints in the dashboard, from connecting your hostname to reviewing the sale.
-
How QueueRoom works
What happens to one request, and the parts that run during a sale.
-
Option: your own Cloudflare
Run QueueRoom on your own zone: the connector, its bindings and its routes.
-
Security controls and gaps
Current controls, how they map to ISO/IEC 27001 and PCI DSS, and what is missing.
How it works
What happens to one request.
On your own Cloudflare zone, every request to a protected page passes through the QueueRoom Worker first. The hosted script tag only redirects browsers that run it.
- 01Buyer request
- 02 QueueRoom Worker On your protected path
- Signed config snapshot
- Admission authority · Durable Object
- 03a · not admittedWaiting pageNot admitted yet: keeps place in line03b · admittedYour checkout Admitted buyers and verified search crawlers1
- Config path · separate from requestsQueueRoom dashboardPublishes signed, versioned config to Workers KV
The parts that run during a sale.
Each launch runs through the same small set of parts.
01Enforcement on your route A Worker on your protected path decides before your origin sees the request.
The QueueRoom Worker reads a signed configuration snapshot through a local cache and Workers KV. Once configuration is loaded, paths you do not protect pass through, and a request to a protected path without a valid admission goes to the waiting room. If signed configuration is missing, every request reaching the Worker gets a 503; if it is past its stale limit, protected paths do.
02One admission authority per room A Durable Object orders registrations and issues admissions at your rate.
Each room has a single authority that ranks registrations, applies the admission rate and the cap on active sessions, and supports first-come order or a lottery for people who arrived before the sale opened. Queue tickets and admissions are signed and stored in host-only cookies. When registration protection is enabled, browsers complete a proof-of-work check before a ticket is issued, and when the rate-limit binding is configured, requests are limited per client IP.
03Signed, versioned configuration Every policy change is signed per hostname and acknowledged by the edge.
Each hostname has its own signing key. A change is staged, reviewed and confirmed, then published with content digests; the dashboard records whether the edge acknowledged that exact version. The Worker rejects configuration signed for another hostname, and the room’s admission authority refuses to accept an older revision than the one it holds.
04Hostname ownership Nothing is published to a hostname until you prove you control it.
The dashboard issues a one-time TXT or CNAME value. QueueRoom checks it through two public DNS resolvers before accepting the hostname, and access in the dashboard is scoped to the organizations that own each host.
05Waiting page behavior One place in line per page, shared across tabs, with paced status checks.
Tabs on the same page share a single place in line and elect one tab to check status. The Worker tells the page when to check next, so waiting browsers do not poll on a fixed timer. While admission is running, the page can show position and an estimated wait range. Position is hidden during a pre-sale draw, and the estimate is withheld while the room is paused, not yet open, sold out or full.
06Evidence after the sale Audit log with a hash-chain check, queue telemetry, and reports.
Every change to a launch or waiting room is written to an audit log whose hash chain you can check from the dashboard, up to the history limit. The Worker records sampled queue telemetry, and post-event reports are included on paid plans; ask about plans through the contact form.3
Option: your own Cloudflare
Run QueueRoom on your own Cloudflare zone.
Route the whole hostname through the connector; the signed policy decides which pages queue. A request to a protected page is queued until admitted, whatever the method (an unadmitted POST gets a temporary error, 503); everything else goes to your existing Worker. Your server must only accept traffic through Cloudflare. Native apps can use the headless client, which talks to the same Worker without browser cookies.
The connector and headless client are not on npm yet; ask about access through the contact form. Values below are placeholders.
import customerWorker from './customer-worker'
import {
createQueueRoomConnector,
AdmissionCoordinatorDO,
} from '@queueroom/cloudflare-worker-connector'
export { AdmissionCoordinatorDO }
export default createQueueRoomConnector({
fallback: (request, env, ctx) =>
customerWorker.fetch(request, env, ctx),
bindings: (env) => ({
CONFIG_KV: env.CUSTOMER_CONFIG_KV,
ADMISSION_COORDINATOR: env.CUSTOMER_ADMISSION,
CONFIG_HMAC_SECRET: env.QUEUE_ROOM_HMAC_SECRET,
HOSTNAME_ROOM_OWNERS: env.HOSTNAME_ROOM_OWNERS,
EDGE_RATE_LIMITER: env.EDGE_RATE_LIMITER,
REQUIRE_EDGE_RATE_LIMITER: 'true',
REQUIRE_REGISTRATION_PROTECTION: 'true',
}),
}) {
"status": "waiting",
"roomId": "<room-id>",
"position": 128,
"aheadCount": 127,
"retryAfterSeconds": 20,
"waitGuidance": {
"state": "available",
"source": "configured_policy",
"precision": "bounded",
"lowerSeconds": 420,
"upperSeconds": 660
}
} Example response with made-up values; fields abridged.
Install checklist
This is a summary. Ask QueueRoom for the install guide that matches your Worker version before you route traffic.
- The Worker verifies signed configuration locally and resolves the room’s policy. It does not call the QueueRoom dashboard for each buyer request. Configuration past its allowed stale time keeps protected paths closed.
- Install
CONFIG_KVandADMISSION_COORDINATORwith its SQLite migration, plusREPORT_QUEUEandANALYTICS_REPORTSfor reporting. - Provision
CONFIG_HMAC_SECRETand the hostname-specificCONFIG_HMAC_KEYRINGas secrets, matching the QueueRoom dashboard. Complete DNS ownership verification and theHOSTNAME_ROOM_OWNERSbootstrap map. - Forward
EDGE_RATE_LIMITERand keepREQUIRE_EDGE_RATE_LIMITERandREQUIRE_REGISTRATION_PROTECTIONenabled. Registration requires an enabled signed proof-of-work policy. The per-location hostname and IP limiter is an abuse backstop, separate from admission capacity; it is not a DDoS guarantee. - Serve
/__queueroom/*and/waiting-room/verifyon the same origin as your protected paths. The dashboard’s waiting-page preview is not the buyer runtime. - Rehearse a full buyer flow on your own Worker before a sale. Installing the Worker does not prove capacity, and production rollback is a manual Cloudflare version rollback.
Troubleshooting for dashboard operators. Button names match the dashboard.
When setup or publication needs attention.
Settings saved, buyer page unchanged
Check desired and acknowledged versions. Saving a draft or branding does not confirm publication. Review the event publication and check the served waiting page after confirmation.
Receipt pending or outcome unknown
Use Reconcile authoritative edge receipt. An install in progress may need its lease to expire first. Authority unavailable, identity mismatch or changed receipt ownership keeps publication frozen. Do not republish or compensate until the outcome is known.
Publication explicitly failed
Check that the selected event, saved policy and authoritative status show an explicit failure, then correct the reported prerequisite. Retry saved policy publication publishes that saved policy immediately, without another review dialog or slide-to-confirm step. Review the saved values before choosing it. Never retry a pending or unknown outcome; reconcile the Worker’s status first.
Ownership, signature or registration rejected
Check current DNS ownership evidence, the exact hostname and room owner, matching key ID and version, the rate limiter binding, trusted connecting-IP metadata and enabled signed registration protection. Keep secret values out of logs and support messages.
Queue is not moving
Check event timing, paused or sold-out state, a zero rate, a full active-session cap and telemetry freshness. Honor server retry guidance. An unavailable wait estimate does not mean immediate admission.
Branding could not load
Use Retry branding before saving, confirm the selected room and preview again. AI suggestions stay drafts until reviewed and saved.
Integrations
Choose the integration for your app.
- Script tag (hosted)
- Add the script tag QueueRoom gives you as the first script in the <head> of the page to queue. Visitors wait on the QueueRoom page, then return to the exact page they opened. If your site sends a Content-Security-Policy, allow the QueueRoom address in script-src. The script queues browsers that run it; on its own it does not stop bots, scripts or direct links.
- Browser waiting page
- On your own Cloudflare zone: uses the same-origin
/__queueroom/waitruntime and signed HttpOnly cookies. Tabs on the same page share one place in line. Buyers return to the protected page with its query string intact, minus QueueRoom’s own__qr_parameters. Return addresses with a #fragment are not accepted. - Existing Cloudflare Worker
- Route the whole hostname through the connector and keep your existing Worker as the fallback. The signed policy decides which pages queue, for every method. Forward the required bindings and flags.
- React Native and native HTTP
- Native apps use the headless client, which sends explicit credential headers instead of browser cookies. Create a client with
createQueueRoomClientand a safe GET target, join the queue, handle the challenge in your app and honor the server’s retry delays. CallprotectedFetchfor a business request; it never retries or replays that request on its own. Your app’s own sign-in stays separate. The headless client is not on npm yet: ask QueueRoom for the package and integration guide that match your QueueRoom setup.
Planning a launch?
Tell us the date, the page to queue and roughly how many buyers you expect. We’ll reply by email.