# Introducing API version 5

# Introduction

We've just released API version 5, which contains many enhancements and new features. Since the introduction of API version 4, our website traffic has tripled. Nowadays we handle 6 million requests per hour. It's an accomplishment that we're very proud of, handling such large amounts of traffic is a great challenge. This service would not have been reliable without the CDN provided by Cloudflare(opens new window) and effective software (such as nginx(opens new window) and libvips(opens new window)).

Here's a summary of the changes. To maintain backward compatibility, all parameters listed on API 4 still work on API 5. The source code is available on the 5.x branch(opens new window), this will become the default branch in the future.

# LuaJIT → C++

With API version 5 we've rewritten the entire codebase to C++ as a nginx module. The reason for this rewrite is to tighten the control over memory allocation. We found out that the current garbage collector (GC) in LuaJIT 2, which is essentially the same as the one in vanilla Lua 5.1, is not very fast for large workloads. A new GC is already proposed(opens new window) for LuaJIT 3.0, but it has not yet been implemented.

We also worried about the future of LuaJIT, given that the author of LuaJIT is stepping down(opens new window). It is doubtful whether anyone will fill his shoes. The new C++ codebase ensures that we can continue our service for many years to come.

# Revamped front-end

The old single index page had to be improved. We've completely revamped the front-end using VuePress(opens new window), which allows us to write the documentation as regular Markdown files.

The documentation is available in our weserv/docs(opens new window) GitHub repository.

# Improved rate limiter

We have improved our basic Redis rate limiter(opens new window). Our new rate limiter is written in C and runs inside a Redis backed nginx module. The implementation is based on the onsigntv/redis-rate-limiter(opens new window) module, which offers a straightforward implementation of the fairly sophisticated generic cell rate algorithm(opens new window), in 130 lines of C, without external dependencies.

An additional feature of this module is that it's easy to check your current rate limit quota:

$ curl -i https://images.weserv.nl/quota
HTTP/1.1 200 OK
Date: Sun, 01 Sep 2019 00:00:00 GMT
X-RateLimit-Limit: 2500
X-RateLimit-Remaining: 2500
X-RateLimit-Reset: 0

{"X-RateLimit-Limit":2500, "X-RateLimit-Remaining":2500, "X-RateLimit-Reset":0}


Our limit is around 2500 images per 10 minutes. Accessing this endpoint does not count against your rate limit.

The source code of the rate limiter can be viewed on GitHub: weserv/rate-limit-nginx-module(opens new window).

# Support for animated images

Thanks to libvips 8.8(opens new window), we've now enabled support for animated WebP and GIF images.

Animated image

# Support for loading HEIC images

We've added support for loading HEIC-images. This is the new image compression standard being used by Apple and others. HEIC files are typically half the size of JPEG files at similar quality.


Saving to HEIC-images isn't supported due to patent issues. Hopefully the use of royalty-free encoding formats such as AVIF(opens new window) will become more widely used in the future.

# CSS-inspired fit parameters

We've deprecated the confusing fit (&t=) parameters (fit, fitup, square, squaredown, absolute and letterbox) and aligned it with the CSS terminology.

Here's a handy table to help users migrating to these new CSS-inspired parameters:


The new without enlargement parameter (&we) can be used in combination with all &fit= parameters. We also introduced a new parameter named &fit=outside, which will resize an image to be as small as possible while ensuring its dimensions are greater than or equal to both those specified.

# Tinting images

We introduced a new parameter named &tint to tint an image using the provided chroma while preserving the image luminance.


# Arbitrary rotation angles

Instead of only being able to rotate multiples of 90 degrees, any angle can now be given. The remaining space can be filled with a background color by using &rbg=. To reflect this change, the &or= parameter has been renamed to &ro=.


# Adaptive filter and compression level

To minimize the size of PNG images and thus reduce their load time we've introduced some new parameters named &af and &l.

# Metadata output

To quickly view the metadata of an image, we've added support for &output=json. See here for an example.

# Flip / flop an image

We've added support for flipping an image horizontally or vertically. You can combine these parameters to flip along both axes.

# JSON for error messages

Instead of returning our error messages as plain text, you'll now receive a JSON-formatted response with the appropriate application/json MIME-type. This makes it easier to integrate our service into any type of website or application.

# Other improvements