Custom Strapi Middleware: Rate Limiting, Logging, Transformation

Custom Strapi Middleware

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1285
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1241
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    982
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1033
  • image_website-sbh_0.webp
    Website development for SBH Partners
    1104
  • image_website-_0.webp
    Website development for Red Pear
    554

Custom Strapi Middleware

Is your Strapi project struggling with 1000 requests per minute? Logs scattered, clients complaining about 429 errors? Typical scenario: navigation starts lagging, response time drops to 800 ms. To fix this, we implement custom middleware — functions that intercept requests before and after controller processing. Our experience: we've implemented such middleware for over 50 projects — from e-commerce stores to complex CMS. Custom Strapi middleware allows flexible request management: throttling, audit trail, access control, response modification.

Middleware is a concept familiar to Express or Koa developers: they work in a chain, passing control via await next(). Strapi supports two types: global (applied to all routes) and route-specific (only to certain routes). Here's a comparison:

Type Scope Registration
Global All requests config/middlewares.js
Route Specific route Route configuration

How rate limiting affects Strapi performance

In-memory rate limiting is one of the most requested middleware. It stores request timestamps per IP in a Map. When the number of requests in a window (e.g., 100 per 60 seconds) exceeds the limit, it returns 429. In-memory is 10x faster than file-based — minimal latency under 1 ms. For distributed systems, we use Redis (adds 1-3 ms latency but scales horizontally); we help with that too. Here is typical code:

// src/middlewares/rate-limit.ts const requests = new Map<string, number[]>() export default (config: any) => { const { maxRequests = 100, windowMs = 60_000 } = config return async (ctx: any, next: any) => { const ip = ctx.request.ip const now = Date.now() const windowStart = now - windowMs const timestamps = (requests.get(ip) || []).filter(t => t > windowStart) if (timestamps.length >= maxRequests) { ctx.status = 429 ctx.body = { error: 'Too Many Requests' } ctx.set('Retry-After', String(Math.ceil(windowMs / 1000))) return } timestamps.push(now) requests.set(ip, timestamps) await next() } } 

Configure in config/middlewares.js as 'global::rate-limit' with maxRequests and windowMs parameters.

In-memory rate limiting with Map yields under 1 ms latency, Redis gives 1-3 ms but scales horizontally. For projects up to 1000 requests/sec, in-memory suffices; from 1000 to 5000, we use Redis. On one project (e-commerce store with 3000 products), after implementing rate limiting and caching middleware, TTFB dropped from 800 ms to 200 ms (a 75% reduction), and 429 errors completely disappeared. This saved $500 per month on server resources (≈$6000 annually).

Why log requests via middleware

The default Strapi logger cannot track slow requests. Custom middleware with timing solves this: it logs all requests and marks slow ones (over 1 second). This helps find bottlenecks before they become critical. Example:

// src/middlewares/request-logger.ts export default (config: any, { strapi }: any) => { return async (ctx: any, next: any) => { const start = Date.now() await next() const duration = Date.now() - start const { method, url, status } = ctx if (duration > 1000) { strapi.log.warn(`Slow request: ${method} ${url} — ${duration}ms (${status})`) } strapi.log.debug(`${method} ${url} — ${duration}ms [${status}]`) } } 

It is registered globally via the middleware configuration file. We guarantee you won't miss any problematic requests after setup.

How we implement subscription check via middleware

For premium content, we use route middleware that checks the user's active subscription. Such middleware only applies to a single route, not burdening others:

// src/middlewares/check-subscription.ts export default (config: any, { strapi }: any) => { return async (ctx: any, next: any) => { const userId = ctx.state.user?.id if (!userId) { ctx.unauthorized('Authentication required') return } const user = await strapi.entityService.findOne( 'plugin::users-permissions.user', userId, { populate: ['subscription'] } ) if (!user?.subscription?.active) { ctx.forbidden('Active subscription required') return } await next() } } 

In the route configuration, add the field middlewares: ['api::check-subscription'].

Why middleware matter for Core Web Vitals

Each middleware can improve Core Web Vitals. For example, caching middleware reduces TTFB, and rate limiting prevents server overload and INP degradation. If your API returns data in 800 ms, it directly affects LCP. Middleware can cache responses or limit frequency, reducing latency by up to 75%.

Response transformation and multilingual support

Often you need to add a computed field — for example, discount percentage. Middleware intercepts the response and adds discountPercent. For multilingual projects, middleware can automatically determine the locale from the Accept-Language header:

// src/middlewares/add-computed-fields.ts export default () => { return async (ctx: any, next: any) => { await next() if (ctx.url.startsWith('/api/products') && ctx.body?.data) { const transform = (item: any) => ({ ...item, attributes: { ...item.attributes, discountPercent: item.attributes.originalPrice ? Math.round((1 - item.attributes.price / item.attributes.originalPrice) * 100) : 0, }, }) if (Array.isArray(ctx.body.data)) { ctx.body.data = ctx.body.data.map(transform) } else { ctx.body.data = transform(ctx.body.data) } } } } 
// src/middlewares/locale-redirect.ts const localeMap: Record<string, string> = { 'ru-RU': 'ru', 'en-US': 'en', 'uk-UA': 'uk', } export default () => { return async (ctx: any, next: any) => { if (!ctx.query.locale) { const acceptLang = ctx.get('Accept-Language')?.split(',')[0] || 'ru' const locale = localeMap[acceptLang] || acceptLang.split('-')[0] || 'ru' ctx.query.locale = locale } await next() } } 

Which middleware are essential for production

The essential set includes throttling, audit trail, access control, and response modification. Additionally, caching, redirects, and CORS can be added. We help select the optimal set for your load. The cost varies depending on complexity; a typical set of 3–4 middleware costs $500–$1000 for development. We provide a detailed quote after analyzing your project.

Step-by-step rate limiting middleware configuration

  1. Create the file src/middlewares/rate-limit.ts with the code from the example.
  2. In config/middlewares.js, add 'global::rate-limit' to the middlewares array.
  3. Configure maxRequests and windowMs parameters according to your load (e.g., 100 requests per 60 seconds).
  4. Test locally with npx strapi develop.
  5. For production, use Redis via external storage if scaling beyond 1000 requests/sec.

For more details on middleware configuration, see the official Strapi documentation.

Work process and what's included

We work as follows: analyze requirements → design middleware architecture → write code with tests → deploy to staging → deploy to production. The result includes:

  • Source code of middleware with comments
  • Installation and configuration documentation
  • Git repository access
  • 1-hour online training for your team
  • 2 weeks of support after launch

Approximate timeline

Development of a set of 3-4 middleware (e.g., throttling, audit trail, access control, response modification) takes 1 to 2 days. Cost is calculated individually, typically $500–$1000.

Contact us to evaluate your project — we'll select the optimal middleware set for your load. Get a consultation on custom Strapi middleware and order turnkey development with a 2-week support guarantee.