diff --git a/pom.xml b/pom.xml
index 540281e9cee73946d66f62e23ce08290b82ce125..947efbb02f791ceee8f27bfe0c99ce92db4a72ef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -292,6 +292,11 @@
 			<artifactId>swagger-annotations</artifactId>
 			<version>1.5.12</version>
 		</dependency>
+		<dependency>
+			<groupId>com.codahale.metrics</groupId>
+			<artifactId>metrics-annotation</artifactId>
+			<version>3.0.2</version>
+		</dependency>
 	</dependencies>
 
 	<build>
@@ -382,11 +387,6 @@
 					</execution>
 				</executions>
 			</plugin>
-			<plugin>
-				<groupId>org.codehaus.mojo</groupId>
-				<artifactId>aspectj-maven-plugin</artifactId>
-				<version>1.9</version>
-			</plugin>
 			<plugin>
 				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-checkstyle-plugin</artifactId>
diff --git a/src/main/java/de/thm/arsnova/services/UserService.java b/src/main/java/de/thm/arsnova/services/UserService.java
index 51edbf0613094d74a7654813524f25550f3006ff..c3ced54d49e613afdc4e5f33250b4cd43655f83d 100644
--- a/src/main/java/de/thm/arsnova/services/UserService.java
+++ b/src/main/java/de/thm/arsnova/services/UserService.java
@@ -17,6 +17,7 @@
  */
 package de.thm.arsnova.services;
 
+import com.codahale.metrics.annotation.Gauge;
 import com.github.leleuj.ss.oauth.client.authentication.OAuthAuthenticationToken;
 import de.thm.arsnova.dao.IDatabaseDao;
 import de.thm.arsnova.entities.DbUser;
@@ -50,6 +51,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Isolation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.util.UriUtils;
+import org.stagemonitor.core.metrics.MonitorGauges;
 
 import javax.annotation.PreDestroy;
 import javax.mail.MessagingException;
@@ -65,6 +67,7 @@ import java.util.regex.Pattern;
  * Performs all user related operations.
  */
 @Service
+@MonitorGauges
 public class UserService implements IUserService {
 
 	private static final int LOGIN_TRY_RESET_DELAY_MS = 30 * 1000;
@@ -325,6 +328,7 @@ public class UserService implements IUserService {
 	}
 
 	@Override
+	@Gauge
 	public int loggedInUsers() {
 		return user2session.size();
 	}
diff --git a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
index 75217e17bbf5c2381a4cd8f5102a04934163f82c..55401f938fc0b3424b925e828161a9dfe8b69d46 100644
--- a/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
+++ b/src/main/java/de/thm/arsnova/socket/ARSnovaSocketIOServer.java
@@ -17,6 +17,8 @@
  */
 package de.thm.arsnova.socket;
 
+import com.codahale.metrics.annotation.Metered;
+import com.codahale.metrics.annotation.Timed;
 import com.corundumstudio.socketio.AckRequest;
 import com.corundumstudio.socketio.Configuration;
 import com.corundumstudio.socketio.SocketConfig;
@@ -131,6 +133,7 @@ public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor {
 
 		server.addEventListener("setFeedback", Feedback.class, new DataListener<Feedback>() {
 			@Override
+			@Timed(name = "setFeedbackEvent.onData")
 			public void onData(final SocketIOClient client, final Feedback data, final AckRequest ackSender) {
 				final User u = userService.getUser2SocketId(client.getSessionId());
 				if (u == null) {
@@ -154,6 +157,7 @@ public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor {
 
 		server.addEventListener("setSession", Session.class, new DataListener<Session>() {
 			@Override
+			@Timed(name = "setSessionEvent.onData")
 			public void onData(final SocketIOClient client, final Session session, final AckRequest ackSender) {
 				final User u = userService.getUser2SocketId(client.getSessionId());
 				if (null == u) {
@@ -183,6 +187,7 @@ public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor {
 				de.thm.arsnova.entities.transport.InterposedQuestion.class,
 				new DataListener<de.thm.arsnova.entities.transport.InterposedQuestion>() {
 			@Override
+			@Timed(name = "readInterposedQuestionEvent.onData")
 			public void onData(
 					SocketIOClient client,
 					de.thm.arsnova.entities.transport.InterposedQuestion question,
@@ -213,6 +218,7 @@ public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor {
 				LearningProgressOptions.class,
 				new DataListener<LearningProgressOptions>() {
 			@Override
+			@Timed(name = "setLearningProgressOptionsEvent.onData")
 			public void onData(SocketIOClient client, LearningProgressOptions progressOptions, AckRequest ack) {
 				final User user = userService.getUser2SocketId(client.getSessionId());
 				final de.thm.arsnova.entities.Session session = sessionService.getSessionInternal(progressOptions.getSessionKeyword(), user);
@@ -226,11 +232,13 @@ public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor {
 
 		server.addConnectListener(new ConnectListener() {
 			@Override
+			@Timed
 			public void onConnect(final SocketIOClient client) { }
 		});
 
 		server.addDisconnectListener(new DisconnectListener() {
 			@Override
+			@Timed
 			public void onDisconnect(final SocketIOClient client) {
 				if (
 						userService == null
@@ -500,6 +508,7 @@ public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor {
 
 	@Async
 	@Override
+	@Timed(name = "visit.NewAnswerEvent")
 	public void visit(NewAnswerEvent event) {
 		final String sessionKey = event.getSession().getKeyword();
 		this.reportAnswersToLecturerQuestionAvailable(event.getSession(), new Question(event.getQuestion()));
@@ -518,6 +527,7 @@ public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor {
 
 	@Async
 	@Override
+	@Timed(name = "visit.DeleteAnswerEvent")
 	public void visit(DeleteAnswerEvent event) {
 		final String sessionKey = event.getSession().getKeyword();
 		this.reportAnswersToLecturerQuestionAvailable(event.getSession(), new Question(event.getQuestion()));
@@ -528,6 +538,7 @@ public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor {
 
 	@Async
 	@Override
+	@Timed(name = "visit.PiRoundDelayedStartEvent")
 	public void visit(PiRoundDelayedStartEvent event) {
 		final String sessionKey = event.getSession().getKeyword();
 		broadcastInSession(sessionKey, "startDelayedPiRound", event.getPiRoundInformations());
@@ -535,6 +546,7 @@ public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor {
 
 	@Async
 	@Override
+	@Timed(name = "visit.PiRoundEndEvent")
 	public void visit(PiRoundEndEvent event) {
 		final String sessionKey = event.getSession().getKeyword();
 		broadcastInSession(sessionKey, "endPiRound", event.getPiRoundEndInformations());
@@ -542,6 +554,7 @@ public class ARSnovaSocketIOServer implements ARSnovaSocket, NovaEventVisitor {
 
 	@Async
 	@Override
+	@Timed(name = "visit.PiRoundCancelEvent")
 	public void visit(PiRoundCancelEvent event) {
 		final String sessionKey = event.getSession().getKeyword();
 		broadcastInSession(sessionKey, "cancelPiRound", event.getQuestionId());
diff --git a/src/main/java/org/stagemonitor/core/metrics/MonitorGauges.java b/src/main/java/org/stagemonitor/core/metrics/MonitorGauges.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e0a25a74e0f899322288173063bca50ffbfadcb
--- /dev/null
+++ b/src/main/java/org/stagemonitor/core/metrics/MonitorGauges.java
@@ -0,0 +1,25 @@
+package org.stagemonitor.core.metrics;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * When a type is marked with this annotation, the creation of gauges with
+ * @{@link com.codahale.metrics.annotation.Gauge} is activated for that type.
+ *
+ * <pre><code>
+ *     \@MonitorGauges
+ *     public class Queue {
+ *         \@Gauge(name = "queueSize")
+ *         public int getQueueSize() {
+ *             return queue.size;
+ *         }
+ *     }
+ * </code></pre>
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MonitorGauges {
+}
diff --git a/src/main/resources/log4j-dev.properties b/src/main/resources/log4j-dev.properties
index cc7b1ff3bd255dd36091cfa89fc5377528d0059e..bae1f9dffd40cb8899c04e8280615aaf9ddf4a71 100644
--- a/src/main/resources/log4j-dev.properties
+++ b/src/main/resources/log4j-dev.properties
@@ -13,3 +13,5 @@ log4j.category.io.netty=INFO
 log4j.category.io.netty.channel.DefaultChannelPipeline=WARN
 log4j.category.net.sf.json=WARN
 log4j.category.org.springframework=INFO
+log4j.category.org.stagemonitor.core=OFF
+log4j.category.org.stagemonitor.requestmonitor=OFF
diff --git a/src/main/resources/stagemonitor.properties b/src/main/resources/stagemonitor.properties
new file mode 100644
index 0000000000000000000000000000000000000000..928b3aa225b7d5d27b06441b9ca3967354d9c32f
--- /dev/null
+++ b/src/main/resources/stagemonitor.properties
@@ -0,0 +1,5 @@
+stagemonitor.active=true
+stagemonitor.applicationName=ARSnova Backend
+stagemonitor.instrument.include=de.thm.arsnova.controller,de.thm.arsnova.services,de.thm.arsnova.socket
+stagemonitor.reporting.interval.console=180
+stagemonitor.web.monitorOnlyForwardedRequests=true
diff --git a/src/main/webapp/WEB-INF/spring/arsnova-servlet.xml b/src/main/webapp/WEB-INF/spring/arsnova-servlet.xml
index 5c9e2a49f688740b5c25869976345f991ff9a3d9..0d9097812adac4376298a23fcb609d8d576c8d6c 100644
--- a/src/main/webapp/WEB-INF/spring/arsnova-servlet.xml
+++ b/src/main/webapp/WEB-INF/spring/arsnova-servlet.xml
@@ -24,6 +24,8 @@
 		<bean class="de.thm.arsnova.web.ResponseInterceptorHandler" />
 	</mvc:interceptors>
 
+	<bean id="requestMappingHandlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" primary="true"></bean>
+
 	<aop:aspectj-autoproxy />
 
 	<!-- Enables swgger ui-->