### Full Configuration Example Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/README.md A comprehensive example demonstrating various configuration options for the under-pressure plugin, including thresholds, error handling, and health monitoring. ```javascript fastify.register(require('@fastify/under-pressure'), { // Thresholds (set to 0 to disable) maxEventLoopDelay: 1000, // 1 second maxEventLoopUtilization: 0.95, // 95% busy maxHeapUsedBytes: 200000000, // 200 MB maxRssBytes: 500000000, // 500 MB // Error configuration message: 'Service Unavailable', retryAfter: 10, // seconds customError: MyError, // optional // Pressure handling pressureHandler: (request, reply, type, value) => { // Custom logic here }, // Health monitoring healthCheck: async (fastify) => { return await database.ping() }, healthCheckInterval: 5000, // milliseconds // Measurement sampleInterval: 1000, // milliseconds // Status endpoint exposeStatusRoute: { url: '/health', routeOpts: { logLevel: 'silent' } } }) ``` -------------------------------- ### Install @fastify/under-pressure Source: https://github.com/fastify/under-pressure/blob/main/README.md Install the package using npm. ```bash npm i @fastify/under-pressure ``` -------------------------------- ### Example Request to Status Route Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/endpoints.md A sample GET request to the default '/status' endpoint. No request body or query parameters are required. ```http GET /status HTTP/1.1 Host: example.com ``` -------------------------------- ### Basic Fastify Setup with Under Pressure Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/quick-reference.md Register the under-pressure plugin with basic configuration for maximum event loop delay and heap/RSS bytes. ```javascript const fastify = require('fastify')() const underPressure = require('@fastify/under-pressure') fastify.register(underPressure, { maxEventLoopDelay: 1000, maxHeapUsedBytes: 100000000, maxRssBytes: 100000000 }) fastify.listen({ port: 3000 }) ``` -------------------------------- ### Full Fastify Under Pressure Configuration with Types Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/types.md A comprehensive TypeScript example demonstrating how to register and configure the Fastify Under Pressure plugin with various options. ```typescript import fastify, { FastifyInstance } from 'fastify' import underPressure from '@fastify/under-pressure' const app: FastifyInstance = fastify() app.register(underPressure, { maxEventLoopDelay: 1000, maxHeapUsedBytes: 200000000, message: 'Server overloaded', retryAfter: 30, healthCheck: async (fastify) => { const isConnected = await database.ping() return isConnected }, healthCheckInterval: 5000, pressureHandler: (request, reply, type, value) => { if (type === underPressure.TYPE_HEAP_USED_BYTES) { reply.log.warn(`High heap: ${value}`) } reply.send('Degraded mode') }, exposeStatusRoute: { url: '/health', routeOpts: { logLevel: 'silent' } } }) app.get('/', (request, reply) => { const metrics = app.memoryUsage() const underPressure = app.isUnderPressure() reply.send({ metrics, underPressure }) }) ``` -------------------------------- ### Production-Ready Health Check Example Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/healthCheck.md This example demonstrates a production-ready health check configuration with caching, timeouts, and checks for database and cache services. It includes a structured response schema. ```javascript const cacheHealthCheck = { result: true, lastCheck: 0, maxAge: 2000 // Cache for 2 seconds } fastify.register(underPressure, { healthCheck: async (fastify) => { const now = Date.now() // Use cached result if recent if (now - cacheHealthCheck.lastCheck < cacheHealthCheck.maxAge) { return cacheHealthCheck.result } try { // Check all services with timeout protection const checks = await Promise.race([ Promise.all([ fastify.pg.query('SELECT 1').then(() => true).catch(() => false), fastify.redis.ping().then(() => true).catch(() => false) ]), new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 5000) ) ]) const [dbOk, cacheOk] = checks cacheHealthCheck.result = dbOk && cacheOk cacheHealthCheck.lastCheck = now return { database: dbOk, cache: cacheOk } } catch (error) { fastify.log.warn({ error }, 'Health check failed') cacheHealthCheck.result = false cacheHealthCheck.lastCheck = now return false } }, healthCheckInterval: 5000, exposeStatusRoute: { url: '/health', routeResponseSchemaOpts: { database: { type: 'boolean' }, cache: { type: 'boolean' } } } }) ``` -------------------------------- ### Basic Success Response Example (No Health Check) Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/endpoints.md An example of a successful HTTP response (200 OK) from the status route when no custom health check function is configured. ```json HTTP/1.1 200 OK Content-Type: application/json { "status": "ok" } ``` -------------------------------- ### Configure Simple Memory Limits Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/README.md Example of registering the plugin with specific limits for maximum heap usage and resident set size (RSS) in bytes. ```javascript fastify.register(underPressure, { maxHeapUsedBytes: 200000000, // 200 MB maxRssBytes: 500000000 // 500 MB }) ``` -------------------------------- ### Health Check Examples Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/healthCheck.md Provides examples of how to implement the healthCheck function, including simple boolean returns, returning custom data objects, and conditional logic. ```APIDOC ## Examples ```javascript // Simple boolean return healthCheck: async (fastify) => { const isConnected = await database.ping() return isConnected // true or false } // Return object with custom data healthCheck: async (fastify) => { return { database: await db.ping(), cache: await redis.ping(), version: process.env.APP_VERSION } } // Conditional return healthCheck: async (fastify) => { const connectedServices = await checkServices() if (connectedServices >= 2) { return true // At least 2 services are up } return false // Less than 2 services } ``` ``` -------------------------------- ### Minimal Under Pressure Setup (Tracking Only) Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/quick-reference.md Register the plugin without any thresholds to only decorate Fastify with memoryUsage() and isUnderPressure() methods. No automatic request rejection occurs. ```javascript fastify.register(underPressure) // Decorates with memoryUsage() and isUnderPressure() // No automatic request rejection ``` -------------------------------- ### Under Pressure Setup with Health Check Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/quick-reference.md Configure under-pressure with a custom asynchronous health check function and interval, and enable the status route for monitoring. ```javascript fastify.register(underPressure, { healthCheck: async (fastify) => { return await database.ping() }, healthCheckInterval: 5000, exposeStatusRoute: true }) ``` -------------------------------- ### Under Pressure Setup with Custom Error Handling Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/quick-reference.md Register the plugin with custom thresholds and a `pressureHandler` function to define a custom response when the server is under pressure. ```javascript fastify.register(underPressure, { maxHeapUsedBytes: 200000000, pressureHandler: (req, rep, type, value) => { rep.send({ status: 'degraded' }) } }) ``` -------------------------------- ### Under Pressure Setup with Thresholds Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/quick-reference.md Configure under-pressure with specific thresholds for heap and RSS bytes. The server will return a 503 status code when these thresholds are exceeded. ```javascript fastify.register(underPressure, { maxHeapUsedBytes: 200000000, maxRssBytes: 500000000 }) // Returns 503 when thresholds exceeded ``` -------------------------------- ### Custom Pressure Handler Example Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/module-overview.md Illustrates how to implement a custom `pressureHandler` function to intercept and manage specific pressure events, such as high memory usage. ```javascript pressureHandler: (request, reply, type, value) => { if (type === 'heapUsedBytes') { // Handle high memory return 'Temporarily degraded' } // Continue normally } ``` -------------------------------- ### Default Error Response Example Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/errors.md This JSON illustrates the structure of the default error response sent to a client when the 'FST_UNDER_PRESSURE' error occurs. ```json HTTP/1.1 503 Service Unavailable Content-Type: application/json Retry-After: 10 { "code": "FST_UNDER_PRESSURE", "error": "Service Unavailable", "message": "Service Unavailable", "statusCode": 503 } ``` -------------------------------- ### Pressure Handler: Continue Normally (No Return) Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/errors.md This JavaScript example shows a 'pressureHandler' that logs a warning but returns nothing. In this case, the request continues processing normally. ```javascript pressureHandler: (req, rep, type, value) => { req.log.warn(`Pressure: ${type} = ${value}`) // No return → request continues } ``` -------------------------------- ### Basic Fastify Memory Usage Metrics Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/memoryUsage.md Register the `@fastify/under-pressure` plugin and access memory usage metrics via `fastify.memoryUsage()`. This example displays heap usage, RSS, event loop delay, and utilization in MB and ms. ```javascript const fastify = require('fastify')() const underPressure = require('@fastify/under-pressure') fastify.register(underPressure, { maxEventLoopDelay: 1000 }) fastify.get('/metrics', (request, reply) => { const metrics = fastify.memoryUsage() reply.send({ heapUsedMB: Math.round(metrics.heapUsed / 1024 / 1024), rssMB: Math.round(metrics.rssBytes / 1024 / 1024), eventLoopDelayMs: Math.round(metrics.eventLoopDelay), eventLoopUtilization: metrics.eventLoopUtilized.toFixed(2) }) }) ``` -------------------------------- ### Simple Threshold Enforcement Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/module-overview.md Registers the under-pressure plugin to reject requests when the heap memory usage exceeds a specified limit (200MB in this example). ```javascript fastify.register(underPressure, { maxHeapUsedBytes: 200000000 }) // Requests are rejected when heap exceeds 200MB ``` -------------------------------- ### Registering Under Pressure with Health Check, Interval, and Status Route Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/healthCheck.md This example shows a comprehensive configuration of the under-pressure plugin, including a health check that returns custom data, periodic checking, and a custom status route. Ensure `exposeStatusRoute` options are correctly defined. ```javascript fastify.register(underPressure, { healthCheck: async (fastify) => { const db = await fastify.database.ping() const cache = await fastify.redis.ping() return { db, cache } }, healthCheckInterval: 10000, // Check every 10 seconds exposeStatusRoute: { url: '/health', routeResponseSchemaOpts: { db: { type: 'boolean' }, cache: { type: 'boolean' } } } }) ``` -------------------------------- ### Pressure Handler: Custom Response via Return Value Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/errors.md This JavaScript example shows a 'pressureHandler' that returns a string. This string is then sent directly to the client as the response. ```javascript pressureHandler: (req, rep, type, value) => { return 'Service temporarily unavailable' } ``` -------------------------------- ### Background Task Queueing with isUnderPressure Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/isUnderPressure.md Manage background tasks by queuing them when the server is under pressure and processing them later when the load decreases. This example uses a simple array as a task queue. ```javascript const fastify = require('fastify')() const underPressure = require('@fastify/under-pressure') const taskQueue = [] fastify.register(underPressure, { maxHeapUsedBytes: 200000000 }) fastify.post('/task', async (request, reply) => { if (fastify.isUnderPressure()) { // Queue the task for later processing taskQueue.push(request.body) return reply.status(202).send({ queued: true }) } // Process immediately const result = await processTask(request.body) reply.send(result) }) // Background worker setInterval(() => { if (!fastify.isUnderPressure() && taskQueue.length > 0) { const task = taskQueue.shift() processTask(task).catch(err => fastify.log.error(err)) } }, 5000) ``` -------------------------------- ### Pressure Handler: Throwing an Error Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/errors.md This JavaScript example demonstrates a 'pressureHandler' that throws an error under specific conditions (e.g., health check failure). The error will propagate to Fastify's main error handler. ```javascript pressureHandler: async (req, rep, type, value) => { if (type === underPressure.TYPE_HEALTH_CHECK) { throw new Error('Critical external service is down') } } ``` -------------------------------- ### Pressure Handler: Custom Response via reply.send() Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/errors.md This JavaScript example shows a 'pressureHandler' that calls 'rep.send()' to send a custom JSON response to the client, indicating a degraded service state. ```javascript pressureHandler: (req, rep, type, value) => { rep.send({ status: 'degraded', queue_position: getQueueLength() }) } ``` -------------------------------- ### Custom Error Class for Overload Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/configuration.md This example shows how to define and use a custom error class for server overload conditions. This allows for more specific error handling and reporting when the server exceeds its resource limits. ```javascript class SystemOverloadError extends Error { constructor() { super('System is overloaded') this.code = 'SYSTEM_OVERLOAD' Error.captureStackTrace(this, SystemOverloadError) } } fastify.register(require('@fastify/under-pressure'), { maxHeapUsedBytes: 100000000, customError: SystemOverloadError }) ``` -------------------------------- ### Health Check Failed Response Example (503) Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/endpoints.md An example of a 503 Service Unavailable response when the health check fails. Includes the 'Retry-After' header. ```json HTTP/1.1 503 Service Unavailable Content-Type: application/json Retry-After: 30 { "code": "FST_UNDER_PRESSURE", "error": "Service Unavailable", "message": "Service Unavailable", "statusCode": 503 } ``` -------------------------------- ### Registering @fastify/under-pressure with Options Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/module-overview.md Demonstrates how to register the @fastify/under-pressure plugin with various configuration options for thresholds, health monitoring, response handling, and measurement. ```javascript fastify.register(underPressure, { // Thresholds (all optional, default to 0 = disabled) maxEventLoopDelay: 1000, // milliseconds maxEventLoopUtilization: 0.95, // ratio 0-1 maxHeapUsedBytes: 200000000, // bytes maxRssBytes: 500000000, // bytes // Health monitoring healthCheck: async (fastify) => { ... }, healthCheckInterval: 5000, // milliseconds // Response handling pressureHandler: (req, rep, type, value) => { ... }, message: 'Service Unavailable', retryAfter: 10, // seconds customError: CustomErrorClass, // Measurement sampleInterval: 1000, // milliseconds // Status endpoint exposeStatusRoute: true | '/health' | { ... } }) ``` -------------------------------- ### Custom Error Response Example Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/errors.md This JSON shows an example of a default error response with a custom message and a longer 'Retry-After' header, indicating a more severe overload condition. ```json HTTP/1.1 503 Service Unavailable Content-Type: application/json Retry-After: 30 { "code": "FST_UNDER_PRESSURE", "error": "Service Unavailable", "message": "Server is overloaded. Please retry after 30 seconds.", "statusCode": 503 } ``` -------------------------------- ### Configuration Options Summary Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/quick-reference.md A summary of all available configuration options for the @fastify/under-pressure plugin, detailing their type, default values, and purpose. ```APIDOC ## Configuration Options Summary | Option | Type | Default | Description | |---|---|---|---| | maxEventLoopDelay | number | 0 | Max delay in ms (0 = disabled) | | maxEventLoopUtilization | number | 0 | Max utilization 0-1 (0 = disabled) | | maxHeapUsedBytes | number | 0 | Max heap in bytes (0 = disabled) | | maxRssBytes | number | 0 | Max RSS in bytes (0 = disabled) | | message | string | 'Service Unavailable' | Error message | | retryAfter | number | 10 | Retry-After header in seconds | | customError | Error | — | Custom error class | | healthCheck | function | — | Async health check function | | healthCheckInterval | number | -1 | Health check interval in ms | | pressureHandler | function | — | Custom pressure handler | | sampleInterval | number | 1000 | Metric sample interval in ms | | exposeStatusRoute | boolean|string|object | false | Enable status endpoint | ``` -------------------------------- ### Health Check Function Error Response Example (500) Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/endpoints.md An example of a 500 Internal Server Error response when the health check function itself encounters an error, such as a database timeout. ```json HTTP/1.1 500 Internal Server Error Content-Type: application/json { "message": "Database connection timeout", "statusCode": 500 } ``` -------------------------------- ### Success Response Example with Custom Data Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/endpoints.md An example of a successful health check response including custom data returned by a healthCheck function, such as timestamp, region, version, and metrics. ```json HTTP/1.1 200 OK Content-Type: application/json { "status": "ok", "timestamp": "2024-01-15T10:30:45.123Z", "region": "us-west-2", "version": "2.1.0", "metrics": { "eventLoopDelay": 12.5, "heapUsed": 45000000, "rssBytes": 120000000, "eventLoopUtilized": 0.45 } } ``` -------------------------------- ### TypeScript Configuration and Usage Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/README.md Demonstrates how to use the Fastify Under Pressure plugin with TypeScript, including type definitions for options and the pressure handler. ```typescript import fastify from 'fastify' import underPressure from '@fastify/under-pressure' import type { FastifyUnderPressureOptions } from '@fastify/under-pressure' const app = fastify() const options: FastifyUnderPressureOptions = { maxHeapUsedBytes: 200000000, pressureHandler: (request, reply, type, value) => { // Types are inferred console.log(`Pressure: ${type} = ${value}`) } } app.register(underPressure, options) ``` -------------------------------- ### Example of Health Check Error Log Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/errors.md This shows the expected log output when the health check function fails and an error is logged by the plugin. ```javascript fastify.register(underPressure, { healthCheck: async () => { throw new Error('Database timeout') }, healthCheckInterval: 5000 }) // In logs after 5 seconds: // level: 5 (error) // msg: "external healthCheck function supplied to `under-pressure` threw an error. setting the service status to unhealthy." // error: Error: Database timeout ``` -------------------------------- ### Health Check Returning False Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/errors.md Example of a health check function that returns false, causing the plugin to return a 503 error with FST_UNDER_PRESSURE. ```javascript healthCheck: async (fastify) => false ``` -------------------------------- ### Plugin Structure Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/module-overview.md Illustrates the main components of the @fastify/under-pressure plugin, including its registration, decorations, hooks, and optional status route. ```javascript index.js (main plugin file) ├── Plugin registration: fastifyUnderPressure() ├── Decorations: fastify.memoryUsage(), fastify.isUnderPressure() ├── Hooks: onRequest (pressure checking), onClose (cleanup) └── Route: GET /status (optional health check endpoint) ``` -------------------------------- ### Get Metrics History Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/measurements.md Retrieves a history of collected memory usage and event loop metrics. The history is limited to the last 1000 samples. ```APIDOC ## GET /metrics/history ### Description Retrieves a history of collected memory usage and event loop metrics. The history is limited to the last 1000 samples. ### Method GET ### Endpoint /metrics/history ### Response #### Success Response (200) - **metricsHistory** (array) - An array of metric objects, each containing a timestamp and memory/event loop data. ### Response Example [ { "timestamp": 1678886400000, "heapUsed": 123456789, "rssBytes": 987654321, "eventLoopDelay": 10.5, "eventLoopUtilized": 0.999 } ] ``` -------------------------------- ### Configure Graceful Degradation with Custom Handler Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/README.md Demonstrates registering the plugin with memory limits and a custom `pressureHandler` to serve cached responses when heap usage exceeds the threshold. ```javascript fastify.register(underPressure, { maxHeapUsedBytes: 200000000, pressureHandler: (req, rep, type, value) => { if (type === underPressure.TYPE_HEAP_USED_BYTES) { // Serve cached response instead of computing rep.send(cache.get(req.url)) } } }) ``` -------------------------------- ### Get Resident Set Size (RSS) Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/measurements.md Retrieves the total physical memory allocated to the Node.js process in bytes using process.memoryUsage().rss. ```javascript const mem = process.memoryUsage() rssBytes = mem.rss ``` -------------------------------- ### Accessing Services via Fastify Instance Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/healthCheck.md Demonstrates how to access registered services (like database or Redis) within the healthCheck function using the provided Fastify instance. ```APIDOC ## Accessing Services The `fastify` parameter gives access to all registered plugins and services: ```javascript fastify.register(require('@fastify/postgresql'), { connectionString: process.env.DATABASE_URL }) fastify.register(require('@fastify/redis')) fastify.register(underPressure, { healthCheck: async (fastify) => { // Access registered services const dbConnected = await fastify.pg.query('SELECT 1') const redisConnected = await fastify.redis.ping() return { database: !!dbConnected, cache: redisConnected === 'PONG' } }, healthCheckInterval: 5000 }) ``` ``` -------------------------------- ### Importing Fastify Under Pressure Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/types.md Shows how to import and register the Fastify Under Pressure plugin using CommonJS and ES Modules. ```typescript // CommonJS const underPressure = require('@fastify/under-pressure') fastify.register(underPressure, options) // ES Modules (with proper setup) import underPressure from '@fastify/under-pressure' fastify.register(underPressure, options) ``` -------------------------------- ### Get Heap Used Memory Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/measurements.md Retrieves the currently allocated JavaScript heap memory in bytes using Node.js's process.memoryUsage() API. ```javascript const mem = process.memoryUsage() heapUsed = mem.heapUsed ``` -------------------------------- ### Invalid Health Check Configurations Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/quick-reference.md Examples of invalid configurations for the healthCheck option in the underPressure plugin. These demonstrate incorrect types or missing required properties. ```javascript // ❌ Must be a function fastify.register(underPressure, { healthCheck: true }) // ❌ Must have interval or status route fastify.register(underPressure, { healthCheck: async () => true }) ``` -------------------------------- ### FastifyInstance Extensions Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/types.md When the @fastify/under-pressure plugin is registered, it extends the FastifyInstance interface with methods to retrieve memory usage statistics and check the pressure status. ```APIDOC ## FastifyInstance Extensions ### Description When the plugin is registered, it extends the FastifyInstance interface with two new methods: `memoryUsage()` and `isUnderPressure()`. ### Methods #### memoryUsage() Retrieves detailed memory usage statistics. ##### Return Type ```json { "heapUsed": number, "rssBytes": number, "eventLoopDelay": number, "eventLoopUtilized": number } ``` ##### Properties - **heapUsed** (number) - JavaScript heap memory in bytes. From `process.memoryUsage().heapUsed`. - **rssBytes** (number) - Resident set size in bytes. From `process.memoryUsage().rss`. - **eventLoopDelay** (number) - Mean event loop delay in milliseconds. May be Infinity if calculation error occurs. - **eventLoopUtilized** (number) - Event loop utilization ratio (0-1). Returns 0 on unsupported Node versions. #### isUnderPressure() Checks if the service is currently under pressure. ##### Return Type ```typescript boolean ``` Returns `true` if any configured threshold is exceeded or health check fails, `false` otherwise. ``` -------------------------------- ### Encapsulated Plugin Registration with Different Configurations Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/module-overview.md Demonstrates registering the under-pressure plugin multiple times within different encapsulated scopes of a Fastify application, each with its own configuration. ```javascript fastify.register(underPressure, { maxHeapUsedBytes: 100000000 }) fastify.register(async (fastify) => { // Nested scope with different config fastify.register(underPressure, { maxHeapUsedBytes: 50000000 }) }) Each scope gets its own metrics collection and hooks. ``` -------------------------------- ### Adding Authentication to Status Route Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/endpoints.md To add authentication or other hooks to the status route, use routeOpts.config. This example configures a rate limit for the status endpoint. ```javascript fastify.register(underPressure, { exposeStatusRoute: { routeOpts: { config: { rateLimit: { max: 100, timeWindow: '15 minutes' } } } } }) ``` -------------------------------- ### Basic Plugin Registration Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/plugin.md Register the under-pressure plugin with basic threshold configurations for event loop delay and memory usage. ```javascript const fastify = require('fastify')() const underPressure = require('@fastify/under-pressure') fastify.register(underPressure, { maxEventLoopDelay: 1000, maxHeapUsedBytes: 100000000, maxRssBytes: 100000000 }) fastify.get('/', (request, reply) => { reply.send({ hello: 'world' }) }) fastify.listen({ port: 3000 }) ``` -------------------------------- ### Register Under Pressure Plugin with Kubernetes Liveness Probe Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/README.md Integrate with Kubernetes by exposing a liveness probe endpoint at /live. Customize the health check logic to include a database ping and set the health check interval. ```javascript fastify.register(underPressure, { exposeStatusRoute: '/live', healthCheck: async (fastify) => { return await database.ping() }, healthCheckInterval: 10000 }) // kubectl uses /live for readiness probe ``` -------------------------------- ### Health Check Returning Truthy Object Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/errors.md Example of a health check function that returns a truthy object, which will be merged into the response and return a 200 status code. ```javascript healthCheck: async (fastify) => ({ status: 'ok', db: 'connected' }) ``` -------------------------------- ### Health Check Throwing an Error Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/errors.md Example of a health check function that throws an error, resulting in a 500 error with the error details logged at the error level. ```javascript healthCheck: async (fastify) => { throw new Error('Database disconnected') } ``` -------------------------------- ### Use Case: Monitor with Load Balancer Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/quick-reference.md Configure under-pressure with a health check endpoint and expose the status route, suitable for integration with load balancers. ```javascript fastify.register(underPressure, { exposeStatusRoute: '/healthz', maxHeapUsedBytes: 200000000, healthCheck: async (fastify) => { return await database.ping() }, healthCheckInterval: 5000 }) ``` -------------------------------- ### Pressure Type Constants and Custom Handler Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/errors.md Demonstrates registering the under-pressure plugin with custom options and a pressure handler that logs specific error types and returns custom messages. ```javascript const fastify = require('fastify')() const underPressure = require('@fastify/under-pressure') fastify.register(underPressure, { maxEventLoopDelay: 1000, maxHeapUsedBytes: 100000000, pressureHandler: (req, rep, type, value) => { switch (type) { case underPressure.TYPE_EVENT_LOOP_DELAY: req.log.error(`Event loop delay: ${value}ms`) return 'Event loop overloaded' case underPressure.TYPE_HEAP_USED_BYTES: req.log.error(`Heap usage: ${(value / 1024 / 1024).toFixed(2)}MB`) return 'Memory limit reached' case underPressure.TYPE_RSS_BYTES: req.log.error(`RSS memory: ${(value / 1024 / 1024).toFixed(2)}MB`) return 'Process memory limit reached' case underPressure.TYPE_HEALTH_CHECK: req.log.error('Health check failed') return 'External service unavailable' case underPressure.TYPE_EVENT_LOOP_UTILIZATION: req.log.error(`Event loop utilization: ${(value * 100).toFixed(1)}%`) return 'CPU overloaded' } } }) ``` -------------------------------- ### Get Current Memory Usage Source: https://github.com/fastify/under-pressure/blob/main/README.md Access the current memory usage metrics exposed by the plugin. This function returns an object with heapUsed, rssBytes, eventLoopDelay, and eventLoopUtilized. ```javascript console.log(fastify.memoryUsage()) ``` -------------------------------- ### Background Health Check Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/healthCheck.md Background health checks run asynchronously and do not block incoming requests. If a background check is slow, it delays the start of the next check. ```javascript const beginCheck = async () => { await doCheck() // Runs in background externalHealthCheckTimer.refresh() } ``` ```javascript healthCheck: async (fastify) => { // If this takes 30 seconds and healthCheckInterval is 10 seconds, // the next check won't start until 30 seconds later return await slowOperation() } ``` -------------------------------- ### Use Case: Serve Cache When Busy Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/quick-reference.md Configure a `pressureHandler` to serve cached responses when the server is under pressure, reducing load on backend services. ```javascript fastify.register(underPressure, { maxHeapUsedBytes: 150000000, pressureHandler: (req, rep) => { const cached = cache.get(req.url) if (cached) rep.send(cached) } }) ``` -------------------------------- ### Encapsulation Configuration Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/quick-reference.md Configure the underPressure plugin globally and with different settings in a nested scope. This demonstrates how to apply specific configurations to different parts of the application. ```javascript // Global plugin configuration fastify.register(underPressure, { maxHeapUsedBytes: 200000000 }) // Nested scope with different config fastify.register(async (fastify) => { fastify.register(underPressure, { maxHeapUsedBytes: 100000000 // Lower limit for this scope }) }) ``` -------------------------------- ### Pressure Handler: Continue Normally (Return Null) Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/errors.md This JavaScript example demonstrates a 'pressureHandler' that explicitly returns null. This also results in the request continuing to be processed normally. ```javascript pressureHandler: (req, rep, type, value) => { return null // Continue normally } ``` -------------------------------- ### Status Route Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/endpoints.md The status route is an optional GET endpoint that returns the health status of the server. It is only exposed when the `exposeStatusRoute` option is enabled. The default path is `/status`, but it can be customized. ```APIDOC ## GET /status ### Description Provides the health status of the Fastify server. This endpoint is optional and only available if `exposeStatusRoute` is configured. ### Method GET ### Endpoint /status (default), or a custom path defined by `exposeStatusRoute.url`. ### Parameters No query parameters or request body are required for this endpoint. ### Request Example ```http GET /status HTTP/1.1 Host: example.com ``` ### Response #### Success Response (200 OK) Returned when the server is healthy. It includes a `status: 'ok'` field and optionally merges properties from a provided `healthCheck` function. - **status** (string) - Indicates the server is healthy. - **[additionalProperties]** (any) - Optional properties returned by the `healthCheck` function. ```json { "status": "ok", "timestamp": "2024-01-15T10:30:45.123Z", "version": "2.1.0" } ``` #### Service Unavailable Response (503) Returned when a health check fails or any pressure threshold is exceeded. - **code** (string) - Error code, typically 'FST_UNDER_PRESSURE'. - **error** (string) - Error description, typically 'Service Unavailable'. - **message** (string) - Detailed error message. - **statusCode** (number) - HTTP status code, always 503. **Headers:** - **Retry-After** (string) - The value of the `retryAfter` option (default: 10 seconds), indicating when to retry. ```json { "code": "FST_UNDER_PRESSURE", "error": "Service Unavailable", "message": "Service Unavailable", "statusCode": 503 } ``` #### Error Response (500) Returned if the health check function throws an error during execution. - **message** (string) - Error message indicating an internal server error. - **statusCode** (number) - HTTP status code, always 500. ```json { "message": "Database connection timeout", "statusCode": 500 } ``` ``` -------------------------------- ### FastifyUnderPressureOptions Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/types.md The main options interface for configuring the @fastify/under-pressure plugin. It allows setting various thresholds for event loop delay, memory usage, and custom handlers. ```APIDOC ## FastifyUnderPressureOptions ### Description The main options interface for plugin configuration. ### Fields - **maxEventLoopDelay** (number, optional) - Maximum event loop delay in ms. Defaults to 0 (disabled). - **maxEventLoopUtilization** (number, optional) - Maximum event loop utilization (0-1). Defaults to 0 (disabled). - **maxHeapUsedBytes** (number, optional) - Maximum heap memory in bytes. Defaults to 0 (disabled). - **maxRssBytes** (number, optional) - Maximum RSS memory in bytes. Defaults to 0 (disabled). - **message** (string, optional) - Custom error message. Defaults to 'Service Unavailable'. - **retryAfter** (number, optional) - Retry-After header value in seconds. Defaults to 10. - **healthCheck** (function, optional) - Async function returning true/false or data object. No default. - **healthCheckInterval** (number, optional) - Milliseconds between health check invocations. Defaults to -1 (disabled). - **pressureHandler** (function, optional) - Custom handler for pressure events. No default. - **sampleInterval** (number, optional) - Milliseconds between metric updates. Defaults to 1000. - **exposeStatusRoute** (boolean | string | object, optional) - Enable and configure status endpoint. Defaults to false. - **customError** (Error class, optional) - Custom error to throw. Defaults to internal FST_UNDER_PRESSURE error. ``` -------------------------------- ### Configuring CORS for Status Route Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/endpoints.md The status route respects Fastify's global routeOpts configuration, including CORS settings. This example configures CORS to allow all origins. ```javascript fastify.register(underPressure, { exposeStatusRoute: { url: '/health', routeOpts: { cors: { origin: '*', credentials: false } } } }) ``` -------------------------------- ### Graceful Degradation with Essential and Optional Services Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/healthCheck.md Prioritizes essential services for a quick check and then checks optional services only if the essential ones are healthy. This pattern ensures fast responses for critical failures. ```javascript healthCheck: async (fastify) => { const essential = await checkEssential() // Must be fast if (!essential) { return false // Fast fail } // Only check optional services if essential is healthy const optional = await checkOptional() // Can be slower return { essential: true, optional, timestamp: new Date().toISOString() } } ``` -------------------------------- ### Register @fastify/under-pressure Plugin Source: https://github.com/fastify/under-pressure/blob/main/README.md Register the plugin with Fastify and configure load thresholds. The plugin automatically handles 'Service Unavailable' errors when thresholds are met. ```javascript const fastify = require('fastify')() fastify.register(require('@fastify/under-pressure'), { maxEventLoopDelay: 1000, maxHeapUsedBytes: 100000000, maxRssBytes: 100000000, maxEventLoopUtilization:0.98 }) fastify.get('/', (request, reply) => { if (fastify.isUnderPressure()) { // skip complex computation } reply.send({ hello: 'world'}) }) fastify.listen({ port: 3000 }, err => { if (err) throw err console.log(`server listening on ${fastify.server.address().port}`) }) ``` -------------------------------- ### Registering Under Pressure and Checking Status Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/isUnderPressure.md This snippet demonstrates how to register the underPressure plugin with custom pressure handling and how to use the isUnderPressure() method within a route to check the system's pressure status. ```javascript fastify.register(underPressure, { maxHeapUsedBytes: 100000000, pressureHandler: (request, reply, type, value) => { // This is called when pressure is detected reply.send('Service overloaded') } }) fastify.get('/check', (request, reply) => { // Check manually without being rejected if (fastify.isUnderPressure()) { reply.send({ warning: 'Service nearing capacity' }) } else { reply.send({ status: 'ok' }) } }) ``` -------------------------------- ### Monitoring and Logging Memory Usage Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/memoryUsage.md Configure `@fastify/under-pressure` with limits for event loop delay and heap usage. This snippet demonstrates logging high event loop delay periodically using `setInterval` and `fastify.memoryUsage()`. ```javascript fastify.register(underPressure, { maxEventLoopDelay: 500, maxHeapUsedBytes: 100000000 }) // Log metrics periodically setInterval(() => { const usage = fastify.memoryUsage() if (usage.eventLoopDelay > 100) { fastify.log.warn('High event loop delay detected', { usage }) } }, 10000) ``` -------------------------------- ### Pressure Handler: Asynchronous Operation Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/errors.md This JavaScript example shows an asynchronous 'pressureHandler' that performs an operation (e.g., notifying operations) using a Promise. The request processing waits for the promise to settle before continuing. ```javascript pressureHandler: async (req, rep, type, value) => { await notifyOps(type, value) // No reply.send() → request continues after promise settles } ``` -------------------------------- ### Accessing Services in Health Check Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/healthCheck.md Demonstrates how to access Fastify plugins and services (like database or Redis) within the `healthCheck` function. Ensure the services are correctly registered before `underPressure`. ```javascript fastify.register(require('@fastify/postgresql'), { connectionString: process.env.DATABASE_URL }) fastify.register(require('@fastify/redis')) fastify.register(underPressure, { healthCheck: async (fastify) => { // Access registered services const dbConnected = await fastify.pg.query('SELECT 1') const redisConnected = await fastify.redis.ping() return { database: !!dbConnected, cache: redisConnected === 'PONG' } }, healthCheckInterval: 5000 }) ``` -------------------------------- ### Expose Prometheus Metrics Endpoint Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/README.md Integrate with Prometheus by exposing a /metrics endpoint that reports heap usage. This snippet shows how to define a GET route to fetch and send memory usage data. ```javascript fastify.get('/metrics', (req, rep) => { const usage = fastify.memoryUsage() rep.send(`heap_used_bytes ${usage.heapUsed}\nrss_bytes ${usage.rssBytes}`) }) ``` -------------------------------- ### Get Metrics Source: https://github.com/fastify/under-pressure/blob/main/_autodocs/api-reference/measurements.md Retrieves the current memory usage and event loop metrics. The response is formatted in megabytes for heap and RSS, milliseconds for event loop delay, and as a percentage for event loop utilization. ```APIDOC ## GET /metrics ### Description Retrieves the current memory usage and event loop metrics. The response is formatted in megabytes for heap and RSS, milliseconds for event loop delay, and as a percentage for event loop utilization. ### Method GET ### Endpoint /metrics ### Response #### Success Response (200) - **heapUsedMB** (string) - Heap used in megabytes, formatted to two decimal places. - **rssMB** (string) - Resident Set Size in megabytes, formatted to two decimal places. - **eventLoopDelayMs** (string) - Event loop delay in milliseconds, formatted to two decimal places. - **eventLoopUtilization** (string) - Event loop utilization as a percentage, formatted to one decimal place. ### Response Example { "heapUsedMB": "123.45", "rssMB": "678.90", "eventLoopDelayMs": "10.12", "eventLoopUtilization": "99.9%" } ```