Skip to content

Commit 2d984ed

Browse files
achingbrainBigLep
andauthored
docs: update limits doc (#1456)
Incorporate feedback from #1421 Co-authored-by: Steve Loeppky <biglep@protocol.ai>
1 parent 5a62f4f commit 2d984ed

File tree

1 file changed

+118
-59
lines changed

1 file changed

+118
-59
lines changed

doc/LIMITS.md

+118-59
Original file line numberDiff line numberDiff line change
@@ -2,100 +2,133 @@
22

33
In order to prevent excessive resource consumption by a libp2p node it's important to understand limits are applied and how to tune them to the needs of your application.
44

5+
This is important for [DoS](https://en.wikipedia.org/wiki/Denial-of-service_attack) attack mitgation - there is a more holistic discussion and general advice on that topic at [the main libp2p docs website](https://docs.libp2p.io/reference/dos-mitigation/).
6+
57
## Table of contents <!-- omit in toc -->
68

79
- [Connection limits](#connection-limits)
10+
- [Closing connections](#closing-connections)
811
- [Inbound connection threshold](#inbound-connection-threshold)
912
- [Data transfer and Event Loop limits](#data-transfer-and-event-loop-limits)
1013
- [Stream limits](#stream-limits)
1114
- [Mplex](#mplex)
1215
- [Yamux](#yamux)
1316
- [Protocol limits](#protocol-limits)
14-
- [Closing connections](#closing-connections)
1517
- [Transport specific limits](#transport-specific-limits)
1618
- [TCP](#tcp)
1719
- [Allow/deny lists](#allowdeny-lists)
20+
- [How much memory will be used for buffering?](#how-much-memory-will-be-used-for-buffering)
1821

1922
## Connection limits
2023

21-
It's possible to limit the amount of incoming and outgoing connections a node is able to make. When this limit is reached and an attempt to open a new connection is made, existing connections may be closed to make room for the new connection.
24+
It's possible to limit the total amount of connections a node is able to make (combining incoming and outgoing). When this limit is reached and an attempt to open a new connection is made, existing connections may be closed to make room for the new connection (see [Closing connections][#closing-connections]).
25+
26+
* Note: there currently isn't a way to specify different limits for incoming vs. outgoing. Connection limits are applied across both incoming and outgoing connections combined. There is a backlog item for this [here](https://github.com/libp2p/js-libp2p/issues/1508).
2227

2328
We can also limit the number of connections in a "pending" state. These connections have been opened by a remote peer but peer IDs have yet to be exchanged and/or connection encryption and multiplexing negotiated. Once this limit is hit further connections will be closed unless the remote peer has an address in the [allow list](#allowdeny-lists).
2429

25-
```js
30+
All fields are optional. The default values are defined in [src/connection-manager/index.ts](https://github.com/libp2p/js-libp2p/blob/master/src/connection-manager/index.ts) - please see that file for the current values.
31+
32+
```ts
2633
const node = await createLibp2pNode({
2734
connectionManager: {
2835
/**
2936
* The total number of connections allowed to be open at one time
3037
*/
31-
maxConnections: 200,
38+
maxConnections: number
3239

3340
/**
3441
* If the number of open connections goes below this number, the node
35-
* will try to connect to nearby peers from the peer store
42+
* will try to connect to randomly selected peers from the peer store
3643
*/
37-
minConnections: 20,
44+
minConnections: number
3845

3946
/**
4047
* How many connections can be open but not yet upgraded
4148
*/
42-
maxIncomingPendingConnections: 10
49+
maxIncomingPendingConnections: number
4350
}
4451
})
4552
```
4653

54+
## Closing connections
55+
56+
When choosing connections to close the connection manager sorts the list of connections by the value derived from the tags given to each peer. The values of all tags are summed and connections with lower valued peers are eligible for closing first.
57+
58+
```js
59+
// tag a peer
60+
await libp2p.peerStore.tagPeer(peerId, 'my-tag', {
61+
value: 50, // 0-100 is the typical value range
62+
ttl: 1000 // optional field, this tag will be deleted after this many ms
63+
})
64+
```
65+
4766
## Inbound connection threshold
4867

49-
To prevent individual peers from opening multiple connections to a node, an `inboundConnectionThreshold` is configurable. This is the number of connections per second an individual remote host can open to a node, once this threshold is crossed all further connections opened by that host will be rejected.
68+
To prevent individual peers from opening multiple connections to a node, an `inboundConnectionThreshold` is configurable. This is the number of connections per second an individual peer can open to a node, once this threshold is crossed all further connections opened by that peer will be rejected until the threshold resets in the next second.
5069

70+
All fields are optional. The default values are defined in [src/connection-manager/index.ts](https://github.com/libp2p/js-libp2p/blob/master/src/connection-manager/index.ts) - please see that file for the current values.
5171

52-
```js
72+
```ts
5373
const node = await createLibp2pNode({
5474
connectionManager: {
5575
/**
5676
* A remote peer may attempt to open up to this many connections per second,
5777
* any more than that will be automatically rejected
5878
*/
59-
inboundConnectionThreshold: 5
79+
inboundConnectionThreshold: number
6080
}
6181
})
6282
```
6383

6484
## Data transfer and Event Loop limits
6585

66-
If metrics are enabled the node will track the amount of data being sent to and from the network. If the amount sent is over the threshold connections will be trimmed to free up resources. The default amount is `Ininity` so this must be explicitly enabled.
86+
If metrics are enabled the node will track the amount of data being sent to and from the network. If the rate of data sent is over the threshold connections will be trimmed to free up resources. The default rate is `Ininity` so this must be explicitly enabled.
6787

6888
Connections may also be trimmed if [event loop](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick) latency exceeds the configured limit.
6989

70-
```js
90+
All fields are optional. The default values are defined in [src/connection-manager/index.ts](https://github.com/libp2p/js-libp2p/blob/master/src/connection-manager/index.ts) - please see that file for the current values.
91+
92+
```ts
7193
const node = await createLibp2pNode({
7294
metrics: {
7395
enabled: true
7496
},
7597
connectionManager: {
7698
/**
7799
* If the node transfers more than this amount of data in bytes/second
78-
* low value connections may be closed
100+
* connections to untagged peers or those not in the allow list may be
101+
* closed.
102+
*
103+
* It is bytes per second.
79104
*/
80-
maxData: 1024 * 1024,
105+
maxData: number
81106

82107
/**
83108
* If the node sends more than this amount of data in bytes/second
84-
* low value connections may be closed
109+
* connections to untagged peers or those not in the allow list may be
110+
* closed.
111+
*
112+
* It is bytes per second.
85113
*/
86-
maxSentData: 1024 * 1024
114+
maxSentData: number
87115

88116
/**
89117
* If the node receives more than this amount of data in bytes/second
90-
* low value connections may be closed
118+
* connections to untagged peers or those not in the allow list may be
119+
* closed.
120+
*
121+
* It is bytes per second.
91122
*/
92-
maxReceivedData: 1024 * 1024,
123+
maxReceivedData: number
93124

94125
/**
95-
* If the event loop takes longer than this many ms to run, low value
96-
* connections may be closed
126+
* If the event loop takes longer than this many ms to run, connections
127+
* to untagged peers or those not in the allow list may be closed.
128+
*
129+
* It is milliseconds.
97130
*/
98-
maxEventLoopDelay: 1000
131+
maxEventLoopDelay: number
99132
}
100133
})
101134
```
@@ -108,85 +141,88 @@ These settings are done on a per-muxer basis, please see the README of the relev
108141

109142
### Mplex
110143

111-
[@libp2p/mplex](https://github.com/libp2p/js-libp2p-mplex) supports the following:
144+
[@libp2p/mplex](https://github.com/libp2p/js-libp2p-mplex) supports the following.
112145

113-
```js
146+
All fields are optional. The default values are defined in [@libp2p/mplex/src/mplex.ts](https://github.com/libp2p/js-libp2p-mplex/blob/master/src/mplex.ts) - please see that file for the current values.
147+
148+
```ts
114149
const node = await createLibp2pNode({
115150
muxers: [
116-
new Mplex({
151+
mplex({
117152
/**
118153
* The total number of inbound protocol streams that can be opened on a given connection
119154
*/
120-
maxInboundStreams: 1024,
155+
maxInboundStreams: number
121156

122157
/**
123158
* The total number of outbound protocol streams that can be opened on a given connection
124159
*/
125-
maxOutboundStreams: 1024,
160+
maxOutboundStreams: number
161+
162+
/**
163+
* How much incoming data in bytes to buffer while attempting to parse messages - peers sending many small messages in batches may cause this buffer to grow
164+
*/
165+
maxUnprocessedMessageQueueSize: number
126166

127167
/**
128-
* How much incoming data to buffer before resetting the stream
168+
* How much message data in bytes to buffer after parsing - slow stream consumers may cause this buffer to grow
129169
*/
130-
maxStreamBufferSize: 4 * 1024 * 1024,
170+
maxStreamBufferSize: number
131171

132172
/**
133173
* Mplex does not support backpressure so to protect ourselves, if `maxInboundStreams` is
134174
* hit and the remote opens more than this many streams per second, close the connection
135175
*/
136-
disconnectThreshold: 5
176+
disconnectThreshold: number
137177
})
138178
]
139179
})
140180
```
141181

142182
### Yamux
143183

144-
[@chainsafe/libp2p-yamux](https://github.com/Chainsafe/js-libp2p-yamux) supports the following:
184+
[@chainsafe/libp2p-yamux](https://github.com/Chainsafe/js-libp2p-yamux) supports the following.
145185

146-
```js
186+
All fields are optional. The default values are defined in [@chainsafe/libp2p-yamux/src/config.ts](https://github.com/ChainSafe/js-libp2p-yamux/blob/master/src/config.ts) - please see that file for the current values.
187+
188+
```ts
147189
const node = await createLibp2pNode({
148190
muxers: [
149-
new Yamux({
191+
yamux({
150192
/**
151193
* The total number of inbound protocol streams that can be opened on a given connection
194+
*
195+
* This field is optional, the default value is shown
152196
*/
153-
maxInboundStreams: 1024,
197+
maxInboundStreams: number
154198

155199
/**
156200
* The total number of outbound protocol streams that can be opened on a given connection
201+
*
202+
* This field is optional, the default value is shown
157203
*/
158-
maxOutboundStreams: 1024
204+
maxOutboundStreams: number
159205
})
160206
]
161207
})
162208
```
163209

164210
### Protocol limits
165211

166-
When registering listeners for custom protocols, the maximum number of simultaneously open inbound and outbound streams per-connection can be specified. If not specified these will default to 32 inbound streams and 64 outbound streams.
212+
When registering listeners for custom protocols, the maximum number of simultaneously open inbound and outbound streams per-connection can be specified. If not specified these will default to [32 inbound streams and 64 outbound streams](https://github.com/libp2p/js-libp2p/blob/master/src/registrar.ts#L14-L15).
167213

168214
If more than this number of streams for the given protocol are opened on a single connection, subsequent new streams for that protocol will be immediately reset.
169215

170-
Since incoming stream data is buffered until it is comsumed, you should attempt to specify the minimum amount of streams required to keep memory usage to a minimum.
216+
Since incoming stream data is buffered until it is consumed, you should attempt to specify the minimum amount of streams required to keep memory usage to a minimum.
171217

172-
```js
218+
All fields are optional. The default values are defined in [src/registrar.ts](https://github.com/libp2p/js-libp2p/blob/master/src/registrar.ts) - please see that file for the current values.
219+
220+
```ts
173221
libp2p.handle('/my-protocol/1.0.0', (streamData) => {
174222
// ..handle stream
175223
}, {
176-
maxInboundStreams: 10, // defaults to 32
177-
maxOutboundStreams: 10, // defaults to 64
178-
})
179-
```
180-
181-
## Closing connections
182-
183-
When choosing connections to close the connection manager sorts the list of connections by the value derived from the tags given to each peer. The values of all tags are summed and connections with lower valued peers are elibible for closing first.
184-
185-
```js
186-
// tag a peer
187-
await libp2p.peerStore.tagPeer(peerId, 'my-tag', {
188-
value: 50, // 0-100 is the typical value range
189-
ttl: 1000 // optional field, this tag will be deleted after this many ms
224+
maxInboundStreams: number
225+
maxOutboundStreams: number
190226
})
191227
```
192228

@@ -198,28 +234,30 @@ A non-exhaustive list follows:
198234

199235
### TCP
200236

201-
The [@libp2p/tcp](https://github.com/libp2p/js-libp2p-tcp) transport allows additional limits to be configured
237+
The [@libp2p/tcp](https://github.com/libp2p/js-libp2p-tcp) transport allows additional limits to be configured.
202238

203-
```js
239+
All fields are optional. The full list of options is defined in [@libp2p/tcp/src/index.ts](https://github.com/libp2p/js-libp2p-tcp/blob/master/src/index.ts) - please see that file for more details.
240+
241+
```ts
204242
const node = await createLibp2pNode({
205243
transports: [
206-
new TCP({
244+
tcp({
207245
/**
208-
* Inbound connections with no activity in this timeframe (ms) will be closed
246+
* Inbound connections with no activity in this time frame (ms) will be closed
209247
*/
210-
inboundSocketInactivityTimeout: 30000,
248+
inboundSocketInactivityTimeout: number
211249

212250
/**
213-
* Outbound connections with no activity in this timeframe (ms) will be closed
251+
* Outbound connections with no activity in this time frame (ms) will be closed
214252
*/
215-
outboundSocketInactivityTimeout: 60000,
253+
outboundSocketInactivityTimeout: number
216254

217255
/**
218256
* Once this many connections are open on this listener any further connections
219257
* will be rejected - this will have no effect if it is larger than the value
220258
* configured for the ConnectionManager maxConnections parameter
221259
*/
222-
maxConnections: 200
260+
maxConnections: number
223261
})
224262
]
225263
})
@@ -257,3 +295,24 @@ const node = await createLibp2pNode({
257295
}
258296
})
259297
```
298+
299+
## How much memory will be used for buffering?
300+
301+
There is no a single config value to control the amount of memory js-libp2p uses.
302+
303+
Important details for ascertaining this are:
304+
305+
* Each connection has a multiplexer
306+
* Each multiplexer has a buffer for raw incoming data (`muxer.maxUnprocessedMessageQueueSize`)
307+
* The incoming data is parsed into messages for each stream and queued (`muxer.maxStreamBufferSize`)
308+
* Each multiplexer has a stream limit for number of streams (`muxer.maxInboundStreams`, `muxer.maxOutboundStreams`).
309+
310+
As a result, the max amount of memory buffered by libp2p is approximately:
311+
312+
```
313+
connectionManager.maxConnections *
314+
(muxer.maxUnprocessedMessageQueueSize
315+
+ (muxer.maxInboundStreams * muxer.maxStreamBufferSize)
316+
+ (muxer.maxOutboundStreams * muxer.maxStreamBufferSize)
317+
)
318+
```

0 commit comments

Comments
 (0)