RateLimit.json
(This function can be tried with the "Pleasanter Extensions Trial".)
Cautions¶
When changing parameters, please refer to "Confirmation When Changing Parameters".
"RateLimit.json" is loaded when Pleasanter starts. If you change the setting values, they are applied after Pleasanter is restarted.
Setting Values¶
The setting values of this parameter file are as follows.
| Parameter name | e.g. | Description |
|---|---|---|
| Mode | "Off" | Specify the operation mode of the whole rate limit function. The setting method is described below. |
| ApplyPaths | [ "/" ] | Specify the paths (prefixes) to which the rate limit is applied. The default value is all paths ("/"). |
| ExcludePaths | [ "/mcp", "/healthz", … ] | Specify the paths to be excluded from the rate limit (applied to both "GlobalLimiter" and the policies by function category). For details, see "About ExcludePaths" below. |
| KeyResolver | The setting method is described below | Specify the resolution order of the partition key used in policies whose Partition is "Auto". |
| Exclusions | The setting method is described below | Specify the users to be excluded from the rate limit. |
| GlobalLimiter | The setting method is described below | The upper-level policy common to all requests (the last line of defense). |
| Policies | The setting method is described below | The policies by function category (General / List / Admin and so on). |
| RejectedResponse | The setting method is described below | The settings for the response when the limit is exceeded. |
Setting Mode¶
The top-level "Mode" switches the operation of the whole rate limit function.
| Setting value | Description |
|---|---|
| Off | (Default) Disables the rate limit function. Because the middleware is not registered, there is no effect on performance. |
| LogOnly | Observes that the limit is exceeded and records it in the log (virtual rejection log), but does not block the request (does not return 429). Use it for observation when adjusting thresholds. |
| On | Returns "429 Too Many Requests" and blocks the request when the limit is exceeded. |
By specifying "Mode" for each policy (under GlobalLimiter / Policies) individually, you can override the operation for each policy (described below).
Setting Exclusions¶
| Parameter name | e.g. | Description |
|---|---|---|
| LoginIds | [ "batch", "monitor" ] | Specify the login IDs of the users to be excluded from the rate limit. Specify users that you do not want to limit, such as accounts for batch processing or monitoring tools. They are matched by login ID (string), and case is not distinguished. |
Setting KeyResolver¶
| Parameter name | e.g. | Description |
|---|---|---|
| Order | [ "User", "Ip" ] | Specify the order in which the partition key is resolved in policies whose Partition is "Auto". They are evaluated in order from the beginning, and the first unit that can be resolved (the logged-in user or the IP) is used. |
Common Setting Items of GlobalLimiter / Policies¶
"GlobalLimiter" and each policy under "Policies" are commonly composed of the following items.
| Parameter name | e.g. | Description |
|---|---|---|
| Mode | "Inherit" | Specify the operation mode of the individual policy. "Inherit" (default) inherits the top-level "Mode". If you specify "Off" / "LogOnly" / "On", you can override only that policy individually. |
| Algorithm | "TokenBucket" | Specify the limiting algorithm. For the setting method, see "Algorithm (Limiting Algorithm)" below. |
| Partition | "User" | Specify the unit of the limit. For the setting method, see "Partition (Unit of the Limit)" below. |
| QueueLimit | 0 | Specify the number of requests to be queued when the limit is reached. The default value is 0 (rejected immediately without queuing). |
| (Items specific to the algorithm) | — | The items to specify differ for each algorithm. See "Algorithm (Limiting Algorithm)" below. |
Partition (Unit of the Limit)¶
| Setting value | Description |
|---|---|
| User | Limits per logged-in user (login ID). Unauthenticated requests are not covered. |
| Ip | Limits per source IP address. |
| ApiKey | Limits per API key. |
| Auto | Resolves the unit according to "Order" of "KeyResolver" (by default, in the order User → Ip). |
The limit is counted independently for each partition (unit). For example, in a policy in units of "User", a separate limit is applied to each user.
Algorithm (Limiting Algorithm)¶
A limiting algorithm is a rule for limiting the number of operations that can be performed within a certain time in the rate limit. Because the method of judging access and the characteristics of the limit differ for each algorithm, you can select the appropriate method according to the usage scene.
(1) FixedWindow¶
A method that resets the counter for each fixed time (window) and limits the number of operations within that frame. If operations concentrate near the boundary of a window, it may allow throughput close to twice the rate limit in some cases.
| Parameter name | e.g. | Description |
|---|---|---|
| PermitLimit | 30 | Sets the number of permitted requests within the window. |
| WindowSeconds | 60 | Sets the length of the window (in seconds). |
(2) SlidingWindow¶
A method that limits the number of operations targeting only the most recent fixed period (window). This function adopts a counter approximation method, which divides the window into multiple segments and limits the number of operations by segment. In general, it is said that bursts at window boundaries are less likely to occur than with FixedWindow.
If you increase SegmentsPerWindow, the time resolution becomes finer and the memory consumption and update frequency increase. Conversely, if you decrease SegmentsPerWindow, it approaches the FixedWindow method.
| Parameter name | e.g. | Description |
|---|---|---|
| PermitLimit | 30 | Sets the number of permitted requests within the window. |
| WindowSeconds | 60 | Sets the length of the window (in seconds). |
| SegmentsPerWindow | 5 | Sets the number of segments into which the window is divided. |
(3) TokenBucket¶
A method that limits the number of operations by consuming tokens in a bucket. As long as tokens exist in the bucket, processing is permitted immediately, and when they are exhausted, it is rejected. The tokens in the bucket are replenished at regular intervals. It is suitable when you want to set a limit per unit time while also handling a momentary increase in throughput.
| Parameter name | e.g. | Description |
|---|---|---|
| TokenLimit | 10 | Sets the maximum number of tokens in the bucket. |
| TokensPerPeriod | 5 | Sets the number of tokens added per replenishment period. |
| ReplenishmentPeriodSeconds | 1 | Sets the token replenishment interval (in seconds). |
(4) Concurrency¶
A method close to load control. It limits the number of concurrent executions rather than the number of times per unit time. The count is increased when concurrent execution starts and decreased when it is completed.
| Parameter name | e.g. | Description |
|---|---|---|
| PermitLimit | 3 | Sets the maximum number of concurrent requests. |
Policies (Policies by Function Category)¶
The following default policies exist under "Policies". Each policy is composed of the "common setting items" and the "Algorithm (Limiting Algorithm)" described above. The default values and the target of each policy are as shown in the table below. For the role of each policy and the way of thinking about threshold adjustment, see the function manual "Rate Limit Function: Adjusting Policies and Thresholds".
| Policy name | Unit | Algorithm | Default limit | Main target |
|---|---|---|---|---|
| General | User | TokenBucket | Capacity 10 / +5 per second | General screen operations |
| List | User | SlidingWindow | 30 times in the last 60 seconds | Grid, search, grid and aggregation views |
| Admin | User | FixedWindow | 30 times every 60 seconds | Administrative operations (user / department / group management and so on) |
| Heavy | User | Concurrency | 1 concurrent | Heavy processing on the screen side (export, import and so on) |
| ApiHeavy | ApiKey | Concurrency | 1 concurrent | Heavy processing via API |
| Api | Auto | TokenBucket | Capacity 30 / +10 per second | REST API in general |
| AnonymousIp | Ip | FixedWindow | 60 times in 60 seconds | Unauthenticated access (login attempts and so on) |
| PublicForm | Ip | TokenBucket | Capacity 5 / +2 per second | Submission of public forms |
Setting RejectedResponse¶
| Parameter name | e.g. | Description |
|---|---|---|
| IncludeRetryAfter | true | Specify true to add the "Retry-After" header (the approximate number of seconds until a retry) to the response when the limit is exceeded. |
| LogRejected | true | When Mode is "On", specify whether to record the actually rejected requests in the structured log. Even if you set it to false, the counts (metrics) are always recorded. The virtual rejection log when Mode is "LogOnly" is always output regardless of this setting. |
About ExcludePaths¶
The paths specified in "ExcludePaths" are excluded from the target of both "GlobalLimiter" and the policies by function category (General / List / Admin and so on). The rate limit is not performed for requests to those paths.
By default, the following paths are specified.
"ExcludePaths": [
"/mcp",
"/healthz",
"/favicon.ico",
"/Css",
"/Scripts",
"/fonts",
"/images",
"/binaries",
"/backgroundtasks",
"/reminderschedules",
"/api/backgroundtasks",
"/cspreport",
"/errors",
"/resources"
]
Adjusting PublicForm (for an In-House NAT Environment and So On)¶
"PublicForm" limits per source IP address (Ip). In an environment where many users share the same IP address, such as an in-house NAT, the limit is easily reached. Consider expanding the thresholds according to the scale of sharing, using the following as a guide.
| Usage form | TokenLimit | TokensPerPeriod |
|---|---|---|
| Individual use (for customers and so on) | 5 | 2 |
| In-house NAT shared by about 50 to 100 employees | 20 | 10 |
| Large-scale in-house NAT (500 or more) | 50 | 25 |
Setting Example¶
The description examples of each policy are as follows. "GlobalLimiter" and each policy under "Policies" are described in the same format.
{
"Mode": "On",
"ApplyPaths": ["/"],
"ExcludePaths": [
"/mcp",
"/healthz",
"/favicon.ico",
"/Css",
"/Scripts",
"/fonts",
"/images",
"/binaries",
"/backgroundtasks",
"/reminderschedules",
"/api/backgroundtasks",
"/cspreport",
"/errors",
"/resources"
],
"KeyResolver": {
"Order": ["User", "Ip"]
},
"Exclusions": {
"LoginIds": []
},
"GlobalLimiter": {
"Mode": "Inherit",
"Algorithm": "TokenBucket",
"Partition": "Auto",
"TokenLimit": 100,
"TokensPerPeriod": 50,
"ReplenishmentPeriodSeconds": 1,
"QueueLimit": 0
},
"Policies": {
"General": {
"Mode": "Inherit",
"Algorithm": "TokenBucket",
"Partition": "User",
"TokenLimit": 10,
"TokensPerPeriod": 5,
"ReplenishmentPeriodSeconds": 1,
"QueueLimit": 0
},
"List": {
"Mode": "Inherit",
"Algorithm": "SlidingWindow",
"Partition": "User",
"PermitLimit": 30,
"WindowSeconds": 60,
"SegmentsPerWindow": 6,
"QueueLimit": 0
},
"Admin": {
"Mode": "Inherit",
"Algorithm": "FixedWindow",
"Partition": "User",
"PermitLimit": 30,
"WindowSeconds": 60,
"QueueLimit": 0
},
"Heavy": {
"Mode": "Inherit",
"Algorithm": "Concurrency",
"Partition": "User",
"PermitLimit": 1,
"QueueLimit": 0
},
"ApiHeavy": {
"Mode": "Inherit",
"Algorithm": "Concurrency",
"Partition": "ApiKey",
"PermitLimit": 1,
"QueueLimit": 0
},
"Api": {
"Mode": "Inherit",
"Algorithm": "TokenBucket",
"Partition": "Auto",
"TokenLimit": 30,
"TokensPerPeriod": 10,
"ReplenishmentPeriodSeconds": 1,
"QueueLimit": 0
},
"AnonymousIp": {
"Mode": "Inherit",
"Algorithm": "FixedWindow",
"Partition": "Ip",
"PermitLimit": 60,
"WindowSeconds": 60,
"QueueLimit": 0
},
"PublicForm": {
"Mode": "Inherit",
"Algorithm": "TokenBucket",
"Partition": "Ip",
"TokenLimit": 5,
"TokensPerPeriod": 2,
"ReplenishmentPeriodSeconds": 1,
"QueueLimit": 0
}
},
"RejectedResponse": {
"IncludeRetryAfter": true,
"LogRejected": true
}
}
Supported Versions¶
| Supported versions | Body |
|---|---|
| 1.5.6.0 and later | Added RateLimit.json |