diff --git a/src/client.cpp b/src/client.cpp
index 1bacee514a3c706f0475d17dce1549dedb364e95..e24f0d77c20974c4d8a486407d5585d040f9247a 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -49,36 +49,37 @@ Client::on_resolve(std::shared_ptr<Session> s,
           s->socket.next_layer(),
           results.begin(),
           results.end(),
-          std::bind(&Client::on_connect, shared_from_this(), s, std::placeholders::_1));
+          std::bind(&Client::on_connect, shared_from_this(), std::move(s), std::placeholders::_1));
 }
 
 void
 Client::on_connect(std::shared_ptr<Session> s, boost::system::error_code ec)
 {
         if (ec) {
-                remove_session(s);
-                return s->on_failure(s->id, ec);
+                s->on_failure(s->id, ec);
+                return remove_session(std::move(s));
         }
 
         // Perform the SSL handshake
         s->socket.async_handshake(
           boost::asio::ssl::stream_base::client,
-          std::bind(&Client::on_handshake, shared_from_this(), s, std::placeholders::_1));
+          std::bind(
+            &Client::on_handshake, shared_from_this(), std::move(s), std::placeholders::_1));
 }
 
 void
 Client::on_handshake(std::shared_ptr<Session> s, boost::system::error_code ec)
 {
         if (ec) {
-                remove_session(s);
-                return s->on_failure(s->id, ec);
+                s->on_failure(s->id, ec);
+                return remove_session(std::move(s));
         }
 
         boost::beast::http::async_write(s->socket,
                                         s->request,
                                         std::bind(&Client::on_write,
                                                   shared_from_this(),
-                                                  s,
+                                                  std::move(s),
                                                   std::placeholders::_1,
                                                   std::placeholders::_2));
 }
@@ -91,17 +92,19 @@ Client::on_write(std::shared_ptr<Session> s,
         boost::ignore_unused(bytes_transferred);
 
         if (ec) {
-                remove_session(s);
-                return s->on_failure(s->id, ec);
+                s->on_failure(s->id, ec);
+                return remove_session(std::move(s));
         }
 
         // Receive the HTTP response
-        http::async_read(
-          s->socket,
-          s->output_buf,
-          s->parser,
-          std::bind(
-            &Client::on_read, shared_from_this(), s, std::placeholders::_1, std::placeholders::_2));
+        http::async_read(s->socket,
+                         s->output_buf,
+                         s->parser,
+                         std::bind(&Client::on_read,
+                                   shared_from_this(),
+                                   std::move(s),
+                                   std::placeholders::_1,
+                                   std::placeholders::_2));
 }
 
 void
@@ -114,7 +117,7 @@ Client::on_read(std::shared_ptr<Session> s,
         if (ec)
                 s->error_code = ec;
 
-        on_request_complete(s);
+        on_request_complete(std::move(s));
 }
 
 void
@@ -124,7 +127,7 @@ Client::do_request(std::shared_ptr<Session> s)
                                 std::to_string(port_),
                                 std::bind(&Client::on_resolve,
                                           shared_from_this(),
-                                          s,
+                                          std::move(s),
                                           std::placeholders::_1,
                                           std::placeholders::_2));
 }
@@ -137,7 +140,7 @@ Client::remove_session(std::shared_ptr<Session> s)
         // care about the error code if this function fails.
         boost::system::error_code ignored_ec;
 
-        s->socket.async_shutdown([s](boost::system::error_code ec) {
+        s->socket.async_shutdown([s = std::move(s)](boost::system::error_code ec) {
                 if (ec == boost::asio::error::eof) {
                         // Rationale:
                         // http://stackoverflow.com/questions/25587403/boost-asio-ssl-async-shutdown-always-finishes-with-an-error
@@ -162,14 +165,14 @@ Client::remove_session(std::shared_ptr<Session> s)
 void
 Client::on_request_complete(std::shared_ptr<Session> s)
 {
-        remove_session(s);
-
         boost::system::error_code ec(s->error_code);
         s->on_success(s->id, s->parser.get(), ec);
+
+        remove_session(std::move(s));
 }
 
 void
-Client::setup_auth(std::shared_ptr<Session> session, bool auth)
+Client::setup_auth(Session *session, bool auth)
 {
         const auto token = access_token();
 
diff --git a/src/client.hpp b/src/client.hpp
index 3d3ca86b80afa356e85c78017a3d10b7dd3efb31..bb5ab0b46e7601aeaa79876b3dc45866ecb999d8 100644
--- a/src/client.hpp
+++ b/src/client.hpp
@@ -257,7 +257,7 @@ private:
         std::shared_ptr<Session> create_session(HeadersCallback<Response> callback);
 
         //! Setup http header with the access token if needed.
-        void setup_auth(std::shared_ptr<Session> session, bool auth);
+        void setup_auth(Session *session, bool auth);
 
         void remove_session(std::shared_ptr<Session> s);
         void on_request_complete(std::shared_ptr<Session> s);
@@ -341,7 +341,7 @@ mtx::client::Client::post(const std::string &endpoint,
         if (!session)
                 return;
 
-        setup_auth(session, requires_auth);
+        setup_auth(session.get(), requires_auth);
 
         session->request.method(boost::beast::http::verb::post);
         session->request.target("/_matrix" + endpoint);
@@ -352,7 +352,7 @@ mtx::client::Client::post(const std::string &endpoint,
         session->request.body() = serialize<Request>(req);
         session->request.prepare_payload();
 
-        do_request(session);
+        do_request(std::move(session));
 }
 
 // put function for the PUT HTTP requests that send responses
@@ -369,7 +369,7 @@ mtx::client::Client::put(const std::string &endpoint,
         if (!session)
                 return;
 
-        setup_auth(session, requires_auth);
+        setup_auth(session.get(), requires_auth);
 
         session->request.method(boost::beast::http::verb::put);
         session->request.target("/_matrix" + endpoint);
@@ -380,7 +380,7 @@ mtx::client::Client::put(const std::string &endpoint,
         session->request.body() = serialize<Request>(req);
         session->request.prepare_payload();
 
-        do_request(session);
+        do_request(std::move(session));
 }
 
 // provides PUT functionality for the endpoints which dont respond with a body
@@ -409,7 +409,7 @@ mtx::client::Client::get(const std::string &endpoint,
         if (!session)
                 return;
 
-        setup_auth(session, requires_auth);
+        setup_auth(session.get(), requires_auth);
 
         session->request.method(boost::beast::http::verb::get);
         session->request.target("/_matrix" + endpoint);
@@ -418,14 +418,14 @@ mtx::client::Client::get(const std::string &endpoint,
         session->request.set(boost::beast::http::field::host, session->host);
         session->request.prepare_payload();
 
-        do_request(session);
+        do_request(std::move(session));
 }
 
 template<class Response>
 std::shared_ptr<mtx::client::Session>
 mtx::client::Client::create_session(HeadersCallback<Response> callback)
 {
-        std::shared_ptr<Session> session = std::make_shared<Session>(
+        auto session = std::make_shared<Session>(
           ios_,
           ssl_ctx_,
           server_,
@@ -507,7 +507,7 @@ mtx::client::Client::create_session(HeadersCallback<Response> callback)
                 return nullptr;
         }
 
-        return session;
+        return std::move(session);
 }
 
 template<class Payload, mtx::events::EventType Event>