How bisks.net serves 803 sites with a limit of 500 Workers
bisks.net has more Cloudflare Workers than Cloudflare allows. This page explains what bisks.net is, how it was built, why the limit did not stop it for two months, and the change that fixed it.
What bisks.net is
bisks.net is a collection of small web sites. Each site is a toy, a game, a chart, or a tool. Most of them use public Bluesky data.
A person posts an idea on Bluesky and tags @buildthis.bisks.net. A bot writes the site. The bot saves it in one GitHub repository. GitHub then deploys it. Each site gets its own address, for example workercap.bisks.net. On 2026-11-02 the repository had 803 sites.
Almost all of the sites are static files. A static file is a file that the server sends without change: HTML, JavaScript, or an image. The visitor's browser runs the code.
The first architecture: one Worker for each site
The sites run on Cloudflare. A Worker is a small program that runs on Cloudflare's network. It receives a web request and sends back a response.
Each site had its own Worker. A route connected the hostname of the site to its Worker. The Worker sent each request to the static files of the site. Each deploy created the Worker atprotozoa-<site> if it did not exist.
This design keeps sites separate. A change to one site cannot break another site. But most of these Workers were the same ten lines of code. The code passes the request to the files. 592 of the 803 sites needed nothing more.
The Cloudflare limit: 500 Workers, and an account with 799
The Cloudflare Workers Paid plan allows 500 Workers for each account. Cloudflare counts a Worker that only sends static files in the same way as a Worker that runs code.
On 2026-11-02 the account had 799 Workers. That is 299 more than the limit.
Why 799 was possible
The limit does not remove Workers that already exist. The 500 Workers that existed first, and all later ones, kept serving visitors. No visitor saw an error.
The limit also did not apply to every way of creating a Worker. Wrangler is the Cloudflare deploy tool. Newer versions of wrangler create a Worker through an upload path for static files. Until October 2026, that path did not check the limit. Older versions used a path that did check it. The same credentials failed with one version and succeeded with the other.
Between 2026-10-29 and 2026-10-31, the check began to apply to the upload path. Then every new Worker failed with this error:
You have exceeded the limit of 500 Workers on your account. [code: 10037]
Nine new sites could not deploy before anyone saw the problem.
- 2026-08-20 — The account goes above 500 Workers. Deploys continue to work.
- 2026-09-17 — A request to increase the limit goes to Cloudflare. Cloudflare does not answer. For more than 500 Workers, Cloudflare recommends Workers for Platforms, a different product.
- 2026-10-29 — strandbeest is the last new Worker to deploy.
- 2026-10-31 — The upload path returns error 10037 for new Workers.
Two earlier limits of the same kind
The Worker limit was the third limit that the sites reached. Each limit applies to a different Cloudflare resource.
| limit | value | what happened |
|---|---|---|
| Custom Domains per zone | 100 | The limit was reached in July 2026. New sites deployed with no DNS record. Sites now use plain routes. Only the apex domain keeps a Custom Domain. |
| Routes per zone | 1000 | The limit was reached on 2026-09-25. New sites got a Worker and no route (error 10073). Removal of 293 old path routes made room. |
| Workers per account | 500 | The account has 799. New Workers fail with error 10037. |
The new architecture: shared Workers for sites with no code
A site with only static files does not need its own Worker. One Worker can serve many sites. It reads the hostname of the request, finds the folder for that site, and sends the file from that folder.
A Worker named fallback already had the wildcard route *.bisks.net/*. It receives each request that no other Worker claims. It now sends the request to one of four host Workers. Each host Worker holds the files of about 148 sites.
Each hosted site keeps its own hostname. Thus each site keeps its own origin, cookies, localStorage, and OAuth login.
There are four host Workers, not one, for two reasons. A push to one site deploys only the host of that site. And a bad deploy reaches 148 sites, not 592.
How the 592 sites moved
- classify —
migrate-to-host.mjsfinds sites where the Worker only sends requests to the files. A site with a binding, a cron trigger, or custom code keeps its Worker. - host — Delete the
wrangler.tomlfile and thesrc/folder of the site. Add the site tofallback/sites.json. Push the change. - cut over —
cf-cutover.mjs --routesremoves the old route. It waits until the new Worker answers. It compares the status code and a hash of/. If they are different, it restores the route. - delete —
cf-cutover.mjs --workersdeletes the old Worker. This frees one place under the limit. A Worker with a Custom Domain goes one at a time, because its deletion also deletes the DNS record.
The result
| group | sites | served by |
|---|---|---|
| hosted | 592 | 4 host Workers and the fallback Worker |
| own Worker | 211 | 1 Worker for each site: share routes, KV storage, proxies, custom code |
The account has 216 Workers: 211 site Workers, 4 host Workers, and fallback. That leaves room for 284 more sites with server code.
A new site is now a folder with public/ and site.json. The wildcard route covers it. It uses no Worker and no route. A site with server code gets its own Worker and one route.