{"id":17835055,"url":"https://github.com/namesmt/hono-object-storage-pmtiles-server","last_synced_at":"2026-01-21T21:32:50.444Z","repository":{"id":258981006,"uuid":"873343242","full_name":"NamesMT/hono-object-storage-pmtiles-server","owner":"NamesMT","description":"Example repo for a Hono tile server in front of a pmtiles source stored in object storage (S3-compatible) provider","archived":false,"fork":false,"pushed_at":"2026-01-20T03:06:04.000Z","size":94,"stargazers_count":6,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-20T09:56:00.398Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NamesMT.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-10-16T02:21:11.000Z","updated_at":"2025-11-29T21:26:16.000Z","dependencies_parsed_at":"2025-12-17T14:00:15.497Z","dependency_job_id":null,"html_url":"https://github.com/NamesMT/hono-object-storage-pmtiles-server","commit_stats":null,"previous_names":["namesmt/hono-object-storage-pmtiles-server"],"tags_count":0,"template":false,"template_full_name":"NamesMT/starter-ts","purl":"pkg:github/NamesMT/hono-object-storage-pmtiles-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NamesMT%2Fhono-object-storage-pmtiles-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NamesMT%2Fhono-object-storage-pmtiles-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NamesMT%2Fhono-object-storage-pmtiles-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NamesMT%2Fhono-object-storage-pmtiles-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NamesMT","download_url":"https://codeload.github.com/NamesMT/hono-object-storage-pmtiles-server/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NamesMT%2Fhono-object-storage-pmtiles-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28644061,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T21:29:11.980Z","status":"ssl_error","status_checked_at":"2026-01-21T21:24:31.872Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-27T20:16:39.963Z","updated_at":"2026-01-21T21:32:50.422Z","avatar_url":"https://github.com/NamesMT.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hosps ![TypeScript heart icon](https://img.shields.io/badge/♡-%23007ACC.svg?logo=typescript\u0026logoColor=white)\n\n**hosps (hono-object-storage-pmtiles-server)** is an example repo for a tile server using [PMTiles](https://github.com/protomaps/PMTiles) and [Hono](https://honojs.dev/), with an object storage (a.k.a S3-compatible storage) provider.  \n\nWhile PMTiles support direct usage with range requests, a tile-server is necessary for security and performance like caching.\n\n\n### Info \u0026 Bench\nThis PMTiles server is also A LOT MORE faster, and efficient than [Martin tile server](https://github.com/maplibre/martin), though, because of the SDK (`aws-lite`) to interract with object storage provider (S3 / Tigris / R2), the base memory is a bit high, though, for environments like Cloudflare Workers and R2, you could use a custom PMTiles `Source` that could bypass the SDK.\n\nThe comparison is also unfair for this server vs Martin, because for this server we fetch from the storage securely with tokens, while with Martin I set the bucket to public and let it directly connect to the storage url without signing overhead.\n\nBench setup: one fly.io machine for each, size: shared 1x 512MB.\nBench method: fetching random tiles from browser with caching disabled.\n\nBench code snippets:\n```js\nconst fetchTile = async (domain, z, x, y) =\u003e {  \n    const url = `https://${domain}/world/${z}/${x}/${y}`;  \n    const startTime = performance.now(); // Start time for the fetch  \n    const response = await fetch(url);  \n    const endTime = performance.now(); // End time for the fetch  \n    \n    console.log(`Fetched tile at ${url} in ${(endTime - startTime).toFixed(2)} ms`);  \n};  \n\nconst fetchTiles = async (domain, numTiles) =\u003e {  \n    const promises = [];  \n    const overallStartTime = performance.now(); // Start time for overall fetching  \n\n    for (let i = 0; i \u003c numTiles; i++) {  \n        const z = Math.floor(Math.random() * 5);\n        const x = Math.floor(Math.random() * 100);\n        const y = Math.floor(Math.random() * 100);\n        promises.push(fetchTile(domain, z, x, y));  \n    }  \n\n    await Promise.all(promises);  \n    const overallEndTime = performance.now(); // End time for overall fetching  \n    console.log(`Fetched ${numTiles} tiles in ${(overallEndTime - overallStartTime).toFixed(2)} ms`);  \n}; \n```\n```js\n// 10 batches of 500 parallel requests\nfor (let i=0; i\u003c10; i++)\n    await fetchTiles('machine.fly.dev', 500);\n```\n\nMartin's results:\n```\nFetched 500 tiles in 10455.10 ms\nFetched 500 tiles in 13348.80 ms\nFetched 500 tiles in 13815.40 ms\nFetched 500 tiles in 11839.60 ms\nFetched 500 tiles in 16080.70 ms\nFetched 500 tiles in 22558.40 ms\nFetched 500 tiles in 4051.30 ms\nFetched 500 tiles in 4672.30 ms\nFetched 500 tiles in 3815.60 ms\nFetched 500 tiles in 4101.00 ms\n```\nSomewhere at the middle a few requests started to fail and then the server went dead from OOM and come back processing a bit faster for some reason idk.  \nBase memory: 88-89 MB  \nPeak: maxed and died from OOM.  \nFirecracker load: 0.2  \n\n\nNode's results:\n```\nFetched 500 tiles in 2175.10 ms\nFetched 500 tiles in 1417.80 ms\nFetched 500 tiles in 1248.80 ms\nFetched 500 tiles in 1344.10 ms\nFetched 500 tiles in 1248.20 ms\nFetched 500 tiles in 1279.30 ms\nFetched 500 tiles in 1376.80 ms\nFetched 500 tiles in 1599.60 ms\nFetched 500 tiles in 1166.70 ms\nFetched 500 tiles in 1176.50 ms\n```\nBase memory: 160.5 MB  \nPeak: 182.5 MB  \nFirecracker load: it's so low it doesn't even display any load, when increasing the test to 1000 parallel tiles the max load is 0.1.  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnamesmt%2Fhono-object-storage-pmtiles-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnamesmt%2Fhono-object-storage-pmtiles-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnamesmt%2Fhono-object-storage-pmtiles-server/lists"}