diff --git a/inc/lektor/commands.h b/inc/lektor/commands.h
index 42708c858d5d6e44fe45ca1388edf53f9af04d4d..7cc63b06322b7af24744adae05506ff149e140ca 100644
--- a/inc/lektor/commands.h
+++ b/inc/lektor/commands.h
@@ -17,6 +17,7 @@
 /* Querying lektor's status */
 bool command_currentsong(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX]);
 bool command_status     (struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX]);
+bool command_stats      (struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX]);
 
 /* Controlling playback */
 bool command_next    (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]);
diff --git a/inc/lektor/database.h b/inc/lektor/database.h
index cef0a11c416826fe65ab6f7c66d946177f1df9ad..e980b680ac3dd7b0026b09492f4f3609826663f6 100644
--- a/inc/lektor/database.h
+++ b/inc/lektor/database.h
@@ -192,7 +192,9 @@ bool database_sticker_delete        (volatile sqlite3 *db, const char *name);
 bool database_sticker_delete_specify(volatile sqlite3 *sb, const char *type, int uri,
                                      const char *name);
 bool database_sticker_set           (volatile sqlite3 *db, const char *type, const char *name,
-                                     int uri,
-                                     int value);
+                                     int uri, int value);
+
+/* Get some stats from the database */
+bool database_stats(volatile sqlite3 *db, int *authors, int *sources, int *karas);
 
 #endif /* __LKT_DATABASE_H__ */
diff --git a/inc/lektor/net.h b/inc/lektor/net.h
index 4ec9c4f89fe62677cf233083548846d8714c7af2..1bfb4c336682b204b12c550ccc4e9ba62aedf1b2 100644
--- a/inc/lektor/net.h
+++ b/inc/lektor/net.h
@@ -60,6 +60,8 @@ struct lkt_state {
 
     struct lkt_module window_mod;
     struct lkt_module repo_mod;
+
+    time_t start_date;
 };
 
 /* Send a message to the connected client. */
diff --git a/src/base/commands.c b/src/base/commands.c
index 65db132a891a3a924f74915d26fca1bdeaf91ee9..98c2ca2374204fe5512fee4603d0ccc1b17a6fd8 100644
--- a/src/base/commands.c
+++ b/src/base/commands.c
@@ -23,7 +23,8 @@ command_restart(struct lkt_state *srv, size_t c,
                 char __attribute__((unused)) *__argv[LKT_MESSAGE_ARGS_MAX])
 {
     const char *const argv[] = { executable_name, NULL };
-    struct lkt_queue_state sta = {0};
+    struct lkt_queue_state sta;
+    memset(&sta, 0, sizeof(struct lkt_queue_state));
     RETURN_UNLESS(lkt_client_auth(srv, c, false), "Failed to authentificate user", false);
     if (!executable_name) {
         LOG_ERROR("GENERAL", "Can't restart if the executable path was not found at start-up");
@@ -116,6 +117,37 @@ command_currentsong(struct lkt_state *srv, size_t c,
     return true;
 }
 
+bool
+command_stats(struct lkt_state *srv, size_t c,
+              char __attribute__((unused)) *args[LKT_MESSAGE_ARGS_MAX])
+{
+    struct lkt_message *out = lkt_message_new();
+    int is_updating = 0, artists = 0, albums = 0, songs = 0;
+    long ts_update  = 0;
+
+    MOD_CALL(srv->repo_mod, "is_updating", &is_updating);
+    database_get_update(srv->db, &ts_update, NULL, NULL);
+    database_stats(srv->db, &artists, &albums, &songs);
+
+    /* TODO: Missing fields:
+     * db_playtime: total time of what can be played with the database (can be
+     *              problematic, needs some work to be done)
+     * playtime:    time already played by lektord (need some modifications of
+     *              the sdl2 module and any player module) */
+    out->data_len = safe_snprintf(out->data, LKT_MESSAGE_MAX,
+                                  "__is_updating: %d\n" /* Custom field here */
+                                  "db_update: %ld\n"
+                                  "uptime: %ld\n"
+                                  "artists: %d\n"       /* Number of authors */
+                                  "albums: %d\n"        /* Number of source names */
+                                  "songs: %d\n",        /* Number of songs */
+                                  is_updating, (uint64_t) ts_update,
+                                  (uint64_t) (time(NULL) - srv->start_date),
+                                  artists, albums, songs);
+    lkt_state_send(srv, c, out);
+    return true;
+}
+
 bool
 command_status(struct lkt_state *srv, size_t c,
                char __attribute__((unused)) *args[LKT_MESSAGE_ARGS_MAX])
@@ -123,13 +155,15 @@ command_status(struct lkt_state *srv, size_t c,
     struct lkt_message *out;
     struct lkt_queue_state queue_state;
     int elapsed, duration, songid = 0;
+    long update_job;
     const char *play_state;
 
     RETURN_UNLESS(srv, "Invalid argument", false);
     RETURN_UNLESS(database_queue_state(srv->db, &queue_state), "Can't get playback status", false);
     database_queue_current_kara(srv->db, NULL, &songid);
-    MOD_CALL(srv->window_mod, "get_elapsed", &elapsed);
+    MOD_CALL(srv->window_mod, "get_elapsed",  &elapsed);
     MOD_CALL(srv->window_mod, "get_duration", &duration);
+    database_get_update(srv->db, NULL, &update_job, NULL);
 
     out = lkt_message_new();
     play_state = queue_state.current <= 0
@@ -146,11 +180,12 @@ command_status(struct lkt_state *srv, size_t c,
                                   "playlistlength: %d\n"
                                   "elapsed: %d\n"
                                   "duration: %d\n"
+                                  "updating_db: %d"
                                   "songid: %d\n",
                                   queue_state.volume, queue_state.repeat, queue_state.random,
                                   queue_state.single, queue_state.consume, play_state,
                                   queue_state.current < 0 ? -1 : queue_state.current - 1,
-                                  queue_state.length, elapsed, duration, songid);
+                                  queue_state.length, elapsed, duration, update_job, songid);
     lkt_state_send(srv, c, out);
     return true;
 }
@@ -210,6 +245,7 @@ command_play(struct lkt_state *srv, char __attribute__((unused)) *args[LKT_MESSA
 {
     char *endptr, err;
     long pos = 1;
+    struct lkt_queue_state queue_state;
 
     /* Argument handle. */
     if (args[0]) {
@@ -217,6 +253,13 @@ command_play(struct lkt_state *srv, char __attribute__((unused)) *args[LKT_MESSA
         RETURN_IF(err, "STRTOL failed", false);
     }
 
+    /* If position is after the queue, don't do anything */
+    RETURN_UNLESS(database_queue_state(srv->db, &queue_state), "Can't get playback status", false);
+    if (queue_state.length <= pos) {
+        LOG_INFO("COMMAND", "Don't perform play command, queue is empty or position is after queue length");
+        return false;
+    }
+
     /* Do the actual job here. */
     database_queue_stop(srv->db);
     RETURN_IF(MOD_CALL(srv->window_mod, "new", &srv->queue, srv->db), "Can't create window", false);
diff --git a/src/database/update.c b/src/database/update.c
index 535174aef55cedaef95fb9fb2572d0e0938353f6..92b82dabc1ea6abd7407c32b1ca7feaa00959f33 100644
--- a/src/database/update.c
+++ b/src/database/update.c
@@ -321,3 +321,27 @@ sqlite_just_exec(database_stamp, "UPDATE misc SET last_update = strftime('%s','n
 sqlite_just_exec(database_updated,
                  "UPDATE misc SET last_end_update = strftime('%s','now'), update_job = update_job + 1;")
 #undef sqlite_just_exec
+
+bool
+database_stats(volatile sqlite3 *db, int *authors, int *sources, int *karas)
+{
+    static const char *SQL =
+        "SELECT"
+        " (SELECT COUNT(DISTINCT author_name) FROM kara),"
+        " (SELECT COUNT(DISTINCT source_name) FROM kara),"
+        " (SELECT COUNT(id) FROM kara);";
+    sqlite3_stmt *stmt = 0;
+
+    SQLITE_PREPARE(db, stmt, SQL, error);
+    SQLITE_STEP_ROW(db, stmt, error);
+
+    *authors = sqlite3_column_int(stmt, 0);
+    *sources = sqlite3_column_int(stmt, 1);
+    *karas   = sqlite3_column_int(stmt, 2);
+
+    sqlite3_finalize(stmt);
+    return true;
+error:
+    sqlite3_finalize(stmt);
+    return false;
+}
diff --git a/src/main/lkt.c b/src/main/lkt.c
index 079a34e1a1f200fc9f8ffd114fe46e15ea8d7581..ade01eadd79185d9367f69b4c35b7467a26e1155 100644
--- a/src/main/lkt.c
+++ b/src/main/lkt.c
@@ -488,61 +488,91 @@ status__(struct cmd_args *args)
         fail("Invalid argument, the status command takes no arguments");
 
     static const char *const status_str__ = "status\n";
-    int ret = EXIT_FAILURE, it = 0;
+    static const char *const stats_str__  = "stats\n";
 
     char buff[LKT_MESSAGE_MAX];
     char flags[24];
 
-    bool play = false, stopped = true;
-    int time_pos = 0, time_duration = 0, song_index = 0, plt_len = 0;
+    bool play = false, stopped = true, is_updating = false;
+    int time_pos = 0, time_duration = 0, song_index = 0, plt_len = 0, ret = EXIT_FAILURE, it = 0;
+    size_t len;
+    time_t update_ts = 0;
 
     memset(flags, 0, 24 * sizeof(char));
     FILE *sock = lkt_connect();
 
-    /* Get lektor's status. */
+#define assign_flag(str, f)  if (STR_NMATCH(buff, str, len) && (atoi(lkt_skip_key(buff)) == 1)) { flags[it++] = f; continue; }
+#define assign_int(str, var) if (STR_NMATCH(buff, str, len)) { var = (strtoll(lkt_skip_key(buff), NULL, 0)); continue; }
+#define check_end()                                     \
+    if (STR_NMATCH(buff, "OK", 2)) break;               \
+    else if (STR_NMATCH(buff, "ACK", 3)) goto error;
 
+    /* Get lektor's status */
     write_socket(sock, status_str__);
-
-#define assign_flag(str, f)  if (STR_NMATCH(buff, str, len) && (atoi(lkt_skip_key(buff)) == 1)) { flags[it++] = f; continue; }
-#define assign_int(str, var) if (STR_NMATCH(buff, str, len)) { var = (atoi(lkt_skip_key(buff))); continue; }
     for (;;) {
-        memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char));
-        read_socket(sock, buff, LKT_MESSAGE_MAX - 1);
-        size_t len = strcspn(buff, LKT_KEY_VALUE_SEP);
+        len       = read_socket(sock, buff, LKT_MESSAGE_MAX - 1);
+        buff[len] = '\0';
+        len       = strcspn(buff, LKT_KEY_VALUE_SEP);
 
         if (STR_NMATCH(buff, "state", len)) {
             char *it = lkt_skip_key(buff);
-            play = STR_NMATCH(it, "play", 4);
-            stopped = STR_NMATCH(it, "stop", 4);
+            play     = STR_NMATCH(it, "play", 4);
+            stopped  = STR_NMATCH(it, "stop", 4);
             continue;
         }
 
-        assign_flag("random", 'r')
-        assign_flag("repeat", 'l')
-        assign_flag("single", 's')
+        assign_flag("random",  'r')
+        assign_flag("repeat",  'l')
+        assign_flag("single",  's')
         assign_flag("consume", 'c')
 
-        assign_int("elapsed", time_pos)
-        assign_int("duration", time_duration)
-        assign_int("song", song_index)
+        assign_int("elapsed",        time_pos)
+        assign_int("duration",       time_duration)
+        assign_int("song",           song_index)
         assign_int("playlistlength", plt_len)
 
-        /* At this point every key has been parsed. */
-        if (STR_NMATCH(buff, "OK", 2))
-            goto print;
-        else if (STR_NMATCH(buff, "ACK", 3))
-            goto error;
+        check_end()
     }
-#undef assign_flag
-#undef assign_int
 
-print:
+    /* Get lektor's stats */
+    write_socket(sock, stats_str__);
+    for (;;) {
+        len       = read_socket(sock, buff, LKT_MESSAGE_MAX - 1);
+        buff[len] = '\0';
+        len       = strcspn(buff, LKT_KEY_VALUE_SEP);
+
+        assign_int("__is_updating", is_updating)
+        assign_int("db_update",     update_ts)
+
+        check_end()
+    }
+
+    /* End of communication */
     fclose(sock);
 
-    printf("Lektor: %s\nQueue: #%d/%d\nPlayback: %d/%ds\nFlags: %s\n",
+#undef assign_flag
+#undef assign_int
+#undef check_end
+
+    struct tm *p_tm = localtime(&update_ts);
+    len = strftime(buff, LKT_MESSAGE_MAX - 1, "%F %H:%M:%S", p_tm);
+    buff[len] = '\0';
+
+    int  pla_m = time_pos / 60;
+    char pla_s = time_pos % 60;
+    int  dur_m = time_duration / 60;
+    char dur_s = time_duration % 60;
+
+    printf("Lektor: %s\n"
+           "Queue: #%d/%d\n"
+           "Playback: %d:%d/%d:%d\n"
+           "Flags: %s\n"
+           "%s: %s\n",
            play ? "play" : "stopped",
-           song_index + 1, plt_len, time_pos, time_duration,
-           flags[0] ? flags : "(none)");
+           song_index + 1, plt_len,
+           pla_m, pla_s, dur_m, dur_s,
+           flags[0] ? flags : "(none)",
+           is_updating ? "Updating" : "Last update", buff);
 
     /* If there is a kara loaded in mpv, get this kara. */
     if (!stopped) {
diff --git a/src/module/module_repo.c b/src/module/module_repo.c
index e163357ee15744fa0945c68a74421c075c61d933..726d5705902fde9efa12ad6faae95933d3e1497b 100644
--- a/src/module/module_repo.c
+++ b/src/module/module_repo.c
@@ -657,12 +657,29 @@ mod_rescan(va_list *va)
     return 0;
 }
 
+static int
+mod_is_updating(va_list *va)
+{
+    va_list copy;
+    struct module_repo_internal **repo;
+    int *ret;
+    va_copy(copy, *va);
+    repo = (struct module_repo_internal **) va_arg(copy, void **);
+    ret  = va_arg(copy, int *);
+    if (ret == NULL)
+        return 1;
+    *ret = (*repo)->updating;
+    va_end(copy);
+    return 0;
+}
+
 REG_BEGIN(repo_reg)
-REG_ADD_NAMED("new",    mod_new)
-REG_ADD_NAMED("free",   mod_free)
-REG_ADD_NAMED("close",  mod_close)
-REG_ADD_NAMED("update", mod_update)
-REG_ADD_NAMED("rescan", mod_rescan)
+REG_ADD_NAMED("new",         mod_new)
+REG_ADD_NAMED("free",        mod_free)
+REG_ADD_NAMED("close",       mod_close)
+REG_ADD_NAMED("update",      mod_update)
+REG_ADD_NAMED("rescan",      mod_rescan)
+REG_ADD_NAMED("is_updating", mod_is_updating)
 REG_END()
 #if ! defined (LKT_STATIC_MODULE)
     REG_EXPORT(repo_reg)
diff --git a/src/net/listen.c b/src/net/listen.c
index a1f1653d79bf314a012edfb45f886fc39610f03c..0a227239af1257c790507f9183500eeb51a39323 100644
--- a/src/net/listen.c
+++ b/src/net/listen.c
@@ -166,38 +166,40 @@ handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd)
 
         /* Commands that are available if not in idle mode */
         else if (STR_MATCH(cmd.name, "currentsong"))
-            err = !command_currentsong(srv, c, NULL);
+            err = ! command_currentsong(srv, c, NULL);
         else if (STR_MATCH(cmd.name, "status"))
-            err = !command_status(srv, c, NULL);
+            err = ! command_status(srv, c, NULL);
+        else if (STR_MATCH(cmd.name, "stats"))
+            err = ! command_stats(srv, c, NULL);
 
         else if (STR_MATCH(cmd.name, "close"))
-            err = !lkt_close_client(srv, c);
+            err = ! lkt_close_client(srv, c);
         else if (STR_MATCH(cmd.name, "ping"))
             err = 0;
 
         else if (STR_MATCH(cmd.name, "next"))
-            err = !command_next(srv, NULL);
+            err = ! command_next(srv, NULL);
         else if (STR_MATCH(cmd.name, "pause"))
-            err = !command_pause(srv, NULL);
+            err = ! command_pause(srv, NULL);
         else if (STR_MATCH(cmd.name, "previous"))
-            err = !command_previous(srv, NULL);
+            err = ! command_previous(srv, NULL);
         else if (STR_MATCH(cmd.name, "play"))
             err = ! command_play(srv, cmd.args);
         else if (STR_MATCH(cmd.name, "playid"))
             err = ! command_playid(srv, cmd.args);
         else if (STR_MATCH(cmd.name, "stop"))
-            err = !command_stop(srv, NULL);
+            err = ! command_stop(srv, NULL);
         else if (STR_MATCH(cmd.name, "clear"))
-            err = !command_clear(srv, NULL);
+            err = ! command_clear(srv, NULL);
         else if (STR_MATCH(cmd.name, "crop"))
-            err = !command_crop(srv, NULL);
+            err = ! command_crop(srv, NULL);
         else if (STR_MATCH(cmd.name, "moveid"))
-            err = !command_move(srv, cmd.args);
+            err = ! command_move(srv, cmd.args);
         else if (STR_MATCH(cmd.name, "shuffle"))
-            err = !command_shuffle(srv, NULL);
+            err = ! command_shuffle(srv, NULL);
 
         else if (STR_MATCH(cmd.name, "playlist") || STR_MATCH(cmd.name, "playlistinfo"))
-            err = !command_queue_list(srv, c, cmd.args);
+            err = ! command_queue_list(srv, c, cmd.args);
         else if (STR_MATCH(cmd.name, "playlistfind") || STR_MATCH(cmd.name, "playlistsearch"))
             err = ! command_find(srv, c, cmd.args, cmd.cont, database_search_queue_init);
 
@@ -215,7 +217,7 @@ handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd)
         }
 
         else if (STR_MATCH(cmd.name, "help"))
-            err = !command_help(srv, c, NULL);
+            err = ! command_help(srv, c, NULL);
 
         else if (STR_MATCH(cmd.name, "__insert"))
             err = ! command_add(srv, cmd.args, 5);
@@ -253,21 +255,21 @@ handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd)
             err = ! command_plt_ctx(srv, c, cmd.args, cmd.cont);
 
         else if (STR_MATCH(cmd.name, "random"))
-            err = !command_set_playback_option(srv, c, lkt_playback_option_random, cmd.args);
+            err = ! command_set_playback_option(srv, c, lkt_playback_option_random, cmd.args);
         else if (STR_MATCH(cmd.name, "repeat"))
-            err = !command_set_playback_option(srv, c, lkt_playback_option_repeat, cmd.args);
+            err = ! command_set_playback_option(srv, c, lkt_playback_option_repeat, cmd.args);
         else if (STR_MATCH(cmd.name, "setvol"))
-            err = !command_set_playback_option(srv, c, lkt_playback_option_volume, cmd.args);
+            err = ! command_set_playback_option(srv, c, lkt_playback_option_volume, cmd.args);
         else if (STR_MATCH(cmd.name, "single"))
-            err = !command_set_playback_option(srv, c, lkt_playback_option_single, cmd.args);
+            err = ! command_set_playback_option(srv, c, lkt_playback_option_single, cmd.args);
         else if (STR_MATCH(cmd.name, "consume"))
-            err = !command_set_playback_option(srv, c, lkt_playback_option_consume, cmd.args);
+            err = ! command_set_playback_option(srv, c, lkt_playback_option_consume, cmd.args);
 
         else if (STR_MATCH(cmd.name, "password"))
-            err = !command_password(srv, c, cmd.args);
+            err = ! command_password(srv, c, cmd.args);
 
         else if (STR_MATCH(cmd.name, "idle")) {
-            err = !command_idle(srv, c, &cmd);
+            err = ! command_idle(srv, c, &cmd);
             goto end_no_send_status;
         } else if (STR_MATCH(cmd.name, "search") || STR_MATCH(cmd.name, "find"))
             err = ! command_find(srv, c, cmd.args, cmd.cont, database_search_database_init);
@@ -279,10 +281,10 @@ handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd)
     default:
         /* commands available only in idle mode */
         if (STR_MATCH(cmd.name, "idle")) {
-            err = !command_idle(srv, c, &cmd);
+            err = ! command_idle(srv, c, &cmd);
             goto end_no_send_status;
         } else if (STR_MATCH(cmd.name, "noidle"))
-            err = !command_noidle(srv, c);
+            err = ! command_noidle(srv, c);
         else
             err = 2;
 
@@ -798,7 +800,13 @@ lkt_listen(struct lkt_state *srv)
         return;
 
     srv->fds[0].events = POLLIN;
-    srv->fds_len = 1;
+    srv->fds_len       = 1;
+    srv->start_date    = time(NULL);
+
+    if (srv->start_date == (time_t) -1) {
+        LOG_ERROR("FATAL", "Overflow or error on call to time function");
+        exit(EXIT_FAILURE);
+    }
 
     /* Listen */
     for (;;) {