diff --git a/monitor.c b/monitor.c
index 8ec2c5e..88938d6 100644
--- a/monitor.c
+++ b/monitor.c
@@ -63,6 +63,7 @@
 #endif
 #include "trace/control.h"
 #include "ui/qemu-spice.h"
+#include "qemu-queue.h"
 
 //#define DEBUG
 //#define DEBUG_COMPLETION
@@ -124,6 +125,17 @@ typedef struct mon_cmd_t {
     int flags;
 } mon_cmd_t;
 
+struct HelpCmdElem {
+    QTAILQ_ENTRY(HelpCmdElem) entry;
+    const mon_cmd_t *cmd;
+};
+
+typedef struct HelpCmdElem HelpCmdElem;
+
+QTAILQ_HEAD(HelpCmdQueue, HelpCmdElem);
+
+typedef struct HelpCmdQueue HelpCmdQueue;
+
 /* file descriptors passed via SCM_RIGHTS */
 typedef struct mon_fd_t mon_fd_t;
 struct mon_fd_t {
@@ -193,6 +205,8 @@ static QLIST_HEAD(mon_list, Monitor) mon_list;
 
 static const mon_cmd_t mon_cmds[];
 static const mon_cmd_t info_cmds[];
+static HelpCmdQueue *mon_cmds_queue;
+static HelpCmdQueue *info_cmds_queue;
 
 static const mon_cmd_t qmp_cmds[];
 static const mon_cmd_t qmp_query_cmds[];
@@ -560,12 +574,15 @@ static int compare_cmd(const char *name, const char *list)
     return 0;
 }
 
-static void help_cmd_dump(Monitor *mon, const mon_cmd_t *cmds,
+static void help_cmd_dump_queue(Monitor *mon, const HelpCmdQueue *queue,
                           const char *prefix, const char *name)
 {
     const mon_cmd_t *cmd;
+    HelpCmdElem *elem = NULL;
+    HelpCmdElem *next = NULL;
 
-    for(cmd = cmds; cmd->name != NULL; cmd++) {
+    QTAILQ_FOREACH_SAFE(elem, queue, entry, next) {
+        cmd = elem->cmd;
         if (!name || !strcmp(name, cmd->name))
             monitor_printf(mon, "%s%s %s -- %s\n", prefix, cmd->name,
                            cmd->params, cmd->help);
@@ -575,9 +592,9 @@ static void help_cmd_dump(Monitor *mon, const mon_cmd_t *cmds,
 static void help_cmd(Monitor *mon, const char *name)
 {
     if (name && !strcmp(name, "info")) {
-        help_cmd_dump(mon, info_cmds, "info ", NULL);
+        help_cmd_dump_queue(mon, info_cmds_queue, "info ", NULL);
     } else {
-        help_cmd_dump(mon, mon_cmds, "", name);
+        help_cmd_dump_queue(mon, mon_cmds_queue, "", name);
         if (name && !strcmp(name, "log")) {
             const CPULogItem *item;
             monitor_printf(mon, "Log items (comma separated):\n");
@@ -5275,6 +5292,76 @@ static void monitor_event(void *opaque, int event)
  * End:
  */
 
+static int cmdlist_sortto_queue(const mon_cmd_t *cmdlist,
+                                HelpCmdQueue **pqueue)
+{
+    const mon_cmd_t *cmd = NULL;
+    HelpCmdElem *elem = NULL;
+    HelpCmdElem *newelem = NULL;
+    HelpCmdElem *next = NULL;
+    HelpCmdQueue *cmdqueue = NULL;
+    int cmpret1, cmpret2;
+
+    if (*pqueue != NULL) {
+        /* queue already allocated.
+        because the cmd contents would not change when reboot, so skip */
+        return 0;
+    }
+    cmdqueue = g_malloc(sizeof(HelpCmdQueue));
+    if (cmdqueue == NULL) {
+        return -1;
+    }
+    QTAILQ_INIT(cmdqueue);
+
+    for (cmd = cmdlist; cmd->name != NULL; cmd++) {
+        newelem = NULL;
+        newelem = g_malloc(sizeof(HelpCmdElem));
+        if (newelem == NULL) {
+            return -1;
+        }
+        newelem->cmd = cmd;
+
+        if (QTAILQ_EMPTY(cmdqueue)) {
+            QTAILQ_INSERT_HEAD(cmdqueue, newelem, entry);
+            continue;
+        }
+        QTAILQ_FOREACH_SAFE(elem, cmdqueue, entry, next) {
+            /* search for proper postion */
+            cmpret1 = strcmp(cmd->name, elem->cmd->name);
+            if (next == NULL) {
+                if (cmpret1 >= 0) {
+                    QTAILQ_INSERT_TAIL(cmdqueue, newelem, entry);
+                } else {
+                    QTAILQ_INSERT_HEAD(cmdqueue, newelem, entry);
+                }
+                break;
+            } else {
+                cmpret2 = strcmp(cmd->name, next->cmd->name);
+            }
+            if ((cmpret1 >= 0) && (cmpret2 <= 0)) {
+                QTAILQ_INSERT_AFTER(cmdqueue, elem, newelem, entry);
+                break;
+            }
+        }
+    }
+    *pqueue = cmdqueue;
+    return 1;
+}
+
+static int cmd_queue_init(void)
+{
+    int ret;
+    ret = cmdlist_sortto_queue(mon_cmds, &mon_cmds_queue);
+    if (ret < 0) {
+        printf("error in initilize mon cmd queue, return is %d.\n", ret);
+    }
+    ret = cmdlist_sortto_queue(info_cmds, &info_cmds_queue);
+    if (ret < 0) {
+        printf("error in initilize info cmd queue, return is %d.\n", ret);
+    }
+    return ret;
+}
+
 void monitor_init(CharDriverState *chr, int flags)
 {
     static int is_first_init = 1;
@@ -5308,6 +5395,8 @@ void monitor_init(CharDriverState *chr, int flags)
     QLIST_INSERT_HEAD(&mon_list, mon, entry);
     if (!default_mon || (flags & MONITOR_IS_DEFAULT))
         default_mon = mon;
+
+    cmd_queue_init();
 }
 
 static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque)
