Project: APISIX (Orchestration & Management / API Gateway)
File: limit-conn.md

title: limit-conn keywords: Apache APISIX API Gateway Limit Connection description: This document contains information about the Apache APISIX limit-con Plugin, you can use it to limits the number of concurrent requests to your services. <!-- --> The `limit-conn` Plugin limits the number of concurrent requests to your services. | Name | Type | Required | Default | Valid values | Description | |--|| -- |-|--|--| | conn | integer | True | | conn > 0 | Maximum number of concurrent requests allowed. Requests exceeding this ratio (and below `conn` + `burst`) will be delayed (configured by `defaultconndelay`). | | burst | integer | True | | burst >= 0 | Number of additional concurrent requests allowed to be delayed per second. If the number exceeds this hard limit, they will get rejected immediately. | | defaultconndelay | number | True | | defaultconndelay > 0 | Delay in seconds to process the concurrent requests exceeding `conn` (and `conn` + `burst`). | | onlyusedefaultdelay | boolean | False | false | [true,false] | When set to `true`, the Plugin will always set a delay of `defaultconn_delay` and would not use any other calculations. | | keytype | string | False | "var" | ["var", "varcombination"] | Type of user specified key to use. | | key | string | True | | | User specified key to base the request limiting on. If the `keytype` attribute is set to `"var"`, the key will be treated as a name of variable, like `remoteaddr` or `consumername`. If the `keytype` is set to `"varcombination"`, the key will be a combination of variables, like `$remoteaddr $consumername`. If the value of the key is empty, `remoteaddr` will be set as the default key. | | rejected_code | string | False | 503 | [200,...,599] | HTTP status code returned when the requests exceeding the threshold are rejected. | | rejected_msg | string | False | | non-empty | Body of the response returned when the requests exceeding the threshold are rejected. | | allow_degradation | boolean | False | false | | When set to `true` enables Plugin degradation when the Plugin is temporarily unavailable and allows requests to continue. | | policy | string | False | "local" | ["local", "redis", "redis-cluster"] | Rate-limiting policies to use for retrieving and increment the limit count. When set to `local` the counters will be locally stored in memory on the node. When set to `redis` counters are stored on a Redis server and will be shared across the

It is done usually for global speed limiting, and setting to `redis-cluster` uses a Redis cluster instead of a single instance. | | redis_host | string | required when `policy` is `redis` | | | Address of the Redis server. Used when the `policy` attribute is set to `redis`. | | redis_port | integer | False | 6379 | [1,...] | Port of the Redis server. Used when the `policy` attribute is set to `redis`. | | redisusername | string | False | | | Username for Redis authentication if Redis ACL is used (for Redis version >= 6.0). If you use the legacy authentication method `requirepass` to configure Redis password, configure only the `redispassword`. Used when the `policy` is set to `redis`. | | redis_password | string | False | | | Password for Redis authentication. Used when the `policy` is set to `redis` or `redis-cluster`. | | redis_ssl | boolean | False | false | | If set to `true`, then uses SSL to connect to redis instance. Used when the `policy` attribute is set to `redis`. | | redissslverify | boolean | False | false | | If set to `true`, then verifies the validity of the server SSL certificate. Used when the `policy` attribute is set to `redis`. See . | | redisdatabase | integer | False | 0 | redisdatabase >= 0 | Selected database of the Redis server (for single instance operation or when using Redis cloud with a single entrypoint). Used when the `policy` attribute is set to `redis`. | | redis_timeout | integer | False | 1000 | [1,...] | Timeout in milliseconds for any command submitted to the Redis server. Used when the `policy` attribute is set to `redis` or `redis-cluster`. | | redisclusternodes | array | required when `policy` is `redis-cluster` | | | Addresses of Redis cluster nodes. Used when the `policy` attribute is set to `redis-cluster`. | | redisclustername | string | required when `policy` is `redis-cluster` | | | Name of the Redis cluster service nodes. Used when the `policy` attribute is set to `redis-cluster`. | | redisclusterssl | boolean | False | false | | If set to `true`, then uses SSL to connect to redis-cluster. Used when the `policy` attribute is set to `redis-cluster`. | | redisclusterssl_verify | boolean | False | false | | If set to `true`, then verifies the validity of the server SSL certificate. Used when the `policy` attribute is set to `redis-cluster`. | You can enable the Plugin on a Route as shown below: :::note You can fetch the `admin_key` from

and save to an environment variable with the following command: ```bash adminkey=$(yq '.deployment.admin.adminkey[0].key' conf/config.yaml | sed 's/"//g') ``` ::: ```shell curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H "X-API-KEY: $admin_key" -X PUT -d ' { "methods": ["GET"], "uri": "/index.html", "plugins": { "limit-conn": { "conn": 1, "burst": 0, "defaultconndelay": 0.1, "rejected_code": 503, "key_type": "var", "key": "http_a" } }, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:1980": 1 } } }' ``` You can also configure the `keytype` to `varcombination` as shown: ```shell curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H "X-API-KEY: $admin_key" -X PUT -d ' { "methods": ["GET"], "uri": "/index.html", "plugins": { "limit-conn": { "conn": 1, "burst": 0, "defaultconndelay": 0.1, "rejected_code": 503, "keytype": "varcombination", "key": "$consumername $remoteaddr" } }, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:1980": 1 } } }' ``` The example above configures the Plugin to only allow one connection on this route. When more than one request is received, the Plugin will respond with a `503` HTTP status code and reject the connection: ```shell curl -i http://127.0.0.1:9080/index.html?sleep=20 & curl -i http://127.0.0.1:9080/index.html?sleep=20 ``` ```shell <html> <head><title>503 Service Temporarily Unavailable</title></head> <body> <center><h1>503 Service Temporarily Unavailable</h1></center> <hr><center>openresty</center> </body> </html> ``` To remove the `limit-conn` Plugin, you can delete the corresponding JSON configuration from the Plugin configuration. APISIX will automatically reload and you do not have to restart for this to take effect. ```shell curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H "X-API-KEY: $admin_key" -X PUT -d ' { "methods": ["GET"], "uri": "/index.html", "id": 1, "plugins": { }, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:1980": 1 } } }' ``` Apache APISIX supports WebSocket proxy, we can use `limit-conn` plugin to limit the number of concurrent WebSocket connections. Create a Route, enable the WebSocket proxy and the `limit-conn` plugin. ```shell curl http://127.0.0.1:9180/apisix/admin/routes/1 \ -H "X-API-KEY: $admin_key" -X PUT -d ' { "uri": "/ws", "enable_websocket": true, "plugins": { "limit-conn": { "conn": 1, "burst": 0, "defaultconndelay": 0.1, "rejected_code": 503, "key_type": "var", "key": "remote_addr" } }, "upstream": { "type": "roundrobin", "nodes": { "127.0.0.1:1980": 1 } } }' ``` The above route enables the WebSocket proxy on `/ws`, and limits the number of concurrent WebSocket connections to 1. More than 1 concurrent WebSocket connection will return `503` to reject the request. Initiate a WebSocket request, and the connection is established successfully. ```shell curl --include \ --no-buffer \ --header "Connection: Upgrade" \ --header "Upgrade: websocket" \ --header "Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==" \ --header "Sec-WebSocket-Version: 13" \ --http1.1 \ http://127.0.0.1:9080/ws ``` ```shell HTTP/1.1 101 Switching Protocols ``` Initiate the WebSocket request again in another terminal, the request will be rejected. ```shell HTTP/1.1 503 Service Temporarily Unavailable <html> <head><title>503 Service Temporarily Unavailable</title></head> <body> <center><h1>503 Service Temporarily Unavailable</h1></center> <hr><center>openresty</center> </body> </html> ```