diff --git a/src/include/platform/CHIPDeviceEvent.h b/src/include/platform/CHIPDeviceEvent.h
index 4583f6cc887c7b..0d3da3b44db27d 100644
--- a/src/include/platform/CHIPDeviceEvent.h
+++ b/src/include/platform/CHIPDeviceEvent.h
@@ -307,10 +307,7 @@ typedef void (*AsyncWorkFunct)(intptr_t arg);
 
 #include <ble/BleConfig.h>
 #include <inet/InetLayer.h>
-#include <system/SystemEvent.h>
-#include <system/SystemLayer.h>
-#include <system/SystemObject.h>
-#include <system/SystemPacketBuffer.h>
+#include <lib/support/LambdaBridge.h>
 
 namespace chip {
 namespace DeviceLayer {
@@ -325,7 +322,7 @@ struct ChipDeviceEvent final
     union
     {
         ChipDevicePlatformEvent Platform;
-        System::LambdaBridge LambdaEvent;
+        LambdaBridge LambdaEvent;
         struct
         {
             ::chip::System::EventType Type;
diff --git a/src/include/platform/PlatformManager.h b/src/include/platform/PlatformManager.h
index 9f268cb00573dd..966d3e033c7874 100644
--- a/src/include/platform/PlatformManager.h
+++ b/src/include/platform/PlatformManager.h
@@ -25,12 +25,9 @@
 
 #include <platform/CHIPDeviceBuildConfig.h>
 #include <platform/CHIPDeviceEvent.h>
+#include <system/PlatformEventSupport.h>
 #include <system/SystemLayer.h>
 
-#if CHIP_SYSTEM_CONFIG_USE_LWIP
-#include <system/LwIPEventSupport.h>
-#endif // CHIP_SYSTEM_CONFIG_USE_LWIP
-
 namespace chip {
 
 namespace Dnssd {
diff --git a/src/include/platform/internal/GenericPlatformManagerImpl.cpp b/src/include/platform/internal/GenericPlatformManagerImpl.cpp
index 29d29efb3af17b..e3eaa0ad623b3c 100644
--- a/src/include/platform/internal/GenericPlatformManagerImpl.cpp
+++ b/src/include/platform/internal/GenericPlatformManagerImpl.cpp
@@ -233,7 +233,7 @@ void GenericPlatformManagerImpl<ImplClass>::_DispatchEvent(const ChipDeviceEvent
         break;
 
     case DeviceEventType::kChipLambdaEvent:
-        event->LambdaEvent.LambdaProxy(static_cast<const void *>(event->LambdaEvent.LambdaBody));
+        event->LambdaEvent();
         break;
 
     case DeviceEventType::kCallWorkFunct:
diff --git a/src/lib/support/LambdaBridge.h b/src/lib/support/LambdaBridge.h
new file mode 100644
index 00000000000000..32b0a17075fc80
--- /dev/null
+++ b/src/lib/support/LambdaBridge.h
@@ -0,0 +1,53 @@
+/*
+ *    Copyright (c) 2021 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#pragma once
+
+#include <string.h>
+
+#include <lib/core/CHIPConfig.h>
+
+namespace chip {
+
+class LambdaBridge
+{
+public:
+    // Use initialize instead of constructor because this class has to be trivial
+    template <typename Lambda>
+    void Initialize(const Lambda & lambda)
+    {
+        // memcpy is used to move the lambda into the event queue, so it must be trivially copyable
+        static_assert(std::is_trivially_copyable<Lambda>::value, "lambda must be trivially copyable");
+        static_assert(sizeof(Lambda) <= CHIP_CONFIG_LAMBDA_EVENT_SIZE, "lambda too large");
+        static_assert(CHIP_CONFIG_LAMBDA_EVENT_ALIGN % alignof(Lambda) == 0, "lambda align too large");
+
+        // Implicit cast a capture-less lambda into a raw function pointer.
+        mLambdaProxy = [](const std::aligned_storage<CHIP_CONFIG_LAMBDA_EVENT_SIZE, CHIP_CONFIG_LAMBDA_EVENT_ALIGN> & body) {
+            (*reinterpret_cast<const Lambda *>(&body))();
+        };
+        memcpy(&mLambdaBody, &lambda, sizeof(Lambda));
+    }
+
+    void operator()() const { mLambdaProxy(mLambdaBody); }
+
+private:
+    void (*mLambdaProxy)(const std::aligned_storage<CHIP_CONFIG_LAMBDA_EVENT_SIZE, CHIP_CONFIG_LAMBDA_EVENT_ALIGN> & body);
+    std::aligned_storage<CHIP_CONFIG_LAMBDA_EVENT_SIZE, CHIP_CONFIG_LAMBDA_EVENT_ALIGN> mLambdaBody;
+};
+
+static_assert(std::is_trivial<LambdaBridge>::value, "LambdaBridge is not trivial");
+
+} // namespace chip
diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn
index c18a3da9d193cb..7870c9127e3b8c 100644
--- a/src/platform/BUILD.gn
+++ b/src/platform/BUILD.gn
@@ -285,8 +285,8 @@ if (chip_device_platform != "none") {
       "GeneralUtils.cpp",
       "Globals.cpp",
       "LockTracker.cpp",
-      "LwIPEventSupport.cpp",
       "PersistedStorage.cpp",
+      "PlatformEventSupport.cpp",
       "TestIdentity.cpp",
     ]
 
diff --git a/src/platform/LwIPEventSupport.cpp b/src/platform/PlatformEventSupport.cpp
similarity index 96%
rename from src/platform/LwIPEventSupport.cpp
rename to src/platform/PlatformEventSupport.cpp
index 0a4cead359ab50..f7ed770bdf8f6f 100644
--- a/src/platform/LwIPEventSupport.cpp
+++ b/src/platform/PlatformEventSupport.cpp
@@ -34,11 +34,11 @@ namespace System {
 
 using namespace ::chip::DeviceLayer;
 
-CHIP_ERROR PlatformEventing::ScheduleLambdaBridge(System::Layer & aLayer, const LambdaBridge & bridge)
+CHIP_ERROR PlatformEventing::ScheduleLambdaBridge(System::Layer & aLayer, LambdaBridge && bridge)
 {
     ChipDeviceEvent event;
     event.Type        = DeviceEventType::kChipLambdaEvent;
-    event.LambdaEvent = bridge;
+    event.LambdaEvent = std::move(bridge);
 
     return PlatformMgr().PostEvent(&event);
 }
diff --git a/src/system/BUILD.gn b/src/system/BUILD.gn
index 83989935b6f7ef..e4538f9a930142 100644
--- a/src/system/BUILD.gn
+++ b/src/system/BUILD.gn
@@ -131,6 +131,7 @@ static_library("system") {
     "SystemError.h",
     "SystemEvent.h",
     "SystemFaultInjection.h",
+    "SystemLayer.cpp",
     "SystemLayer.h",
     "SystemLayerImpl${chip_system_config_event_loop}.cpp",
     "SystemLayerImpl${chip_system_config_event_loop}.h",
@@ -170,7 +171,7 @@ static_library("system") {
   }
 
   if (chip_system_config_use_lwip) {
-    sources += [ "LwIPEventSupport.h" ]
+    sources += [ "PlatformEventSupport.h" ]
   }
 
   if (chip_with_nlfaultinjection) {
diff --git a/src/system/LwIPEventSupport.h b/src/system/PlatformEventSupport.h
similarity index 97%
rename from src/system/LwIPEventSupport.h
rename to src/system/PlatformEventSupport.h
index 3679bec5a68a38..ee17332a04df4a 100644
--- a/src/system/LwIPEventSupport.h
+++ b/src/system/PlatformEventSupport.h
@@ -29,7 +29,7 @@ class Object;
 class PlatformEventing
 {
 public:
-    static CHIP_ERROR ScheduleLambdaBridge(System::Layer & aLayer, const LambdaBridge & bridge);
+    static CHIP_ERROR ScheduleLambdaBridge(System::Layer & aLayer, LambdaBridge && bridge);
     static CHIP_ERROR PostEvent(System::Layer & aLayer, Object & aTarget, EventType aType, uintptr_t aArgument);
     static CHIP_ERROR StartTimer(System::Layer & aLayer, System::Clock::Timeout aTimeout);
 };
diff --git a/src/system/SystemLayer.cpp b/src/system/SystemLayer.cpp
new file mode 100644
index 00000000000000..cb4330e194c5ec
--- /dev/null
+++ b/src/system/SystemLayer.cpp
@@ -0,0 +1,35 @@
+/*
+ *    Copyright (c) 2021 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include <lib/support/CodeUtils.h>
+#include <system/PlatformEventSupport.h>
+#include <system/SystemLayer.h>
+
+namespace chip {
+namespace System {
+
+CHIP_ERROR Layer::ScheduleLambdaBridge(LambdaBridge && bridge)
+{
+    CHIP_ERROR lReturn = PlatformEventing::ScheduleLambdaBridge(*this, std::move(bridge));
+    if (lReturn != CHIP_NO_ERROR)
+    {
+        ChipLogError(chipSystemLayer, "Failed to queue CHIP System Layer lambda event: %s", ErrorStr(lReturn));
+    }
+    return lReturn;
+}
+
+} // namespace System
+} // namespace chip
diff --git a/src/system/SystemLayer.h b/src/system/SystemLayer.h
index b731ec31fa5feb..b61acf22c6fe70 100644
--- a/src/system/SystemLayer.h
+++ b/src/system/SystemLayer.h
@@ -25,6 +25,8 @@
 
 #pragma once
 
+#include <type_traits>
+
 // Include configuration headers
 #include <system/SystemConfig.h>
 
@@ -32,6 +34,7 @@
 
 #include <lib/support/CodeUtils.h>
 #include <lib/support/DLLUtil.h>
+#include <lib/support/LambdaBridge.h>
 #include <lib/support/ObjectLifeCycle.h>
 #include <system/SystemClock.h>
 #include <system/SystemError.h>
@@ -50,12 +53,6 @@
 namespace chip {
 namespace System {
 
-struct LambdaBridge
-{
-    void (*LambdaProxy)(const void * context);
-    alignas(CHIP_CONFIG_LAMBDA_EVENT_ALIGN) char LambdaBody[CHIP_CONFIG_LAMBDA_EVENT_SIZE];
-};
-
 class Layer;
 using TimerCompleteCallback = void (*)(Layer * aLayer, void * appState);
 
@@ -148,6 +145,31 @@ class DLL_EXPORT Layer
      */
     virtual CHIP_ERROR ScheduleWork(TimerCompleteCallback aComplete, void * aAppState) = 0;
 
+    /**
+     * @brief
+     *   Schedules a lambda even to be run as soon as possible in the CHIP context. This function is not thread-safe,
+     *   it must be called with in the CHIP context
+     *
+     *  @param[in] event   A object encapsulate the context of a lambda
+     *
+     *  @retval    CHIP_NO_ERROR                  On success.
+     *  @retval    other Platform-specific errors generated indicating the reason for failure.
+     */
+    CHIP_ERROR ScheduleLambdaBridge(LambdaBridge && event);
+
+    /**
+     * @brief
+     *   Schedules a lambda object to be run as soon as possible in the CHIP context. This function is not thread-safe,
+     *   it must be called with in the CHIP context
+     */
+    template <typename Lambda>
+    CHIP_ERROR ScheduleLambda(const Lambda & lambda)
+    {
+        LambdaBridge bridge;
+        bridge.Initialize(lambda);
+        return ScheduleLambdaBridge(std::move(bridge));
+    }
+
 private:
     // Copy and assignment NOT DEFINED
     Layer(const Layer &) = delete;
@@ -202,36 +224,6 @@ class LayerLwIP : public Layer
      */
     virtual CHIP_ERROR PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument) = 0;
 
-    /**
-     * This posts an event / message of the specified type with the provided argument to this instance's platform-specific event
-     * queue.
-     *
-     *  @param[in] event   A object encapsulate the context of a lambda
-     *
-     *  @retval    CHIP_NO_ERROR                  On success.
-     *  @retval    CHIP_ERROR_INCORRECT_STATE     If the state of the Layer object is incorrect.
-     *  @retval    CHIP_ERROR_NO_MEMORY           If the event queue is already full.
-     *  @retval    other Platform-specific errors generated indicating the reason for failure.
-     */
-    virtual CHIP_ERROR ScheduleLambdaBridge(const LambdaBridge & event) = 0;
-
-    template <typename Lambda>
-    CHIP_ERROR ScheduleLambda(const Lambda & lambda)
-    {
-        LambdaBridge event;
-
-        // memcpy is used to move the lambda into the event queue, so it must be trivially copyable
-        static_assert(std::is_trivially_copyable<Lambda>::value);
-        static_assert(sizeof(Lambda) <= CHIP_CONFIG_LAMBDA_EVENT_SIZE);
-        static_assert(alignof(Lambda) <= CHIP_CONFIG_LAMBDA_EVENT_ALIGN);
-
-        // Implicit cast a capture-less lambda into a raw function pointer.
-        event.LambdaProxy = [](const void * body) { (*static_cast<const Lambda *>(body))(); };
-        memcpy(event.LambdaBody, &lambda, sizeof(Lambda));
-
-        return ScheduleLambdaBridge(event);
-    }
-
 protected:
     // Provide access to private members of EventHandlerDelegate.
     struct LwIPEventHandlerDelegate : public EventHandlerDelegate
diff --git a/src/system/SystemLayerImplLwIP.cpp b/src/system/SystemLayerImplLwIP.cpp
index ff7585ab0b76ad..8385cec67c1519 100644
--- a/src/system/SystemLayerImplLwIP.cpp
+++ b/src/system/SystemLayerImplLwIP.cpp
@@ -22,7 +22,7 @@
  */
 
 #include <lib/support/CodeUtils.h>
-#include <system/LwIPEventSupport.h>
+#include <system/PlatformEventSupport.h>
 #include <system/SystemFaultInjection.h>
 #include <system/SystemLayer.h>
 #include <system/SystemLayerImplLwIP.h>
@@ -122,18 +122,6 @@ CHIP_ERROR LayerImplLwIP::AddEventHandlerDelegate(EventHandlerDelegate & aDelega
     return CHIP_NO_ERROR;
 }
 
-CHIP_ERROR LayerImplLwIP::ScheduleLambdaBridge(const LambdaBridge & bridge)
-{
-    VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
-
-    CHIP_ERROR lReturn = PlatformEventing::ScheduleLambdaBridge(*this, bridge);
-    if (lReturn != CHIP_NO_ERROR)
-    {
-        ChipLogError(chipSystemLayer, "Failed to queue CHIP System Layer lambda event: %s", ErrorStr(lReturn));
-    }
-    return lReturn;
-}
-
 CHIP_ERROR LayerImplLwIP::PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument)
 {
     VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
diff --git a/src/system/SystemLayerImplLwIP.h b/src/system/SystemLayerImplLwIP.h
index 4ff2686d4e597e..867f198c0119e9 100644
--- a/src/system/SystemLayerImplLwIP.h
+++ b/src/system/SystemLayerImplLwIP.h
@@ -44,7 +44,6 @@ class LayerImplLwIP : public LayerLwIP
 
     // LayerLwIP overrides.
     CHIP_ERROR AddEventHandlerDelegate(EventHandlerDelegate & aDelegate);
-    CHIP_ERROR ScheduleLambdaBridge(const LambdaBridge & bridge) override;
     CHIP_ERROR PostEvent(Object & aTarget, EventType aEventType, uintptr_t aArgument);
 
 public: