In a recent Sitecore XP project, we built a controller route that generates PDFs of the pages on demand. While this worked well functionally, we realized that without any rate limiting, users (or bots) could easily overload the server by repeatedly hitting the endpoint. To prevent performance issues by overloading the server, we needed a simple way to throttle requests to this route.
The MvcThrottle Module
After exploring a few options, we landed on the MvcThrottle module that allows you to limit the number of HTTP requests a client can make to your Web API or MVC endpoints over a specified time window.
MvcThrottle tracks incoming requests based on client IP, endpoint, or custom keys, and enforces rate limits using in-memory or distributed stores. You can configure limits per second, minute, hour, or day, and when a limit is exceeded return a 429 Too Many Requests response.
Implementation in Sitecore XP
Here’s how we integrated MvcThrottle into my Sitecore XP solution:
- Add the NuGet Package
I added the MvcThrottle package to the Foundation layer of my solution, in this case the Foundation module handling Mvc customizations, using NuGet:
Install-Package MvcThrottle
- Register the MvcThrottle Module
MvcThrottle is typically registered inGlobal.asax
, but since this is a Sitecore solution, I registered it via the Sitecoreinitialize
pipeline for modularity and to avoid global configurations
using System.Web.Mvc;
using Sitecore.Pipelines;
using MvcThrottle;
namespace MyProject.Foundation.Mvc.Pipelines.Initialize
{
public class RegisterMvcThrottle
{
public void Process(PipelineArgs args)
{
var throttleFilter = new ThrottlingFilter
{
Policy = new ThrottlePolicy(
// Required parameter, set to null if not needed
perSecond: null,
perMinute: 5,
perHour: 100)
{
IpThrottling = true
},
Repository = new CacheRepository()
};
GlobalFilters.Filters.Add(throttleFilter);
}
}
}
- Apply the MvcThrottle Attribute
Next, I decorated the PDF generation controller action with the [EnableThrottling] attribute to enforce rate limits:
[HttpGet]
[EnableThrottling]
public ActionResult Pdf(string id)
{
// Pdf generation logic...
}
In this case we’re using the defaults configured in the module registration. If desired, you can set custom throttling parameters on each action by passing parameters with the EnableThrottling attribute.
- Handle 429 Errors
Finally, we need to handle the error thrown when a throttling limit is reached. This should map to a page in your site, like the 404 page, with a useful error. If you have a Foundation error handling module, you can handle it there. The simplest approach is to configure a custom error page for HTTP 429 responses in web.config:
<system.webServer>
<httpErrors errorMode="Custom">
<error statusCode="429" path="/error/ratelimit" responseMode="Redirect" />
</httpErrors>
</system.webServer>
Summary
MvcThrottle provided a quick and effective way to protect my PDF generation route from abuse. It’s easy to integrate, works well with Sitecore, and offers enough flexibility for most throttling scenarios. In this example we’re throttling by IP. It’s possible to configure this differently by changing the caching strategy. For example, if your site requires authentication, you could throttle by user id instead.