aboutsummaryrefslogtreecommitdiffstats
path: root/doc/src/manual/cowboy_websocket.asciidoc
AgeCommit message (Collapse)Author
2025-02-05Lower the lower dynamic buffer value to 1024Loïc Hoguin
There's not a big performance difference between 8192 and 1024 so let's use less memory at the start of the connection.
2025-02-05Implement dynamic socket buffer sizesLoïc Hoguin
Cowboy will set the socket's buffer size dynamically to better fit the current workload. When the incoming data is small, a low buffer size reduces the memory footprint and improves responsiveness and therefore performance. When the incoming data is large, such as large HTTP request bodies, a larger buffer size helps us avoid doing too many binary appends and related allocations. Setting a large buffer size for all use cases is sub-optimal because allocating more than needed necessarily results in a performance hit (not just increased memory usage). By default Cowboy starts with a buffer size of 8192 bytes. It then doubles or halves the buffer size depending on the size of the data it receives from the socket. It stops decreasing at 8192 and increasing at 131072 by default. To keep track of the size of the incoming data Cowboy maintains a moving average. It allows Cowboy to avoid changing the buffer too often but still react quickly when necessary. Cowboy will increase the buffer size when the moving average is above 90% of the current buffer size, and decrease when the moving average is below 40% of the current buffer size. The current buffer size and moving average are propagated when switching protocols. The dynamic buffer is implemented in HTTP/1, HTTP/2 and HTTP/1 Websocket. HTTP/2 Websocket has it disabled because it doesn't interact directly with the socket; in that case it is HTTP/2 that has a dynamic buffer. The dynamic buffer provides a very large performance improvement in many scenarios, at minimal cost for others. Because it largely depend on the underlying protocol the improvements are no all equal. TLS and compression also impact the results. The improvement when reading a large request body, with the requests repeated in a fast loop are: * HTTP: 6x to 20x faster * HTTPS: 2x to 6x faster * H2: 4x to 5x faster * H2C: 20x to 40x faster I am not sure why H2C's performance was so bad, especially compared to H2, when using default buffer sizes. Dynamic buffers make H2C a lot more viable with default settings. The performance impact on "hello world" type requests is minimal, it goes from -5% to +5% roughly. Websocket improvements vary again depending on the protocol, but also depending on whether compression is enabled: * HTTP echo: roughly 2x faster * HTTP send: roughly 4x faster * H2C echo: roughly 2x faster * H2C send: 3x to 4x faster In the echo test we reply back, and Gun doesn't have the dynamic buffer optimisation, so that probably explains the x2 difference. With compression however there isn't much improvement. The results are roughly within -10% to +10% of each other. Zlib compression seems to be a bottleneck, or at least to modify the performance profile to such an extent that the size of the buffer does not matter. This happens to randomly generated binary data as well so it is probably not caused by the test data.
2025-01-16Websocket: Allow setting the max_frame_size option dynamicallyLoïc Hoguin
This can be used to limit the maximum frame size before some authentication or other validation is completed.
2024-01-23Cowboy 2.11Loïc Hoguin
2024-01-08Ensure HTTP/1.1 Websocket resets the trap_exit flagLoïc Hoguin
While we are identified as a supervisor in the tree, we no longer manage children processes at that point, so do not need to trap exit signals. Users can still enable trap_exit if they prefer to.
2023-12-06Fix typos in documentationKian-Meng, Ang
2020-01-06Use active,NLoïc Hoguin
This reduces the number of times we need to ask for more packets, and as a result we get a fairly large boost in performance, especially with HTTP/1.1. Unfortunately this makes Cowboy require at least Erlang/OTP 21.3+ because the ssl application did not have active,N. For simplicity the version required will be Erlang/OTP 22+. In addition this change improves hibernate handling in cowboy_websocket. Hibernate will now work for HTTP/2 transport as well, and stray or unrelated messages will no longer cancel hibernate (the process will handle the message and go back into hibernation). Thanks go to Stressgrid for benchmarking an early version of this commit: https://stressgrid.com/blog/cowboy_performance_part_2/
2019-12-31No longer use erlang:get_stacktrace/0Loïc Hoguin
It has been deprecated in OTP and the new way is available on all supported OTP versions.
2019-10-10Add shutdown_reason Websocket commandLoïc Hoguin
This allows changing the normal exit reason of Websocket processes, providing a way to signal other processes of why the exit occurred.
2019-10-07Document the set_options stream handler commandLoïc Hoguin
2019-10-06Document the commands based Websocket interfaceLoïc Hoguin
The old interface with ok|reply|stop tuples is deprecated.
2019-10-05Add Websocket option validate_utf8Loïc Hoguin
This allows disabling the UTF-8 validation check for text and close frames.
2019-09-06Document unit for options that are in bytesLoïc Hoguin
2018-11-12Add deflate options for Websocket compressionLoïc Hoguin
They allow the server to configure what it is willing to accept for both the negotiated configuration (takeover and window bits) and the other zlib options (level, mem_level and strategy). This can be used to reduce the memory and/or CPU footprint of the compressed data, which comes with a cost in compression ratio.
2018-06-26Add missing frame types to websocket_handle specs/docsLoïc Hoguin
Thanks Artem.
2018-06-06Fix an incorrect section_title level in the manualLoïc Hoguin
2018-03-28Add max_frame_size option for websocket handlersKirill Kinduk
Option allows to limit a frame by size before decoding its payload. LH: I have added a test for when the limit is reached on a nofin fragmented frame (the last commit addressed that case but it had no test). I have fixed formatting and other, and changed the default value to infinity since it might otherwise be incompatible with existing code. I also added documentation and a bunch of other minor changes.
2017-10-02Document cow_ws:frame in Cowboy for nowLoïc Hoguin
2017-09-04Fix more documentation todosLoïc Hoguin
I have decided not to include a manual page for cowboy_stream_h at this point because it clashes with the cowboy_stream manual page. This decision will be revisited in the future.
2017-05-28Introduce the req_filter Websocket optionLoïc Hoguin
This option allows customizing the compacting of the Req object when using Websocket. By default it will keep most public fields excluding headers of course, since those can be large.
2017-02-18Allow passing options to sub protocolsLoïc Hoguin
Before this commit we had an issue where configuring a Websocket connection was simply not possible without doing magic, adding callbacks or extra return values. The init/2 function only allowed setting hibernate and timeout options. After this commit, when switching to a different type of handler you can either return {module, Req, State} or {module, Req, State, Opts} where Opts is any value (as far as the sub protocol interface is concerned) and is ultimately checked by the custom handlers. A large protocol like Websocket would accept only a map there, with many different options, while a small interface like loop handlers would allow passing hibernate and nothing else. For Websocket, hibernate must be set from the websocket_init/1 callback, because init/2 executes in a separate process. Sub protocols now have two callbacks: one with the Opts value, one without. The loop handler code was largely reworked and simplified. It does not need to manage a timeout or read from the socket anymore, it's the job of the protocol code. A lot of unnecessary stuff was therefore removed. Websocket compression must now be enabled from the handler options instead of per listener. This means that a project can have two separate Websocket handlers with different options. Compression is still disabled by default, and the idle_timeout value was changed from inifnity to 60000 (60 seconds), as that's safer and is also a good value for mobile devices.
2016-12-23Update cowboy_loop manualLoïc Hoguin
2016-12-23Update the cowboy_handler manualLoïc Hoguin
Also fixes a small mistake in cowboy_websocket.
2016-12-22Update cowboy_websocket_manualLoïc Hoguin
2016-08-31Update websocket documentation: based on ↵Alex Prut
https://github.com/ninenines/cowboy/blob/master/examples/websocket/src/ws_handler.erl
2016-01-14Convert the documentation to AsciidocLoïc Hoguin
A few small revisions were made, and Erlang.mk has been updated.