diff --git a/inc/lektor/database.h b/inc/lektor/database.h
index e26b78f14089117b8bc4c83e49ecf6e248bbf5a9..475206c5e695c6419e26f7077487e4d6236edb19 100644
--- a/inc/lektor/database.h
+++ b/inc/lektor/database.h
@@ -30,7 +30,7 @@ bool database_detach(sqlite3 *db, const char *name);
 
 /* Get information on the queue and currently playing kara. */
 bool database_queue_state(sqlite3 *db, struct lkt_queue_state *res);
-bool database_queue_current_kara(sqlite3 *db, struct kara_metadata *res);
+bool database_queue_current_kara(sqlite3 *db, struct kara_metadata *res, int *id);
 
 bool database_queue_set_paused(sqlite3 *db, bool paused);
 bool database_queue_set_current_index(sqlite3 *db, int idx);
diff --git a/inc/lektor/macro.h b/inc/lektor/macro.h
index 3ac78e56235110244f9fe2ee620bb38c82e95e04..5403ef8ce96f0ebf4efc9bc18e87c0aa8b056eec 100644
--- a/inc/lektor/macro.h
+++ b/inc/lektor/macro.h
@@ -28,6 +28,9 @@
         goto error;                                                     \
     }
 
+#define SQLITE_DO_ROLLBACK(db)                                          \
+    sqlite3_exec(db, "ROLLBACK TRANSACTION;\n", NULL, NULL, NULL);
+
 #ifndef MAX
 #define MAX(a, b) ((a) < (b) ? (b) : (a))
 #endif /* MAX */
diff --git a/src/commands.c b/src/commands.c
index 2282c9bb041d216aabab8ceaf51ea43681a0bb48..1c5254629204d094134de368286e49adac14bd12 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -98,7 +98,7 @@ command_currentsong(struct lkt_state *srv, size_t c)
 
     memset(&kara, 0, sizeof(struct kara_metadata));
 
-    if (!database_queue_current_kara(srv->db, &kara))
+    if (!database_queue_current_kara(srv->db, &kara, NULL))
         fprintf(stderr, " ! command_currentsong: Failed to get information about the current kara\n");
 
     out = lkt_message_new();
@@ -365,59 +365,13 @@ command_crop(sqlite3 *db, enum mpd_idle_flag *watch_mask_ptr)
     return database_queue_crop(db);
 }
 
-bool
-command_del(sqlite3 *db, struct lkt_win *win, char *pos_range, enum mpd_idle_flag *watch_mask_ptr)
-{
-    (void) win;
-    long pos_lowwer, pos_upper = -1, i;
-    char *endptr;
-    bool ret = true;
-
-    if (pos_range == NULL) {
-        fprintf(stderr, " ! command_del: NULL argument\n");
-        return false;
-    }
-
-    errno = 0;
-    *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
-    pos_lowwer = strtol(pos_range, &endptr, 10);
-
-    if ((errno == ERANGE && (pos_lowwer == LONG_MAX || pos_lowwer == LONG_MIN))
-        || (errno != 0 && pos_lowwer == 0)) {
-        fprintf(stderr, " ! command_del: strtol failed: %s\n", strerror(errno));
-        return false;
-    }
-
-    // Second digit -> a range
-    if (endptr == pos_range) {
-        fprintf(stderr, " . command_del: to digit found in string '%s'\n", pos_range);
-        pos_range = endptr + strcspn(endptr, "0123456789");
-
-        pos_upper = strtol(pos_range, &endptr, 10);
-
-        if ((errno == ERANGE && (pos_upper == LONG_MAX || pos_upper == LONG_MIN))
-            || (errno != 0 && pos_upper == 0)) {
-            fprintf(stderr, " ! command_del: strtol failed: %s\n", strerror(errno));
-            return false;
-        }
-    }
-
-    if (pos_lowwer >= pos_upper)
-        return database_queue_del_pos(db, pos_lowwer);
-    else {
-        for (i = pos_lowwer; i <= pos_upper; ++i)
-            ret &= database_queue_del_pos(db, i);
-
-        return ret;
-    }
-}
-
 bool
 command_delid(sqlite3 *db, struct lkt_win *win, char *id_str, enum mpd_idle_flag *watch_mask_ptr)
 {
     (void) win;
     long id;
     char *endptr;
+    int uri = 0;
 
     errno = 0;
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
@@ -433,6 +387,15 @@ command_delid(sqlite3 *db, struct lkt_win *win, char *id_str, enum mpd_idle_flag
         return false;
     }
 
+    /* If one day we allow suppression of the current kara, will need the `win`
+       pointer to reload the kara in the same position (but the kara won't be
+       the same). */
+    database_queue_current_kara(db, NULL, &uri);
+    if (id == (long) uri) {
+        fprintf(stderr, " . command_delid: Can't delete the currently playing kara\n");
+        return false;
+    }
+
     return database_queue_del_id(db, id);
 }
 
diff --git a/src/database/queue.c b/src/database/queue.c
index 6a486ae466cdb51658d2e1ad9c190460962507f8..1ec0e4292ae8c8821db2cfc6cddfdbd6335fbf54 100644
--- a/src/database/queue.c
+++ b/src/database/queue.c
@@ -53,20 +53,23 @@ error:
 }
 
 bool
-database_queue_current_kara(sqlite3 *db, struct kara_metadata *res)
+database_queue_current_kara(sqlite3 *db, struct kara_metadata *res, int *id)
 {
     static const char *SQL_STMT =
-        "SELECT song_name, source_name, category, language, author_name, song_type, song_number"
+        "SELECT song_name, source_name, category, language, author_name, song_type, song_number, kara_id"
         " FROM kara"
-        " JOIN queue ON queue.kara_id = kara.id"
-        " JOIN queue_state ON queue_state.current = queue.position";
+        " JOIN queue_ ON kara_id = kara.id"
+        " JOIN queue_state ON current = position";
     sqlite3_stmt *stmt = 0;
     int ret = false;
 
     SQLITE_PREPARE(db, stmt, SQL_STMT, error);
-    memset(res, 0, sizeof(struct kara_metadata));
 
     if (sqlite3_step(stmt) == SQLITE_ROW) {
+        /* Here use gotos because of optimisations done by compilators.
+           Most of the time it won't be NULL. */
+        if (!res)
+            goto no_metadata;
         strncpy(res->song_name, (const char *) sqlite3_column_text(stmt, 0), LEKTOR_TAG_MAX - 1);
         strncpy(res->source_name, (const char *) sqlite3_column_text(stmt, 1), LEKTOR_TAG_MAX - 1);
         strncpy(res->category, (const char *) sqlite3_column_text(stmt, 2), LEKTOR_TAG_MAX - 1);
@@ -74,6 +77,10 @@ database_queue_current_kara(sqlite3 *db, struct kara_metadata *res)
         strncpy(res->author_name, (const char *) sqlite3_column_text(stmt, 4), LEKTOR_TAG_MAX - 1);
         strncpy(res->song_type, (const char *) sqlite3_column_text(stmt, 5), LEKTOR_TAG_MAX - 1);
         res->song_number = sqlite3_column_int(stmt, 6);
+no_metadata:
+        /* Most of the time this will be NULL. */
+        if (id)
+            *id = sqlite3_column_int(stmt, 7);
     } else {
         fprintf(stderr, " ! database_queue_current_kara: failed: %s\n",
                 sqlite3_errmsg(db));
@@ -303,40 +310,25 @@ error:
     return status;
 }
 
-static bool
-queue_rm_with_sql(sqlite3 *db, const char *sql, int arg)
-{
-    sqlite3_stmt *stmt = 0;
-    bool res = sqlite3_prepare_v2(db, sql, -1, &stmt, 0) == SQLITE_OK &&
-               sqlite3_bind_int(stmt, 1, arg) == SQLITE_OK &&
-               sqlite3_step(stmt) == SQLITE_DONE;
-
-    if (!res)
-        fprintf(stderr, " ! del_kara_with_sql: Failed to delete kara: %s\n",
-                sqlite3_errmsg(db));
-
-    sqlite3_finalize(stmt);
-    return res;
-}
-
 bool
 database_queue_del_id(sqlite3 *db, int id)
 {
-    static const char *SQL_DEL_KARA = "DELETE FROM queue WHERE kara_id = ?";
-    return queue_rm_with_sql(db, SQL_DEL_KARA, id);
-}
-
-bool
-database_queue_del_pos(sqlite3 *db, int pos)
-{
-    static const char *SQL_DEL_POS =
-        "DELETE FROM queue"
-        "  WHERE position = "
-        "    ( SELECT old_position"
-        "      FROM queue_"
-        "      WHERE position = ?"
-        "    );";
-    return queue_rm_with_sql(db, SQL_DEL_POS, pos);
+    static const char *SQL_TEMPLATE =
+        "BEGIN TRANSACTION;"
+        "WITH before(pos) AS (SELECT position FROM queue_ JOIN queue_state WHERE position < current ORDER BY position DESC LIMIT 1) "
+        "UPDATE queue_state SET current = CASE"
+        " WHEN current IS NULL THEN NULL"
+        " ELSE (SELECT pos FROM before) "
+        "END WHERE current > (SELECT position FROM queue_ WHERE kara_id = %d);"
+        "DELETE FROM queue WHERE kara_id = %d;"
+        "COMMIT TRANSACTION;";
+    char SQL[LKT_MAX_SQLITE_STATEMENT];
+    snprintf(SQL, LKT_MAX_SQLITE_STATEMENT - 1, SQL_TEMPLATE, id, id, id);
+    SQL[LKT_MAX_SQLITE_STATEMENT - 1] = '\0';
+    SQLITE_EXEC(db, SQL, error);
+    return true;
+error:
+    return false;
 }
 
 bool
@@ -578,8 +570,8 @@ database_queue_get_current_file(sqlite3 *db, char filepath[PATH_MAX])
     static const char *SQL_STMT =
         "SELECT file_path"
         "  FROM kara"
-        "  JOIN queue ON kara.id = queue.kara_id"
-        "  JOIN queue_state ON queue.position = queue_state.current";
+        "  JOIN queue_ ON kara.id = queue_.kara_id"
+        "  JOIN queue_state ON queue_.position = queue_state.current";
     bool status = false;
     int code = SQLITE_OK;
     sqlite3_stmt *stmt = NULL;
diff --git a/src/database/stickers.c b/src/database/stickers.c
index 4b8661b800f249bdf5fc9fd3cb7c80552c1a7b23..afeb6209b62dd438d7a9cc57e8e1cae23e7fc5b4 100644
--- a/src/database/stickers.c
+++ b/src/database/stickers.c
@@ -245,7 +245,7 @@ database_sticker_delete_specify(sqlite3 *db, const char *type, int uri, const ch
     }
 
     snprintf(SQL, LKT_MAX_SQLITE_STATEMENT - 1, "DELETE FROM 'stickers.%s' "
-            "WHERE 'stickers.%s' = ? ", type, type);
+             "WHERE 'stickers.%s' = ? ", type, type);
     SQL[LKT_MAX_SQLITE_STATEMENT - 1] = 0;
 
     /* If there is a name specified. */
diff --git a/src/main/lkt.c b/src/main/lkt.c
index c64c68282eae6ae333d951cde7f817a6a71b9ef2..d28fb1a93bfa1d9447b2cc41cf08b1a1b780c16d 100644
--- a/src/main/lkt.c
+++ b/src/main/lkt.c
@@ -21,6 +21,7 @@
 #include <assert.h>
 #include <stdbool.h>
 #include <stdarg.h>
+#include <limits.h>
 
 #define LKT_KEY_VALUE_SEP           ": \n\t\0"
 #define STR_MATCH(str1, str2)       (! strcasecmp(str1, str2))
@@ -47,6 +48,7 @@ help(void)
         "    status:        get the status of lektor.\n"
         "    current:       get the currently playing song.\n"
         "    add <query>:   add a kara to the playlist with a query.\n"
+        "    delete <id>:   delete the id from the queue.\n"
         "    clear:         clear the queue of lektor.\n"
         "    prev:          play previous kara in the queue.\n"
         "    next:          play the next kara in the queue.\n"
@@ -113,12 +115,16 @@ static int
 lkt_valid_type(const char *type)
 {
     return (STR_MATCH(type, "all")      ||
+            STR_MATCH(type, "any")      ||
             STR_MATCH(type, "a")        ||
+            STR_MATCH(type, "id")       ||
+            STR_MATCH(type, "title")    ||
             STR_MATCH(type, "type")     ||
             STR_MATCH(type, "cat")      ||
             STR_MATCH(type, "category") ||
             STR_MATCH(type, "author")   ||
             STR_MATCH(type, "auth")     ||
+            STR_MATCH(type, "source")   ||
             STR_MATCH(type, "lang")     ||
             STR_MATCH(type, "language"));
 }
@@ -475,6 +481,33 @@ shuffle__(struct lkt_cmd_args *args)
     lkt_send_and_exit(shuffle_str__, strlen(shuffle_str__));
 }
 
+noreturn void
+delete__(struct lkt_cmd_args *args)
+{
+    if (args->argc != 1)
+        fail("Invalid argument, need onlt one argument");
+
+    static const char *cmd_id__ = "deleteid %d\nclose\n";
+    int dumy = 0;
+    FILE *sock = lkt_connect();
+    char buff[3];
+
+    sscanf(args->argv[0], "%d", &dumy);
+    if (dumy != 0) {
+        write_socket_format(sock, cmd_id__, dumy);
+        goto check;
+    }
+
+    fail("Invalid argument");
+
+check:
+    assert(read_socket(sock, buff, 2) > 0);
+    if (buff[0] == 'O' && buff[1] == 'K')
+        exit(EXIT_SUCCESS);
+    else
+        exit(EXIT_FAILURE);
+}
+
 noreturn void
 add__(struct lkt_cmd_args *args)
 {
@@ -486,7 +519,7 @@ add__(struct lkt_cmd_args *args)
         fail("Invalid argument, the add command should takes at least two arguments");
 
     if (!lkt_valid_type(args->argv[0]))
-        fail("Invalid argument, the type given to the add command is invalid\n");
+        fail("Invalid argument, the type given to the add command is invalid");
 
     FILE *sock = lkt_connect();
 
@@ -681,6 +714,7 @@ static struct lkt_cmd_opt options_[] = {
     { .name = "clear",      .call = clear__   },
     { .name = "current",    .call = current__ },
     { .name = "play",       .call = play__    },
+    { .name = "delete",     .call = delete__  },
     { .name = "next",       .call = next__    },
     { .name = "previous",   .call = prev__    },
     { .name = "queue",      .call = list__    },
diff --git a/src/net/listen.c b/src/net/listen.c
index d42e68ffd5973791b9665e9c2bcf73282570daa4..58b2743261ccb31c37f0f414f2e9868858abd834 100644
--- a/src/net/listen.c
+++ b/src/net/listen.c
@@ -208,12 +208,9 @@ handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd)
             err = !command_add(srv->db, &srv->win, cmd.args, &srv->mpd_idle_events);
         else if (!strcmp(cmd.name, "addid"))
             err = !command_addid(srv->db, &srv->win, cmd.args, &srv->mpd_idle_events);
-        else if (!strcmp(cmd.name, "delete"))
-            err = ! (cmd.args[0] != NULL &&
-                     command_del(srv->db, &srv->win, cmd.args[0], &srv->mpd_idle_events));
         else if (!strcmp(cmd.name, "deleteid"))
             err = ! (cmd.args[0] != NULL &&
-                     command_del(srv->db, &srv->win, cmd.args[0], &srv->mpd_idle_events));
+                     command_delid(srv->db, &srv->win, cmd.args[0], &srv->mpd_idle_events));
 
         else if (!strcmp(cmd.name, "playlistclear"))
             err = ! command_plt_clear(srv->db, cmd.args, &srv->mpd_idle_events);