Features

Developers

Adding rate limits to your video uploader

September 6, 2021 - Doug Sillars in video create, Video upload, NodeJS

User generated content (UGC) can be an incredible addition to your application or website. Your users generate videos, and upload them to share with other users, creating a cascading effect that increases the number of videos on your platform.

In the past, we've looked at video moderation to protect you from inappropriate UGC. In this post, we'll look at mitigation strategies to limit the NUMBER of videos one user might upload. (Go here to check out the API reference documentation for uploading videos.)

Overwhelming video content

Your user might just be enthusiastic about our platform, or perhaps they have nefarious reasons - but they are just uploading too many videos! Perhaps you just want the videos to stop - so you could ban or cancel the user's account. But perhaps the videos are still welcome, they just need to slow down a bit.

In this post, we'll add a rate limiting step to upload.a.video/JS.html. This page uses our JS uploader to simplify video uploads.

Defining the rate limit

On our Node backend, we add the "express-rate-limit" library, and initialize it to allow for 5 uploads an hour:

//rate limiting code
//rate limiting to protect the demos
const rateLimit = require("express-rate-limit");
app.use(
	rateLimit({
	  windowMs:  60 * 60 * 1000, // 1 hour duration in milliseconds
	  max: 5,
	  message: "You exceeded 5 requests in 1 hour.",
	  headers: true,
	})
  );

We set the window for the rate limit to be one hour, and the maximum number of calls to be 5.

Now, the upload code does not use the NodeJS backend, so I created a dummy endpoint on the nodeJS server called "/ratelimit"

//this applies the ratelimit to all uploads.  Limit to 5 per hour
app.get('/ratelimit',(req,res)=>{
	console.log("rate limiting test");
	res.sendStatus(200);
});

Now we can make dummy calls to upload.a.video/ratelimit to trigger the rate limit in our JavaScript code.

Uploading in the browser

When the form changes, the EventListener fires. Previously, the video would begin uploading. Now, we make a call to the "/ratelimit" endpoint to see if we can commence the upload:

 input.addEventListener('change', () => {
		console.log("upload commencing");

		//adding in rate limiting to prevent abuse
		var qReq = new XMLHttpRequest();
		qReq.open("GET", "/ratelimit");
		qReq.onload = function (oEvent) {

			console.log(qReq.status);
				//once we create the video id do stuff
				if(qReq.status == 429){
					//rate limited
					document.getElementById("chunk-information").innerHTML = "Your uploads have been rate limited. We allow 5 uploads/hour with this demo app. Please try again in a bit."
				}
				else{
					//upload the first chunk to get the videoId
					//its ok to upload the video, we are not rate limited
					uploadFile(input.files[0]);
		
				}
		}
		qReq.send();

If the user has uploaded 5 videos in the last hour, the endpoint will return HTTP 429, and we update the website to tell the user that they have been rate limited.

429: too many requests

If the user is below the rate limit threshold, the rate limit endpoint will return HTTP 200. Since we have passed the rate limit 'test' we call the uploadFile function that uploads the video.

http dogs 200 http response

We genuinely hope that your UGC application will be successful, and one of the ways to ensure success is to allow UGC, but to lightly restrict how UGC can be added. Rate limiting is one of these light restrictions that you can implement to keep the content flowing, but to keep the pace of the content uploads a bit more manageable.

If you have any questions or suggestions, please share them on our community forum. If you don't have an api.video account yet, you can create one in just a few seconds here. Thanks for reading!

Doug Sillars

Head of Developer Relations

Create your free account

Start building with video now