Caching, limits and errors
How Block Render caches models and PNGs, which response headers to rely on, the size limits, how ETags make a repeat request free, and every error code.
Response headers
HTTP/2 200
content-type: image/png
cache-control: public, max-age=604800, immutable
etag: "6b6b0a0f2f0f4f2a1c7c9a1d0e2"
access-control-allow-origin: *
cross-origin-resource-policy: cross-origin
x-robots-tag: all
x-cache: MISS
x-render-ms: 3.4
x-model: block/grass_block Cache-Controlisimmutableon renders and textures. The Minecraft version is pinned and the renderer is deterministic, so the bytes behind a URL genuinely cannot change; when the version moves, so does what the ids mean, and that is a deliberate decision rather than a background update.X-CacheisHITorMISSagainst the in-memory render cache.X-Render-Msis the time spent rasterising and encoding,0on a cache hit.X-Modelnames the Minecraft model the render came from, which is the quickest way to see why a block looks the way it does.X-Ignored-Paramsappears when you sent a query key that is not a parameter of this endpoint at all, which is usually a typo.Access-Control-Allow-Origin: *andCross-Origin-Resource-Policy: cross-origin, so the images work from any page and any canvas.X-Robots-Tagisallon a bare render, on the five download sizes and on every raw texture, so they can appear in image search; any other combination of parameters answersnoindex, because that space is unbounded and each combination is its own URL.
JSON from /api/ is public, max-age=86400. Pages carry an ETag and
must-revalidate, so a revisit is a 304 rather than another 30 kB.
ETags and 304s
The ETag is a hash of everything that determines the bytes: the id, the endpoint and the resolved
options. Two URLs that mean the same thing — /stone and /stone.png,
size=256 and the default — get the same ETag and the same cache entry.
curl -sI "https://blockrender.dev/render/block/stone.png" # note the etag
curl -sI -H 'If-None-Match: "<that etag>"' \
"https://blockrender.dev/render/block/stone.png" # 304, no body Size limits
size,widthandheightare 8–1024 pixels.- The finished image may not exceed 1,048,576 pixels of area, so 1024×1024 is the largest square.
aais 1–4, and is lowered automatically so that the supersampled canvas stays within 2048×2048. Ask foraa=4at 1024 px and you getaa=2.
Speed
Measured with npm run bench on a warm process — rasterising plus PNG encoding, which is
what a cache miss costs:
| Request | Render | PNG |
|---|---|---|
| Item sprite, 256 px | 0.6 ms | 0.4 ms |
| Block, 128 px | 0.5 ms | 0.5 ms |
| Block, 256 px | 1.6 ms | 1.0 ms |
| Block, 512 px | 5.7 ms | 1.8 ms |
| Block, 1024 px | 23 ms | 5 ms |
| Item sprite, 1024 px | 7.6 ms | 3.2 ms |
Those are medians on a developer machine. On the live server, a 512 px block forced to miss the cache
reads 8–10 ms on X-Render-Ms, which covers rasterising and encoding together. The first
render after a restart is several times slower — 54 ms was the very first one — while the JIT warms
up, so quote a tidy single number and the next measurement contradicts it.
A repeated URL is a memory cache hit and renders nothing at all. If you want the real figure for your
own request, read X-Render-Ms off the response; that beats trusting a number in prose
that nobody re-measured.
Rate limits
There is no published rate limit and no key. Renders are cached in memory and answered with an ETag, so the sane way to use this is to let your own cache or CDN do its job and revalidate. Hammering the same URL in a loop is the only thing that would ever get anyone limited, and it is also the thing that costs you the most.
Errors
| Status | When |
|---|---|
400 | A parameter is out of range, malformed, or not a parameter at all in a way that cannot be ignored. The body says what was expected. |
404 | No such id in this version, or the id exists but the game draws it with code and there is no model to rasterise. The body lists near misses. |
500 | Something broke here. Worth reporting. |
Errors are always plain text with the right status, never a PNG containing the word "error" — an image that returns 200 for a mistake is a bug that hides in a page for months.
Using the images
The textures are Mojang's. Renders made from them sit in the same place as a screenshot or a wiki image: fine for fan sites, wikis, plugin pages, Discord bots, videos and documentation; not for anything that passes itself off as an official Minecraft product, and not as a way of shipping the game's art as a texture pack. There is deliberately no whole-pack or archive download here, only individual renders and the individual textures behind them, one page at a time.
Not an official Minecraft product. Not approved by or associated with Mojang or Microsoft. See About.