diff --git a/redis.conf b/redis.conf
index 34b755718..4fbbaf7e0 100644
--- a/redis.conf
+++ b/redis.conf
@@ -1827,6 +1827,7 @@ latency-monitor-threshold 0
 #  z     Sorted set commands
 #  x     Expired events (events generated every time a key expires)
 #  e     Evicted events (events generated when a key is evicted for maxmemory)
+#  n     New key events (Note: not included in the 'A' class)
 #  t     Stream commands
 #  d     Module key type events
 #  m     Key-miss events (Note: It is not included in the 'A' class)
diff --git a/src/config.c b/src/config.c
index 3b5d4d349..cb3ff2e45 100644
--- a/src/config.c
+++ b/src/config.c
@@ -2691,7 +2691,7 @@ static int setConfigNotifyKeyspaceEventsOption(standardConfig *config, sds *argv
     }
     int flags = keyspaceEventsStringToFlags(argv[0]);
     if (flags == -1) {
-        *err = "Invalid event class character. Use 'Ag$lshzxeKEtmd'.";
+        *err = "Invalid event class character. Use 'Ag$lshzxeKEtmdn'.";
         return 0;
     }
     server.notify_keyspace_events = flags;
diff --git a/src/db.c b/src/db.c
index d4da756f1..10da1e923 100644
--- a/src/db.c
+++ b/src/db.c
@@ -182,6 +182,7 @@ void dbAdd(redisDb *db, robj *key, robj *val) {
     dictSetVal(db->dict, de, val);
     signalKeyAsReady(db, key, val->type);
     if (server.cluster_enabled) slotToKeyAddEntry(de, db);
+    notifyKeyspaceEvent(NOTIFY_NEW,"new",key,db->id);
 }
 
 /* This is a special version of dbAdd() that is used only when loading
diff --git a/src/notify.c b/src/notify.c
index 28c0048cb..633e35bdc 100644
--- a/src/notify.c
+++ b/src/notify.c
@@ -57,6 +57,7 @@ int keyspaceEventsStringToFlags(char *classes) {
         case 't': flags |= NOTIFY_STREAM; break;
         case 'm': flags |= NOTIFY_KEY_MISS; break;
         case 'd': flags |= NOTIFY_MODULE; break;
+        case 'n': flags |= NOTIFY_NEW; break;
         default: return -1;
         }
     }
@@ -84,6 +85,7 @@ sds keyspaceEventsFlagsToString(int flags) {
         if (flags & NOTIFY_EVICTED) res = sdscatlen(res,"e",1);
         if (flags & NOTIFY_STREAM) res = sdscatlen(res,"t",1);
         if (flags & NOTIFY_MODULE) res = sdscatlen(res,"d",1);
+        if (flags & NOTIFY_NEW) res = sdscatlen(res,"n",1);
     }
     if (flags & NOTIFY_KEYSPACE) res = sdscatlen(res,"K",1);
     if (flags & NOTIFY_KEYEVENT) res = sdscatlen(res,"E",1);
diff --git a/src/server.h b/src/server.h
index 37f7f3d7e..65727cd40 100644
--- a/src/server.h
+++ b/src/server.h
@@ -603,6 +603,7 @@ typedef enum {
 #define NOTIFY_KEY_MISS (1<<11)   /* m (Note: This one is excluded from NOTIFY_ALL on purpose) */
 #define NOTIFY_LOADED (1<<12)     /* module only key space notification, indicate a key loaded from rdb */
 #define NOTIFY_MODULE (1<<13)     /* d, module key space notification */
+#define NOTIFY_NEW (1<<14)        /* n, new key notification */
 #define NOTIFY_ALL (NOTIFY_GENERIC | NOTIFY_STRING | NOTIFY_LIST | NOTIFY_SET | NOTIFY_HASH | NOTIFY_ZSET | NOTIFY_EXPIRED | NOTIFY_EVICTED | NOTIFY_STREAM | NOTIFY_MODULE) /* A flag */
 
 /* Using the following macro you can run code inside serverCron() with the
diff --git a/tests/unit/pubsub.tcl b/tests/unit/pubsub.tcl
index 4435a9b1d..ea8964cf3 100644
--- a/tests/unit/pubsub.tcl
+++ b/tests/unit/pubsub.tcl
@@ -390,4 +390,17 @@ start_server {tags {"pubsub network"}} {
         r config set notify-keyspace-events EA
         assert_equal {AE} [lindex [r config get notify-keyspace-events] 1]
     }
+
+    test "Keyspace notifications: new key test" {
+        r config set notify-keyspace-events En
+        set rd1 [redis_deferring_client]
+        assert_equal {1} [psubscribe $rd1 *]
+        r set foo bar
+        # second set of foo should not cause a 'new' event
+        r set foo baz 
+        r set bar bar
+        assert_equal "pmessage * __keyevent@${db}__:new foo" [$rd1 read]
+        assert_equal "pmessage * __keyevent@${db}__:new bar" [$rd1 read]
+        $rd1 close
+    }
 }