diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index 059b21991..6cbc974fe 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -358,6 +358,14 @@ public:
         return manager.lock();
     }
 
+    bool GetIsDeferred() const {
+        return is_deferred;
+    }
+
+    void SetIsDeferred(bool is_deferred_ = true) {
+        is_deferred = is_deferred_;
+    }
+
 private:
     friend class IPC::ResponseBuilder;
 
@@ -392,6 +400,7 @@ private:
     u32 domain_offset{};
 
     std::weak_ptr<SessionRequestManager> manager{};
+    bool is_deferred{false};
 
     KernelCore& kernel;
     Core::Memory::Memory& memory;
diff --git a/src/core/hle/service/server_manager.cpp b/src/core/hle/service/server_manager.cpp
index 55788ddeb..1b3db3caf 100644
--- a/src/core/hle/service/server_manager.cpp
+++ b/src/core/hle/service/server_manager.cpp
@@ -25,6 +25,7 @@ constexpr size_t MaximumWaitObjects = 0x40;
 enum HandleType {
     Port,
     Session,
+    DeferEvent,
     Event,
 };
 
@@ -53,9 +54,18 @@ ServerManager::~ServerManager() {
         session->Close();
     }
 
+    for (const auto& request : m_deferrals) {
+        request.session->Close();
+    }
+
     // Close event.
     m_event->GetReadableEvent().Close();
     m_event->Close();
+
+    if (m_deferral_event) {
+        m_deferral_event->GetReadableEvent().Close();
+        // Write event is owned by ServiceManager
+    }
 }
 
 void ServerManager::RunServer(std::unique_ptr<ServerManager>&& server_manager) {
@@ -142,6 +152,21 @@ Result ServerManager::ManageNamedPort(const std::string& service_name,
     R_SUCCEED();
 }
 
+Result ServerManager::ManageDeferral(Kernel::KEvent** out_event) {
+    // Create a new event.
+    m_deferral_event = Kernel::KEvent::Create(m_system.Kernel());
+    ASSERT(m_deferral_event != nullptr);
+
+    // Initialize the event.
+    m_deferral_event->Initialize(nullptr);
+
+    // Set the output.
+    *out_event = m_deferral_event;
+
+    // We succeeded.
+    R_SUCCEED();
+}
+
 void ServerManager::StartAdditionalHostThreads(const char* name, size_t num_threads) {
     for (size_t i = 0; i < num_threads; i++) {
         auto thread_name = fmt::format("{}:{}", name, i + 1);
@@ -207,6 +232,11 @@ Result ServerManager::WaitAndProcessImpl() {
             }
         }
 
+        // Add the deferral wakeup event.
+        if (m_deferral_event != nullptr) {
+            AddWaiter(std::addressof(m_deferral_event->GetReadableEvent()), HandleType::DeferEvent);
+        }
+
         // Add the wakeup event.
         AddWaiter(std::addressof(m_event->GetReadableEvent()), HandleType::Event);
 
@@ -270,6 +300,23 @@ Result ServerManager::WaitAndProcessImpl() {
             // Finish.
             R_RETURN(this->OnSessionEvent(session, std::move(manager)));
         }
+        case HandleType::DeferEvent: {
+            // Clear event.
+            ASSERT(R_SUCCEEDED(m_deferral_event->Clear()));
+
+            // Drain the list of deferrals while we process.
+            std::list<RequestState> deferrals;
+            {
+                std::scoped_lock ll{m_list_mutex};
+                m_deferrals.swap(deferrals);
+            }
+
+            // Allow other threads to serve.
+            sl.unlock();
+
+            // Finish.
+            R_RETURN(this->OnDeferralEvent(std::move(deferrals)));
+        }
         case HandleType::Event: {
             // Clear event and finish.
             R_RETURN(m_event->Clear());
@@ -308,7 +355,6 @@ Result ServerManager::OnPortEvent(Kernel::KServerPort* port,
 Result ServerManager::OnSessionEvent(Kernel::KServerSession* session,
                                      std::shared_ptr<Kernel::SessionRequestManager>&& manager) {
     Result rc{ResultSuccess};
-    Result service_rc{ResultSuccess};
 
     // Try to receive a message.
     std::shared_ptr<Kernel::HLERequestContext> context;
@@ -324,16 +370,43 @@ Result ServerManager::OnSessionEvent(Kernel::KServerSession* session,
     }
     ASSERT(R_SUCCEEDED(rc));
 
+    RequestState request{
+        .session = session,
+        .context = std::move(context),
+        .manager = std::move(manager),
+    };
+
+    // Complete the sync request with deferral handling.
+    R_RETURN(this->CompleteSyncRequest(std::move(request)));
+}
+
+Result ServerManager::CompleteSyncRequest(RequestState&& request) {
+    Result rc{ResultSuccess};
+    Result service_rc{ResultSuccess};
+
+    // Mark the request as not deferred.
+    request.context->SetIsDeferred(false);
+
     // Complete the request. We have exclusive access to this session.
-    service_rc = manager->CompleteSyncRequest(session, *context);
+    service_rc = request.manager->CompleteSyncRequest(request.session, *request.context);
+
+    // If we've been deferred, we're done.
+    if (request.context->GetIsDeferred()) {
+        // Insert into deferral list.
+        std::scoped_lock ll{m_list_mutex};
+        m_deferrals.emplace_back(std::move(request));
+
+        // Finish.
+        R_SUCCEED();
+    }
 
     // Send the reply.
-    rc = session->SendReplyHLE();
+    rc = request.session->SendReplyHLE();
 
     // If the session has been closed, we're done.
     if (rc == Kernel::ResultSessionClosed || service_rc == IPC::ERR_REMOTE_PROCESS_DEAD) {
         // Close the session.
-        session->Close();
+        request.session->Close();
 
         // Finish.
         R_SUCCEED();
@@ -345,7 +418,7 @@ Result ServerManager::OnSessionEvent(Kernel::KServerSession* session,
     // Reinsert the session.
     {
         std::scoped_lock ll{m_list_mutex};
-        m_sessions.emplace(session, std::move(manager));
+        m_sessions.emplace(request.session, std::move(request.manager));
     }
 
     // Signal the wakeup event.
@@ -355,4 +428,21 @@ Result ServerManager::OnSessionEvent(Kernel::KServerSession* session,
     R_SUCCEED();
 }
 
+Result ServerManager::OnDeferralEvent(std::list<RequestState>&& deferrals) {
+    ON_RESULT_FAILURE {
+        std::scoped_lock ll{m_list_mutex};
+        m_deferrals.splice(m_deferrals.end(), deferrals);
+    };
+
+    while (!deferrals.empty()) {
+        RequestState request = deferrals.front();
+        deferrals.pop_front();
+
+        // Try again to complete the request.
+        R_TRY(this->CompleteSyncRequest(std::move(request)));
+    }
+
+    R_SUCCEED();
+}
+
 } // namespace Service
diff --git a/src/core/hle/service/server_manager.h b/src/core/hle/service/server_manager.h
index b26557172..57b954ae8 100644
--- a/src/core/hle/service/server_manager.h
+++ b/src/core/hle/service/server_manager.h
@@ -5,6 +5,7 @@
 
 #include <atomic>
 #include <functional>
+#include <list>
 #include <map>
 #include <mutex>
 #include <string_view>
@@ -19,6 +20,7 @@ class System;
 }
 
 namespace Kernel {
+class HLERequestContext;
 class KEvent;
 class KServerPort;
 class KServerSession;
@@ -42,6 +44,7 @@ public:
     Result ManageNamedPort(const std::string& service_name,
                            std::shared_ptr<Kernel::SessionRequestHandler>&& handler,
                            u32 max_sessions = 64);
+    Result ManageDeferral(Kernel::KEvent** out_event);
 
     Result LoopProcess();
     void StartAdditionalHostThreads(const char* name, size_t num_threads);
@@ -49,12 +52,16 @@ public:
     static void RunServer(std::unique_ptr<ServerManager>&& server);
 
 private:
+    struct RequestState;
+
     Result LoopProcessImpl();
     Result WaitAndProcessImpl();
     Result OnPortEvent(Kernel::KServerPort* port,
                        std::shared_ptr<Kernel::SessionRequestHandler>&& handler);
     Result OnSessionEvent(Kernel::KServerSession* session,
                           std::shared_ptr<Kernel::SessionRequestManager>&& manager);
+    Result OnDeferralEvent(std::list<RequestState>&& deferrals);
+    Result CompleteSyncRequest(RequestState&& state);
 
 private:
     Core::System& m_system;
@@ -65,6 +72,15 @@ private:
     std::map<Kernel::KServerPort*, std::shared_ptr<Kernel::SessionRequestHandler>> m_ports{};
     std::map<Kernel::KServerSession*, std::shared_ptr<Kernel::SessionRequestManager>> m_sessions{};
     Kernel::KEvent* m_event{};
+    Kernel::KEvent* m_deferral_event{};
+
+    // Deferral tracking
+    struct RequestState {
+        Kernel::KServerSession* session;
+        std::shared_ptr<Kernel::HLERequestContext> context;
+        std::shared_ptr<Kernel::SessionRequestManager> manager;
+    };
+    std::list<RequestState> m_deferrals{};
 
     // Host state tracking
     std::atomic<bool> m_stopped{};
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index 0de32b05d..6eba48f03 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -32,6 +32,10 @@ ServiceManager::~ServiceManager() {
         port->GetClientPort().Close();
         port->GetServerPort().Close();
     }
+
+    if (deferral_event) {
+        deferral_event->Close();
+    }
 }
 
 void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) {
@@ -62,6 +66,9 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
 
     service_ports.emplace(name, port);
     registered_services.emplace(name, handler);
+    if (deferral_event) {
+        deferral_event->Signal();
+    }
 
     return ResultSuccess;
 }
@@ -88,7 +95,7 @@ ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name
     std::scoped_lock lk{lock};
     auto it = service_ports.find(name);
     if (it == service_ports.end()) {
-        LOG_ERROR(Service_SM, "Server is not registered! service={}", name);
+        LOG_WARNING(Service_SM, "Server is not registered! service={}", name);
         return ERR_SERVICE_NOT_REGISTERED;
     }
 
@@ -113,6 +120,11 @@ void SM::Initialize(Kernel::HLERequestContext& ctx) {
 
 void SM::GetService(Kernel::HLERequestContext& ctx) {
     auto result = GetServiceImpl(ctx);
+    if (ctx.GetIsDeferred()) {
+        // Don't overwrite the command buffer.
+        return;
+    }
+
     if (result.Succeeded()) {
         IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
         rb.Push(result.Code());
@@ -125,6 +137,11 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {
 
 void SM::GetServiceTipc(Kernel::HLERequestContext& ctx) {
     auto result = GetServiceImpl(ctx);
+    if (ctx.GetIsDeferred()) {
+        // Don't overwrite the command buffer.
+        return;
+    }
+
     IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
     rb.Push(result.Code());
     rb.PushMoveObjects(result.Succeeded() ? result.Unwrap() : nullptr);
@@ -152,8 +169,9 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&
     // Find the named port.
     auto port_result = service_manager.GetServicePort(name);
     if (port_result.Failed()) {
-        LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, port_result.Code().raw);
-        return port_result.Code();
+        LOG_INFO(Service_SM, "Waiting for service {} to become available", name);
+        ctx.SetIsDeferred();
+        return ERR_SERVICE_NOT_REGISTERED;
     }
     auto& port = port_result.Unwrap();
 
@@ -228,8 +246,13 @@ SM::SM(ServiceManager& service_manager_, Core::System& system_)
 SM::~SM() = default;
 
 void LoopProcess(Core::System& system) {
+    auto& service_manager = system.ServiceManager();
     auto server_manager = std::make_unique<ServerManager>(system);
 
+    Kernel::KEvent* deferral_event{};
+    server_manager->ManageDeferral(&deferral_event);
+    service_manager.SetDeferralEvent(deferral_event);
+
     server_manager->ManageNamedPort("sm:", std::make_shared<SM>(system.ServiceManager(), system));
     ServerManager::RunServer(std::move(server_manager));
 }
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h
index 22ca720f8..b7eeafdd6 100644
--- a/src/core/hle/service/sm/sm.h
+++ b/src/core/hle/service/sm/sm.h
@@ -71,6 +71,10 @@ public:
 
     void InvokeControlRequest(Kernel::HLERequestContext& context);
 
+    void SetDeferralEvent(Kernel::KEvent* deferral_event_) {
+        deferral_event = deferral_event_;
+    }
+
 private:
     std::shared_ptr<SM> sm_interface;
     std::unique_ptr<Controller> controller_interface;
@@ -82,6 +86,7 @@ private:
 
     /// Kernel context
     Kernel::KernelCore& kernel;
+    Kernel::KEvent* deferral_event{};
 };
 
 /// Runs SM services.