Skip to content

Cloudflare Integration


1. Upload to R2

Uploading via Web UI is limited to 300 MB.

Use rclone to upload larger PMTiles archives to R2.

Name your uploads to storage with the .pmtiles extension. Your tile requests to the Workers URL will look like /FILENAME/0/0/0.ext for the archive FILENAME.pmtiles.

2. Create Worker with Web Console

  1. In the Workers tab of the Cloudflare dashboard, choose Create a Service.

  2. Leave the default HTTP handler option.

  3. in Settings for your worker, choose Variables > R2 Bucket Bindings > Add Binding.

  • Create variable with name BUCKET and select your R2 bucket from Step 1.

  • Choose Save and Deploy.

  1. in Quick Edit, paste in this code: index.js.
  • Choose Save and Deploy.

Your worker should now be active at its * domain.

Make a request for /FILENAME/0/0/0.EXT to verify tiles are served.

Alternative: Use Wrangler

  1. Clone the PMTiles repository and change to the serverless/cloudflare directory.

  2. npm install in PMTiles/js to get the dependencies of the core JS library

  3. Also npm install in PMTiles/serverless/cloudflare

  4. Copy wrangler.toml.example to wrangler.toml

  5. Edit wrangler.toml, replacing bucket_name with your bucket.

  6. Publish the worker: npm run deploy

3. Create Worker Route

For the cache to work, the worker must be assigned a zone on your own domain, not

  1. In Websites > your domain > DNS, Add a CNAME entry pointing to your domain:

cloudflare image

  1. In Websites > your domain > Workers Routes, Choose Add Route.
  • for Route, enter*

  • for Service, choose the name of your Worker. for Environment, choose production.

cloudflare image

Verify your deployment is working on by checking for the Cf-Cache-Status header with a value of HIT on tile requests. This may take 2-3 attempts.

Example with curl for vector tiles and TileJSON:

curl -v

curl -v
curl -v

curl -v


Optional environment variables can be set set in [vars] of wrangler.toml or in the Workers web console.

  • PMTILES_PATH - A string like folder/{name}.pmtiles specifying the path to archives in your bucket. Default {name}.pmtiles

  • TILES_PATH - a string like prefix/{name}/{z}/{x}/{y}.{ext} specifying the tile path exposed by the worker. Default {name}/{z}/{x}/{y}.{ext} Deprecated

  • PUBLIC_HOSTNAME - Optional, override the absolute hostname in TileJSON responses. Example

  • ALLOWED_ORIGINS - a comma-separated list of allowed CORS origins. Default none. Examples:,https://localhost:3000, *

  • CACHE_MAX_AGE: max age in the Cloudflare cache, in seconds. default 86400, or 1 day.

Cost Estimate

  • Cloudflare Workers is $5 USD per month with 10 million requests a month included, plus $0.50 per additional million.
  • Cloudflare R2 incurs costs for storage, write requests and read requests. These will only happon on tile cache misses.

Cache Invalidation

  • For Cloudflare, "Purge Cache" applies to all cached resources in the zone (domain). It's recommended to deploy on a dedicated zone for this reason.

An open source mapping system released under the BSD and ODbL licenses.