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 and effective software (such as nginx and libvips).

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, 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 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. 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, which allows us to write the documentation as regular Markdown files.

The documentation is available in our weserv/docs GitHub repository.

Improved rate limiter

We have improved our basic Redis rate limiter. 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 module, which offers a straightforward implementation of the fairly sophisticated generic cell rate algorithm, 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://g.misakamoe.com/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}

TIP

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.

Support for animated images

Thanks to libvips 8.8, we've now enabled support for animated WebP and GIF images.

<img src="//g.misakamoe.com/?url=wsrv.nl/banana.webp&h=300&output=gif&n=-1">
![Animated image](https://g.misakamoe.com/?url=wsrv.nl/banana.webp&h=300&output=gif&n=-1)
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.

TIP

Saving to HEIC-images isn't supported due to patent issues. Hopefully the use of royalty-free encoding formats such as AVIF 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:

BeforeAfter
&t=fit&fit=inside&we
&t=fitup&fit=inside
&t=square&fit=cover
&t=squaredown&fit=cover&we
&t=absolute&fit=fill
&t=letterbox&fit=contain

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.

<img src="g.misakamoe.com/?url=wsrv.nl/lichtenstein.jpg&w=300&tint=red">
![Tint](https://g.misakamoe.com/?url=wsrv.nl/lichtenstein.jpg&w=300&tint=red)
Tint

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=.

<img src="//g.misakamoe.com/?url=wsrv.nl/lichtenstein.jpg&h=300&ro=45">
![Rotation](https://g.misakamoe.com/?url=wsrv.nl/lichtenstein.jpg&h=300&ro=45)
Rotation

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