diff --git a/RELEASE-NOTES-next b/RELEASE-NOTES-next
index e5ce52de..da5a014b 100644
--- a/RELEASE-NOTES-next
+++ b/RELEASE-NOTES-next
@@ -45,3 +45,4 @@ working. Please reach out to us in that case!
   • set _NET_DESKTOP_VIEWPORT after randr changes
   • fix a bug with i3-nagbar not starting after it has already started once
   • fix conflict when moving parent of fullscreen window to workspace
+  • fix Xorg memory leak with i3bar
diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c
index 5241f141..94212630 100644
--- a/i3bar/src/xcb.c
+++ b/i3bar/src/xcb.c
@@ -1609,16 +1609,19 @@ void kick_tray_clients(i3_output *output) {
  *
  */
 void destroy_window(i3_output *output) {
-    if (output == NULL) {
-        return;
-    }
-    if (output->bar.id == XCB_NONE) {
+    if (output == NULL || output->bar.id == XCB_NONE) {
         return;
     }
 
-    kick_tray_clients(output);
+    draw_util_surface_free(xcb_connection, &(output->bar));
+    draw_util_surface_free(xcb_connection, &(output->buffer));
+    draw_util_surface_free(xcb_connection, &(output->statusline_buffer));
     xcb_destroy_window(xcb_connection, output->bar.id);
+    xcb_free_pixmap(xcb_connection, output->buffer.id);
+    xcb_free_pixmap(xcb_connection, output->statusline_buffer.id);
     output->bar.id = XCB_NONE;
+
+    kick_tray_clients(output);
 }
 
 /* Strut partial tells i3 where to reserve space for i3bar. This is determined