ZPLToolkit

Limits and alternatives

“Request rate limit exceeded” when rendering ZPL

What a per-second rate limit on a ZPL rendering API means, the three ways around it, and how to stop hitting it at all.

What the error means

A ZPL rendering API turns each preview into an HTTP request, and to keep one caller from saturating the service those requests are capped per second. Going over the cap does not queue your request — it rejects it, which is why the failure arrives as an error rather than as a slow response.

The cap is per second, not per day, so this is the error you get from a loop. A script rendering a batch of labels as fast as it can will trip it within the first dozen; the same script with a pause between calls will not trip it at all.

Check the service's own documentation for the current numbers. Operators change them, and a guide that hard-codes a figure is wrong the day after they do.

Three ways past it

  1. 1Slow the loop down. A delay between requests that keeps you under the documented rate is the smallest change, and it costs you only wall-clock time. Add a retry with backoff for the ones that fail anyway.
  2. 2Send fewer requests. Most rendering APIs accept several labels in one call and return several images. Batching is usually a bigger win than pacing, because it reduces the request count rather than spreading it out.
  3. 3Render locally instead. A renderer that runs in your browser makes no requests at all, so there is no rate to exceed. That is the option with no ceiling, and the trade is that a local renderer will not match a printer on every command.

How to stop hitting it

Most rate-limit trouble comes from previewing in the wrong place in the pipeline. If every label in a batch is rendered to check the template, the template is what needed checking — once, not two hundred times.

A useful split is to validate every label and render only the ones that need looking at. A linter tells you about an unbalanced ^XA, a field off the edge of the label or a bar code with no quiet zone without drawing anything, so it costs nothing per label and catches most of what a visual check would have.

^XA
^PW812
^LL1218
^FO50,50^A0N,50,50^FDShipment 4821^FS
^BY3,3,120
^FO50,140^BCN,120,Y,N,N^FD0123456789^FS
^XZ
A label like this one can be checked for structure, bounds and quiet zones without rendering it at all.

Open the ZPL viewer

Render as many labels as you like, locally, with no request to rate-limit and nothing uploaded.

Open the ZPL viewer

Common questions

Will waiting and retrying fix it?
For a one-off, yes — a rate limit is per second, so the next second is a fresh budget. For a batch, retrying without pacing just trips the limit again a moment later; add a delay or back off exponentially.
Is a rate limit the same as a daily quota?
No. A rate limit is how fast you may ask, and it resets constantly; a daily quota is how much you may ask for in total, and it resets once a day. The fixes are different — pacing solves one and only volume reduction solves the other.
Does previewing in the browser have a rate limit?
No, because there is no request to limit. Rendering happens on your machine, so the only ceiling is how fast your machine draws.

Related guides