       ...> |> elem(0)
       ...> |> :erlang.iolist_to_binary()
       "HTTP/1.1 204 No Content\\r\\nfoo: bar\\r\\n\\r\\n"
-  """
-  @spec serialize_response(Raxx.Response.t()) ::
+
+  ### *https://tools.ietf.org/html/rfc7230#section-6.1*
+
+  > A server that does not support persistent connections MUST send the
+  > "close" connection option in every response message that does not
+  > have a 1xx (Informational) status code.
+
+      iex> Raxx.response(204)
+      ...> |> Raxx.set_header("foo", "bar")
+      ...> |> Raxx.HTTP1.serialize_response(connection: :close)
+      ...> |> elem(0)
+      ...> |> :erlang.iolist_to_binary()
+      "HTTP/1.1 204 No Content\\r\\nconnection: close\\r\\nfoo: bar\\r\\n\\r\\n"
+
+      iex> Raxx.response(204)
+      ...> |> Raxx.set_header("foo", "bar")
+      ...> |> Raxx.HTTP1.serialize_response(connection: :keepalive)
+      ...> |> elem(0)
+      ...> |> :erlang.iolist_to_binary()
+      "HTTP/1.1 204 No Content\\r\\nconnection: keep-alive\\r\\nfoo: bar\\r\\n\\r\\n"
+  """
+  @spec serialize_response(Raxx.Response.t(), [{:connection, :close | :keepalive}]) ::
           {iolist, {:complete, iodata} | {:bytes, non_neg_integer() | :chunked}}
-  def serialize_response(response = %Raxx.Response{}) do
+  def serialize_response(response = %Raxx.Response{}, options \\ []) do
     {payload_headers, body} = payload(response)
-    headers = payload_headers ++ response.headers
+    connection_headers = connection_headers(Keyword.get(options, :connection))
+    headers = connection_headers ++ payload_headers ++ response.headers
     head = [response_line(response), header_lines(headers), @crlf]
     {head, body}
   end

  @crlf "\r\n"

  @doc """
  # NOTE set_body should add content-length otherwise we don't know if to delete it to match on other end, when serializing

  ## Examples
      iex> request = Raxx.request(:GET, "http://example.com/path?qs")
      ...> |> Raxx.set_header("accept", "text/plain")
      ...> {head, _body} =  Raxx.HTTP1.serialize_request(request)
      ...> :erlang.iolist_to_binary(head)
      "GET /path?qs HTTP/1.1\\r\\nhost: example.com\\r\\naccept: text/plain\\r\\n\\r\\n"

      iex> request = Raxx.request(:POST, "https://example.com/path")
      ...> |> Raxx.set_header("content-type", "text/plain")
      ...> |> Raxx.set_body(true)
      ...> {head, _body} =  Raxx.HTTP1.serialize_request(request)
      ...> :erlang.iolist_to_binary(head)
      "POST /path HTTP/1.1\\r\\nhost: example.com\\r\\ntransfer-encoding: chunked\\r\\ncontent-type: text/plain\\r\\n\\r\\n"

      iex> request = Raxx.request(:POST, "https://example.com/path")
      ...> |> Raxx.set_header("content-length", "13")
      ...> |> Raxx.set_body(true)
      ...> {head, _body} =  Raxx.HTTP1.serialize_request(request)
      ...> :erlang.iolist_to_binary(head)
      "POST /path HTTP/1.1\\r\\nhost: example.com\\r\\ncontent-length: 13\\r\\n\\r\\n"
  """
  def serialize_request(request = %Raxx.Request{}) do
    {payload_headers, body} = payload(request)
    headers = [{"host", request.authority}] ++ payload_headers ++ request.headers
    head = [start_line(request), header_lines(headers), @crlf]
    {head, body}
  end

  end

  @doc """
  Serialize a response to an iolist

  Because of HEAD requests we should keep body separate
  ## Examples
