diff --git a/Project.toml b/Project.toml
index b96e06d1..e022c028 100644
--- a/Project.toml
+++ b/Project.toml
@@ -18,6 +18,7 @@ PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
 Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
 SimpleBufferStream = "777ac1f9-54b0-4bf8-805c-2214025038e7"
 Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"
+TaskLocalValues = "ed4db957-447d-4319-bfb6-7fa9ae7ecf34"
 URIs = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"
 UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
 
@@ -30,6 +31,7 @@ MbedTLS = "0.6.8, 0.7, 1"
 OpenSSL = "1.3"
 PrecompileTools = "1.2.1"
 SimpleBufferStream = "1.1"
+TaskLocalValues = "0.1.2"
 URIs = "1.3"
 julia = "1.6"
 
diff --git a/src/WebSockets.jl b/src/WebSockets.jl
index 1afb5f76..0f00b133 100644
--- a/src/WebSockets.jl
+++ b/src/WebSockets.jl
@@ -2,6 +2,7 @@ module WebSockets
 
 using Base64, UUIDs, Sockets, Random
 using MbedTLS: digest, MD_SHA1, SSLContext
+using TaskLocalValues
 using ..IOExtras, ..Streams, ..Connections, ..Messages, ..Conditions, ..Servers
 using ..Exceptions: current_exceptions_to_string
 import ..open
@@ -180,9 +181,14 @@ function readframe(io::IO, ::Type{Frame}, buffer::Vector{UInt8}=UInt8[], first_f
     return Frame(flags, extlen, mask, payload)
 end
 
+const frameio = TaskLocalValue{IOBuffer}(() -> IOBuffer())
+
 # writing a single frame
 function writeframe(io::IO, x::Frame)
-    buff = IOBuffer()
+    buff = frameio[]
+    buff.ptr = 1
+    buff.size = 0
+    buff.offset = 0
     n = write(buff, hton(uint16(x.flags)))
     if x.extendedlen !== nothing
         n += write(buff, hton(x.extendedlen))
@@ -199,7 +205,8 @@ function writeframe(io::IO, x::Frame)
     else
         n += write(buff, pl)
     end
-    write(io.io, take!(buff))
+    seekstart(buff)
+    write(io.io, buff)
     return n
 end