diff --git a/public/language/en_GB/notifications.json b/public/language/en_GB/notifications.json
index b45129b467..5225cffbe6 100644
--- a/public/language/en_GB/notifications.json
+++ b/public/language/en_GB/notifications.json
@@ -13,6 +13,8 @@
 
 	"new_message_from": "New message from <strong>%1</strong>",
 	"upvoted_your_post": "<strong>%1</strong> has upvoted your post.",
+	"moved_your_post": "<strong>%1<strong> has moved your post.",
+	"moved_your_topic": "<strong>%1<strong> has moved your topic.",
 	"favourited_your_post": "<strong>%1</strong> has favourited your post.",
 	"user_flagged_post": "<strong>%1</strong> flagged a post.",
 	"user_posted_to" : "<strong>%1</strong> has posted a reply to: <strong>%2</strong>",
diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js
index 328eda21f2..6b3b51547c 100644
--- a/src/socket.io/posts.js
+++ b/src/socket.io/posts.js
@@ -51,8 +51,11 @@ SocketPosts.reply = function(socket, data, callback) {
 };
 
 SocketPosts.upvote = function(socket, data, callback) {
+	if (!data || !data.pid) {
+		return callback(new Error('[[error:invalid-data]]'));
+	}
 	favouriteCommand('upvote', 'voted', socket, data, callback);
-	sendNotificationToPostOwner(data, socket.uid, 'notifications:upvoted_your_post');
+	SocketPosts.sendNotificationToPostOwner(data.pid, socket.uid, 'notifications:upvoted_your_post');
 };
 
 SocketPosts.downvote = function(socket, data, callback) {
@@ -64,8 +67,11 @@ SocketPosts.unvote = function(socket, data, callback) {
 };
 
 SocketPosts.favourite = function(socket, data, callback) {
+	if (!data || !data.pid) {
+		return callback(new Error('[[error:invalid-data]]'));
+	}
 	favouriteCommand('favourite', 'favourited', socket, data, callback);
-	sendNotificationToPostOwner(data, socket.uid, 'notifications:favourited_your_post');
+	SocketPosts.sendNotificationToPostOwner(data.pid, socket.uid, 'notifications:favourited_your_post');
 };
 
 SocketPosts.unfavourite = function(socket, data, callback) {
@@ -73,7 +79,6 @@ SocketPosts.unfavourite = function(socket, data, callback) {
 };
 
 function favouriteCommand(command, eventName, socket, data, callback) {
-
 	if(data && data.pid && data.room_id) {
 		favourites[command](data.pid, socket.uid, function(err, result) {
 			if (err) {
@@ -90,49 +95,50 @@ function favouriteCommand(command, eventName, socket, data, callback) {
 	}
 }
 
-function sendNotificationToPostOwner(data, fromuid, notification) {
-	if(data && data.pid && fromuid) {
-		posts.getPostFields(data.pid, ['tid', 'uid'], function(err, postData) {
-			if (err) {
-				return;
-			}
+SocketPosts.sendNotificationToPostOwner = function(pid, fromuid, notification) {
+	if(!pid || !fromuid) {
+		return;
+	}
+	posts.getPostFields(pid, ['tid', 'uid'], function(err, postData) {
+		if (err) {
+			return;
+		}
 
-			if (fromuid === parseInt(postData.uid, 10)) {
+		if (fromuid === parseInt(postData.uid, 10)) {
+			return;
+		}
+
+		async.parallel({
+			username: async.apply(user.getUserField, fromuid, 'username'),
+			slug: async.apply(topics.getTopicField, postData.tid, 'slug'),
+			index: async.apply(posts.getPidIndex, pid),
+			postContent: function(next) {
+				async.waterfall([
+					async.apply(posts.getPostField, pid, 'content'),
+					function(content, next) {
+						postTools.parse(content, next);
+					}
+				], next);
+			}
+		}, function(err, results) {
+			if (err) {
 				return;
 			}
 
-			async.parallel({
-				username: async.apply(user.getUserField, fromuid, 'username'),
-				slug: async.apply(topics.getTopicField, postData.tid, 'slug'),
-				index: async.apply(posts.getPidIndex, data.pid),
-				postContent: function(next) {
-					async.waterfall([
-						async.apply(posts.getPostField, data.pid, 'content'),
-						function(content, next) {
-							postTools.parse(content, next);
-						}
-					], next);
-				}
-			}, function(err, results) {
-				if (err) {
-					return;
+			notifications.create({
+				bodyShort: '[[' + notification + ', ' + results.username + ']]',
+				bodyLong: results.postContent,
+				path: nconf.get('relative_path') + '/topic/' + results.slug + '/' + results.index,
+				uniqueId: 'post:' + pid + ':uid:' + fromuid,
+				from: fromuid
+			}, function(err, nid) {
+				if (!err) {
+					notifications.push(nid, [postData.uid]);
 				}
-
-				notifications.create({
-					bodyShort: '[[' + notification + ', ' + results.username + ']]',
-					bodyLong: results.postContent,
-					path: nconf.get('relative_path') + '/topic/' + results.slug + '/' + results.index,
-					uniqueId: 'post:' + data.pid + ':uid:' + fromuid,
-					from: fromuid
-				}, function(err, nid) {
-					if (!err) {
-						notifications.push(nid, [postData.uid]);
-					}
-				});
 			});
 		});
-	}
-}
+	});
+};
 
 SocketPosts.getRawPost = function(socket, pid, callback) {
 	async.waterfall([
diff --git a/src/socket.io/topics.js b/src/socket.io/topics.js
index 4c66db8cb1..20d780923b 100644
--- a/src/socket.io/topics.js
+++ b/src/socket.io/topics.js
@@ -1,17 +1,20 @@
 
 'use strict';
 
-var topics = require('../topics'),
+var nconf = require('nconf'),
+	async = require('async'),
+
+	topics = require('../topics'),
 	categories = require('../categories'),
 	privileges = require('../privileges'),
+	notifications = require('../notifications'),
 	threadTools = require('../threadTools'),
 	websockets = require('./index'),
 	user = require('../user'),
-	db = require('./../database'),
-	meta = require('./../meta'),
+	db = require('../database'),
+	meta = require('../meta'),
 	utils = require('../../public/src/utils'),
-
-	async = require('async'),
+	SocketPosts = require('./posts'),
 
 	SocketTopics = {};
 
@@ -290,7 +293,14 @@ SocketTopics.movePost = function(socket, data, callback) {
 			return callback(err || new Error('[[error:no-privileges]]'));
 		}
 
-		topics.movePostToTopic(data.pid, data.tid, callback);
+		topics.movePostToTopic(data.pid, data.tid, function(err) {
+			if (err) {
+				return callback(err);
+			}
+
+			SocketPosts.sendNotificationToPostOwner(data.pid, socket.uid, 'notifications:moved_your_post');
+			callback();
+		});
 	});
 };
 
@@ -299,7 +309,7 @@ SocketTopics.move = function(socket, data, callback) {
 		return callback(new Error('[[error:invalid-data]]'));
 	}
 
-	async.each(data.tids, function(tid, next) {
+	async.eachLimit(data.tids, 10, function(tid, next) {
 		var oldCid;
 		async.waterfall([
 			function(next) {
@@ -331,11 +341,41 @@ SocketTopics.move = function(socket, data, callback) {
 				tid: tid
 			});
 
+			SocketTopics.sendNotificationToTopicOwner(tid, socket.uid, 'notifications:moved_your_topic');
+
 			next();
 		});
 	}, callback);
 };
 
+
+SocketTopics.sendNotificationToTopicOwner = function(tid, fromuid, notification) {
+	if(!tid || !fromuid) {
+		return;
+	}
+
+	async.parallel({
+		username: async.apply(user.getUserField, fromuid, 'username'),
+		topicData: async.apply(topics.getTopicFields, tid, ['uid', 'slug']),
+	}, function(err, results) {
+		if (err || fromuid === parseInt(results.topicData.uid, 10)) {
+			return;
+		}
+
+		notifications.create({
+			bodyShort: '[[' + notification + ', ' + results.username + ']]',
+			path: nconf.get('relative_path') + '/topic/' + results.topicData.slug,
+			uniqueId: 'topic:' + tid + ':uid:' + fromuid,
+			from: fromuid
+		}, function(err, nid) {
+			if (!err) {
+				notifications.push(nid, [results.topicData.uid]);
+			}
+		});
+	});
+};
+
+
 SocketTopics.moveAll = function(socket, data, callback) {
 	if(!data || !data.cid || !data.currentCid) {
 		return callback(new Error('[[error:invalid-data]]'));