Skip to content

Cloudflare Free deployment is approaching Worker and static asset size limits #235

Description

@LJAYi

Problem

The v1.3.3 Cloudflare build is now very close to both size limits on the Workers Free plan.

Measured by the deployment workflow with wrangler deploy --dry-run --minify:

  • Worker gzip: 2854.75 KiB / 3,000,000 bytes (~97.4% of the Free limit)
  • dist/web/catalog/apps.json: 24.54 MiB / 25 MiB (~98.2% of the per-asset limit)
  • Static asset count: 11 / 20,000

The application builds cleanly and all tests pass, but a downstream deployment guard had to be temporarily relaxed to install v1.3.3. The next catalog/provider growth is likely to make Cloudflare Free deployments fail.

Findings

1. The catalog is combined into one large asset

catalog/apps/ already contains one JSON file per provider, but scripts/copy-catalog-assets.ts combines all 1,194 providers and 12,743 actions into a single /catalog/apps.json. src/server/cloudflare/catalog-assets.ts then reads that one asset during Worker initialization.

This creates an avoidable 25 MiB single-file bottleneck.

2. The Worker embeds every executable action ID

registry.cloudflare.generated.ts contains both the lazy executor import map and arrays for every action ID. The generated action arrays contain 12,743 repeated <service>.<action> strings.

The Wrangler esbuild metafile attributes about 460 KB of minified output to registry.cloudflare.generated.ts. The current generator already treats every definition action of an included provider as executable, so the same execution status can be represented by provider service IDs and expanded from the loaded catalog at startup.

3. Provider executors remain the long-term Worker-size driver

The metafile attributes roughly 10.3 MB of the 11.9 MB minified Worker output to provider modules. Removing the repeated action registry should recover immediate headroom, but executor sharding or more generic runtimes may eventually be needed as the catalog continues to grow.

Proposed backward-compatible changes

A. Shard the Cloudflare catalog asset

  • Write a small versioned manifest plus deterministic catalog chunks (for example, target <= 4 MiB each) instead of one monolithic apps.json.
  • Load the manifest and chunks through the existing ASSETS binding.
  • Keep an apps.json fallback in the loader during the transition if desired.
  • Preserve the existing in-memory CatalogStore and public /api/providers / /api/actions/:id response formats.

A small fixed number of chunks avoids both the 25 MiB file limit and excessive Worker subrequests.

B. Generate executable services instead of executable action arrays

  • Keep the lazy executorModules registry.
  • Stop emitting every action ID into the generated registry.
  • Pass the registry service keys to createCatalogStore.
  • Derive the exact executableActionIds set from catalog actions whose provider service is present.

This should be semantically equivalent to the current generator while removing thousands of repeated strings from the Worker bundle.

Questions

  1. Would maintainers prefer these as one Cloudflare-size PR or two smaller PRs?
  2. Is a versioned index.json plus ~4 MiB chunks acceptable for the internal Cloudflare catalog asset format?
  3. Is service-level executable marking acceptable given that the current registry generator already marks every definition action for an included provider as executable?

I can prepare a draft implementation with size measurements, compatibility tests, and before/after Wrangler output.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions