diff --git a/leshan-server-demo/src/main/java/org/eclipse/leshan/server/demo/servlet/ClientServlet.java b/leshan-server-demo/src/main/java/org/eclipse/leshan/server/demo/servlet/ClientServlet.java
index 1c59cd5c0a..7d20d59936 100644
--- a/leshan-server-demo/src/main/java/org/eclipse/leshan/server/demo/servlet/ClientServlet.java
+++ b/leshan-server-demo/src/main/java/org/eclipse/leshan/server/demo/servlet/ClientServlet.java
@@ -76,11 +76,12 @@
 public class ClientServlet extends HttpServlet {
 
     private static final String FORMAT_PARAM = "format";
+    private static final String TIMEOUT_PARAM = "timeout";
     private static final String REPLACE_PARAM = "replace";
 
     private static final Logger LOG = LoggerFactory.getLogger(ClientServlet.class);
 
-    private static final long TIMEOUT = 5000; // ms
+    private static final long DEFAULT_TIMEOUT = 5000; // ms
 
     private static final long serialVersionUID = 1L;
 
@@ -151,7 +152,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Se
                 if (registration != null) {
                     // create & process request
                     DiscoverRequest request = new DiscoverRequest(target);
-                    DiscoverResponse cResponse = server.send(registration, request, TIMEOUT);
+                    DiscoverResponse cResponse = server.send(registration, request, extractTimeout(req));
                     processDeviceResponse(req, resp, cResponse);
                 } else {
                     resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
@@ -176,7 +177,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Se
 
                 // create & process request
                 ReadRequest request = new ReadRequest(contentFormat, target);
-                ReadResponse cResponse = server.send(registration, request, TIMEOUT);
+                ReadResponse cResponse = server.send(registration, request, extractTimeout(req));
                 processDeviceResponse(req, resp, cResponse);
             } else {
                 resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
@@ -239,7 +240,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws Se
                     target = StringUtils.removeEnd(target, path[path.length - 1]);
                     AttributeSet attributes = AttributeSet.parse(req.getQueryString());
                     WriteAttributesRequest request = new WriteAttributesRequest(target, attributes);
-                    WriteAttributesResponse cResponse = server.send(registration, request, TIMEOUT);
+                    WriteAttributesResponse cResponse = server.send(registration, request, extractTimeout(req));
                     processDeviceResponse(req, resp, cResponse);
                 } else {
                     // get content format
@@ -258,7 +259,7 @@ protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws Se
                     LwM2mNode node = extractLwM2mNode(target, req);
                     WriteRequest request = new WriteRequest(replace ? Mode.REPLACE : Mode.UPDATE, contentFormat, target,
                             node);
-                    WriteResponse cResponse = server.send(registration, request, TIMEOUT);
+                    WriteResponse cResponse = server.send(registration, request, extractTimeout(req));
                     processDeviceResponse(req, resp, cResponse);
                 }
             } else {
@@ -292,7 +293,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
 
                     // create & process request
                     ObserveRequest request = new ObserveRequest(contentFormat, target);
-                    ObserveResponse cResponse = server.send(registration, request, TIMEOUT);
+                    ObserveResponse cResponse = server.send(registration, request, extractTimeout(req));
                     processDeviceResponse(req, resp, cResponse);
                 } else {
                     resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
@@ -312,7 +313,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
                 Registration registration = server.getRegistrationService().getByEndpoint(clientEndpoint);
                 if (registration != null) {
                     ExecuteRequest request = new ExecuteRequest(target, IOUtils.toString(req.getInputStream()));
-                    ExecuteResponse cResponse = server.send(registration, request, TIMEOUT);
+                    ExecuteResponse cResponse = server.send(registration, request, extractTimeout(req));
                     processDeviceResponse(req, resp, cResponse);
                 } else {
                     resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
@@ -346,7 +347,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S
                             request = new CreateRequest(contentFormat, target, (LwM2mObjectInstance) node);
                         }
 
-                        CreateResponse cResponse = server.send(registration, request, TIMEOUT);
+                        CreateResponse cResponse = server.send(registration, request, extractTimeout(req));
                         processDeviceResponse(req, resp, cResponse);
                     } else {
                         throw new IllegalArgumentException("payload must contain an object instance");
@@ -391,7 +392,7 @@ protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws
             Registration registration = server.getRegistrationService().getByEndpoint(clientEndpoint);
             if (registration != null) {
                 DeleteRequest request = new DeleteRequest(target);
-                DeleteResponse cResponse = server.send(registration, request, TIMEOUT);
+                DeleteResponse cResponse = server.send(registration, request, extractTimeout(req));
                 processDeviceResponse(req, resp, cResponse);
             } else {
                 resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
@@ -406,7 +407,7 @@ private void processDeviceResponse(HttpServletRequest req, HttpServletResponse r
             throws IOException {
         if (cResponse == null) {
             LOG.warn(String.format("Request %s%s timed out.", req.getServletPath(), req.getPathInfo()));
-            resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            resp.setStatus(HttpServletResponse.SC_GATEWAY_TIMEOUT);
             resp.getWriter().append("Request timeout").flush();
         } else {
             String response = this.gson.toJson(cResponse);
@@ -434,4 +435,20 @@ private LwM2mNode extractLwM2mNode(String target, HttpServletRequest req) throws
         }
         throw new InvalidRequestException("content type %s not supported", req.getContentType());
     }
+
+    private long extractTimeout(HttpServletRequest req) {
+        // get content format
+        String timeoutParam = req.getParameter(TIMEOUT_PARAM);
+        long timeout;
+        if (timeoutParam != null) {
+            try {
+                timeout = Long.parseLong(timeoutParam) * 1000;
+            } catch (NumberFormatException e) {
+                timeout = DEFAULT_TIMEOUT;
+            }
+        } else {
+            timeout = DEFAULT_TIMEOUT;
+        }
+        return timeout;
+    }
 }
diff --git a/leshan-server-demo/src/main/resources/webapp/css/lw-app.css b/leshan-server-demo/src/main/resources/webapp/css/lw-app.css
index 0003c5a500..d89ea0d882 100644
--- a/leshan-server-demo/src/main/resources/webapp/css/lw-app.css
+++ b/leshan-server-demo/src/main/resources/webapp/css/lw-app.css
@@ -221,6 +221,15 @@ body.modal-open,
   	text-overflow: ellipsis;
 }
 
+.btn-info,
+.btn-info:hover,
+.btn-info:active,
+.btn-info:visited,
+.btn-info:focus {
+    background-color: #babdb6;
+    border-color: #babdb6;
+}
+
 /* Sticky footer styles
 -------------------------------------------------- */
 html {
diff --git a/leshan-server-demo/src/main/resources/webapp/js/client-controllers.js b/leshan-server-demo/src/main/resources/webapp/js/client-controllers.js
index 9be38f1db3..3bd54c51a5 100644
--- a/leshan-server-demo/src/main/resources/webapp/js/client-controllers.js
+++ b/leshan-server-demo/src/main/resources/webapp/js/client-controllers.js
@@ -173,6 +173,7 @@ lwClientControllers.controller('ClientDetailCtrl', [
 
         // default format
         $scope.settings={};
+        $scope.settings.timeout = {format:"5s", value:5};
         $scope.settings.multi = {format:"TLV"};
         $scope.settings.single = {format:"TLV"};
 
diff --git a/leshan-server-demo/src/main/resources/webapp/js/helper-services.js b/leshan-server-demo/src/main/resources/webapp/js/helper-services.js
index bc63cb17a2..a0a73cff5d 100644
--- a/leshan-server-demo/src/main/resources/webapp/js/helper-services.js
+++ b/leshan-server-demo/src/main/resources/webapp/js/helper-services.js
@@ -22,24 +22,29 @@ myModule.factory('helper', ["$filter", function($filter) {
   serviceInstance.handleResponse = function (response, lwm2mNode, successCallback) {
       lwm2mNode.date = new Date();
       var formattedDate = $filter('date')(lwm2mNode.date, 'HH:mm:ss.sss');
-      if (!response.valid){
-          lwm2mNode.status = "INVALID";  
-      }else if (response.success){
-          lwm2mNode.status = "SUCCESS";
-      }else {
-          lwm2mNode.status = "ERROR";
-      }
-
-      if (response.valid)
-          lwm2mNode.tooltip = formattedDate + "<br/>" + response.status ;
-      else
-          lwm2mNode.tooltip = formattedDate + "<br/> Not LWM2M Code <br/>" + response.status;
-      
-      if (response.errormessage)
-          lwm2mNode.tooltip = lwm2mNode.tooltip + "<br/>" + response.errormessage;
+      if (response != null){
+          if (!response.valid){
+              lwm2mNode.status = "INVALID";  
+          }else if (response.success){
+              lwm2mNode.status = "SUCCESS";
+          }else {
+              lwm2mNode.status = "ERROR";
+          }
+    
+          if (response.valid)
+              lwm2mNode.tooltip = formattedDate + "<br/>" + response.status ;
+          else
+              lwm2mNode.tooltip = formattedDate + "<br/> Not LWM2M Code <br/>" + response.status;
+          
+          if (response.errormessage)
+              lwm2mNode.tooltip = lwm2mNode.tooltip + "<br/>" + response.errormessage;
 
-      if (successCallback && response.success) {
-          successCallback(formattedDate);
+          if (successCallback && response.success) {
+              successCallback(formattedDate);
+          }
+      } else {
+          lwm2mNode.status = "TIMEOUT";
+          lwm2mNode.tooltip = formattedDate + "<br/>" + lwm2mNode.status ;
       }
   };
   return serviceInstance;
diff --git a/leshan-server-demo/src/main/resources/webapp/js/instance-directives.js b/leshan-server-demo/src/main/resources/webapp/js/instance-directives.js
index 618a58d29c..4119b9c8d5 100644
--- a/leshan-server-demo/src/main/resources/webapp/js/instance-directives.js
+++ b/leshan-server-demo/src/main/resources/webapp/js/instance-directives.js
@@ -41,55 +41,64 @@ angular.module('instanceDirectives', [])
 
             scope.read = function() {
                 var format = scope.settings.multi.format;
+                var timeout = scope.settings.timeout.value;
                 var uri = "api/clients/" + $routeParams.clientId + scope.instance.path;
-                $http.get(uri, {params:{format:format}})
+                $http.get(uri, {params:{format:format, timeout:timeout}})
                 .success(function(data, status, headers, config) {
-                	helper.handleResponse(data, scope.instance.read, function (formattedDate){
-	                    if (data.success && data.content) {
-	                        for(var i in data.content.resources) {
-	                            var tlvresource = data.content.resources[i];
-	                            resource = lwResources.addResource(scope.parent, scope.instance, tlvresource.id, null);
-	                            if("value" in tlvresource) {
-	                                // single value
-	                                resource.value = tlvresource.value;
-	                            }
-	                            else if("values" in tlvresource) {
-	                                // multiple instances
-	                                var tab = new Array();
-	                                for (var j in tlvresource.values) {
-	                                    tab.push(j+"="+tlvresource.values[j]);
-	                                }
-	                                resource.value = tab.join(", ");
-	                            }
-	                            resource.valuesupposed = false;
-	                            resource.tooltip = formattedDate;
-	                        }
-	                    }
-                	});
+                    helper.handleResponse(data, scope.instance.read, function (formattedDate){
+                        if (data.success && data.content) {
+                            for(var i in data.content.resources) {
+                                var tlvresource = data.content.resources[i];
+                                resource = lwResources.addResource(scope.parent, scope.instance, tlvresource.id, null);
+                                if("value" in tlvresource) {
+                                    // single value
+                                    resource.value = tlvresource.value;
+                                }
+                                else if("values" in tlvresource) {
+                                    // multiple instances
+                                    var tab = new Array();
+                                    for (var j in tlvresource.values) {
+                                        tab.push(j+"="+tlvresource.values[j]);
+                                    }
+                                    resource.value = tab.join(", ");
+                                }
+                                resource.valuesupposed = false;
+                                resource.tooltip = formattedDate;
+                            }
+                        }
+                    });
                 }).error(function(data, status, headers, config) {
-                    errormessage = "Unable to read instance " + scope.instance.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
-                    dialog.open(errormessage);
+                    if (status == 504){
+                        helper.handleResponse(null, scope.instance.read);
+                    } else {
+                        errormessage = "Unable to read instance " + scope.instance.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
+                        dialog.open(errormessage);
+                    }
                     console.error(errormessage);
                 });
             };
 
-
             scope.del = function() {
+                var timeout = scope.settings.timeout.value;
                 var uri = "api/clients/" + $routeParams.clientId + scope.instance.path;
-                $http.delete(uri)
+                $http.delete(uri, {params:{timeout:timeout}})
                 .success(function(data, status, headers, config) {
-                	helper.handleResponse(data, scope.instance.del, function (formattedDate){
-	                    // manage delete instance in resource tree.
-	                    if (data.success) {
-	                    	var i = scope.parent.instances.indexOf(scope.instance);
-	                    	if(i != -1) {
-	                    		scope.parent.instances.splice(i, 1);
-	                    	}
-	                    }
-                	});
+                    helper.handleResponse(data, scope.instance.del, function (formattedDate){
+                        // manage delete instance in resource tree.
+                        if (data.success) {
+                            var i = scope.parent.instances.indexOf(scope.instance);
+                            if(i != -1) {
+                                scope.parent.instances.splice(i, 1);
+                            }
+                        }
+                    });
                 }).error(function(data, status, headers, config) {
-                    errormessage = "Unable to delete instance " + scope.instance.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
-                    dialog.open(errormessage);
+                    if (status == 504){
+                        helper.handleResponse(null, scope.instance.del);
+                    } else {
+                        errormessage = "Unable to delete instance " + scope.instance.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
+                        dialog.open(errormessage);
+                    }
                     console.error(errormessage);
                 });
             };
@@ -125,7 +134,8 @@ angular.module('instanceDirectives', [])
                         }
                         // Send request
                         var format = scope.settings.multi.format;
-                        $http({method: 'PUT', url: "api/clients/" + $routeParams.clientId + scope.instance.path, data: payload, headers:{'Content-Type': 'application/json'}, params:{format:format, replace:result.replace}})
+                        var timeout = scope.settings.timeout.value;
+                        $http({method: 'PUT', url: "api/clients/" + $routeParams.clientId + scope.instance.path, data: payload, headers:{'Content-Type': 'application/json'}, params:{format:format, replace:result.replace, timeout:timeout}})
                         .success(function(data, status, headers, config) {
                             helper.handleResponse(data, scope.instance.write, function (formattedDate) {
                                 if (data.success) {
@@ -137,10 +147,14 @@ angular.module('instanceDirectives', [])
                                         resource.tooltip = formattedDate;
                                     }
                                 }
-                        	});
+                            });
                         }).error(function(data, status, headers, config) {
-                            errormessage = "Unable to write resource " + scope.instance.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
-                            dialog.open(errormessage);
+                            if (status == 504){
+                                helper.handleResponse(null, scope.instance.write);
+                            } else {
+                                errormessage = "Unable to write resource " + scope.instance.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
+                                dialog.open(errormessage);
+                            }
                             console.error(errormessage);
                         });
                     });
@@ -149,40 +163,44 @@ angular.module('instanceDirectives', [])
 
             scope.startObserve = function() {
                 var format = scope.settings.multi.format;
+                var timeout = scope.settings.timeout.value;
                 var uri = "api/clients/" + $routeParams.clientId + scope.instance.path+"/observe";
-                $http.post(uri, null, {params:{format:format}})
+                $http.post(uri, null, {params:{format:format, timeout:timeout}})
                 .success(function(data, status, headers, config) {
-                	helper.handleResponse(data, scope.instance.observe, function (formattedDate) {
-	                    if (data.success) {
-	                        scope.instance.observed = true;
-	
-	                        for(var i in data.content.resources) {
-	                            var tlvresource = data.content.resources[i];
-	                            resource = lwResources.addResource(scope.parent, scope.instance, tlvresource.id, null);
-	                            if("value" in tlvresource) {
-	                                // single value
-	                                resource.value = tlvresource.value;
-	                            }
-	                            else if("values" in tlvresource) {
-	                                // multiple instances
-	                                var tab = new Array();
-	                                for (var j in tlvresource.values) {
-	                                    tab.push(j+"="+tlvresource.values[j]);
-	                                }
-	                                resource.value = tab.join(", ");
-	                            }
-	                            resource.valuesupposed = false;
-	                            resource.tooltip = formattedDate;
-	                        }
-	
-	
-	                        scope.instance.valuesupposed = false;
-	                        scope.instance.tooltip = formattedDate;
-	                    }
-                	});
+                    helper.handleResponse(data, scope.instance.observe, function (formattedDate) {
+                        if (data.success) {
+                            scope.instance.observed = true;
+
+                            for(var i in data.content.resources) {
+                                var tlvresource = data.content.resources[i];
+                                resource = lwResources.addResource(scope.parent, scope.instance, tlvresource.id, null);
+                                if("value" in tlvresource) {
+                                    // single value
+                                    resource.value = tlvresource.value;
+                                }
+                                else if("values" in tlvresource) {
+                                    // multiple instances
+                                    var tab = new Array();
+                                    for (var j in tlvresource.values) {
+                                        tab.push(j+"="+tlvresource.values[j]);
+                                    }
+                                    resource.value = tab.join(", ");
+                                }
+                                resource.valuesupposed = false;
+                                resource.tooltip = formattedDate;
+                            }
+
+                            scope.instance.valuesupposed = false;
+                            scope.instance.tooltip = formattedDate;
+                        }
+                    });
                 }).error(function(data, status, headers, config) {
-                    errormessage = "Unable to start observation on instance " + scope.instance.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
-                    dialog.open(errormessage);
+                    if (status == 504){
+                        helper.handleResponse(null, scope.instance.observe);
+                    } else {
+                        errormessage = "Unable to start observation on instance " + scope.instance.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
+                        dialog.open(errormessage);
+                    }
                     console.error(errormessage);
                 });
                 
diff --git a/leshan-server-demo/src/main/resources/webapp/js/object-directives.js b/leshan-server-demo/src/main/resources/webapp/js/object-directives.js
index 6bbf8443a5..2e9ab62d5e 100644
--- a/leshan-server-demo/src/main/resources/webapp/js/object-directives.js
+++ b/leshan-server-demo/src/main/resources/webapp/js/object-directives.js
@@ -65,8 +65,9 @@ angular.module('objectDirectives', [])
                         }
                         // Send request
                         var format = scope.settings.multi.format;
+                        var timeout = scope.settings.timeout.value;
                         var instancepath  = scope.object.path;
-                        $http({method: 'POST', url: "api/clients/" + $routeParams.clientId + instancepath, data: payload, headers:{'Content-Type': 'application/json'}, params:{format:format}})
+                        $http({method: 'POST', url: "api/clients/" + $routeParams.clientId + instancepath, data: payload, headers:{'Content-Type': 'application/json'}, params:{format:format,timeout:timeout}})
                         .success(function(data, status, headers, config) {
                             helper.handleResponse(data, scope.object.create, function (formattedDate) {
                                 if (data.success) {
@@ -82,8 +83,12 @@ angular.module('objectDirectives', [])
                                 }
                             });
                         }).error(function(data, status, headers, config) {
-                            errormessage = "Unable to create instance " + instancepath + " for "+ $routeParams.clientId + " : " + status +" "+ data;
-                            dialog.open(errormessage);
+                            if (status == 504){
+                                helper.handleResponse(null, scope.object.create)
+                            } else {
+                                errormessage = "Unable to create instance " + instancepath + " for "+ $routeParams.clientId + " : " + status +" "+ data;
+                                dialog.open(errormessage);
+                            }
                             console.error(errormessage);
                         });
                     });
diff --git a/leshan-server-demo/src/main/resources/webapp/js/resource-directives.js b/leshan-server-demo/src/main/resources/webapp/js/resource-directives.js
index a898b4ea66..315a450ef0 100644
--- a/leshan-server-demo/src/main/resources/webapp/js/resource-directives.js
+++ b/leshan-server-demo/src/main/resources/webapp/js/resource-directives.js
@@ -67,8 +67,9 @@ angular.module('resourceDirectives', [])
 
             scope.startObserve = function() {
                 var format = scope.settings.single.format;
+                var timeout = scope.settings.timeout.value;
                 var uri = "api/clients/" + $routeParams.clientId + scope.resource.path+"/observe";
-                $http.post(uri, null,{params:{format:format}})
+                $http.post(uri, null,{params:{format:format, timeout:timeout}})
                 .success(function(data, status, headers, config) {
                     helper.handleResponse(data, scope.resource.observe, function (formattedDate){
                         if (data.success) {
@@ -90,13 +91,18 @@ angular.module('resourceDirectives', [])
                         }	
                 	});
                 }).error(function(data, status, headers, config) {
-                    errormessage = "Unable to start observation on resource " + scope.resource.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
-                    dialog.open(errormessage);
+                    if (status == 504){
+                        helper.handleResponse(null, scope.resource.observe);
+                    } else {
+                        errormessage = "Unable to start observation on resource " + scope.resource.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
+                        dialog.open(errormessage);
+                    }
                     console.error(errormessage);
                 });
             };
 
             scope.stopObserve = function() {
+                var timeout = scope.settings.timeout.value;
                 var uri = "api/clients/" + $routeParams.clientId + scope.resource.path + "/observe";
                 $http.delete(uri)
                 .success(function(data, status, headers, config) {
@@ -110,9 +116,10 @@ angular.module('resourceDirectives', [])
             };
 
             scope.read = function() {
+                var timeout = scope.settings.timeout.value;
                 var format = scope.settings.single.format;
                 var uri = "api/clients/" + $routeParams.clientId + scope.resource.path;
-                $http.get(uri, {params:{format:format}})
+                $http.get(uri, {params:{format:format, timeout:timeout}})
                 .success(function(data, status, headers, config) {
                     // manage request information
                     helper.handleResponse(data, scope.resource.read, function (formattedDate){
@@ -134,8 +141,12 @@ angular.module('resourceDirectives', [])
                         }
                     });
                 }).error(function(data, status, headers, config) {
-                    errormessage = "Unable to read resource " + scope.resource.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
-                    dialog.open(errormessage);
+                    if (status == 504){
+                        helper.handleResponse(null, scope.resource.read);
+                    } else { 
+                        errormessage = "Unable to read resource " + scope.resource.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
+                        dialog.open(errormessage);
+                    }
                     console.error(errormessage);
                 });
             };
@@ -159,7 +170,8 @@ angular.module('resourceDirectives', [])
 
                         // Send request
                         var format = scope.settings.multi.format;
-                        $http({method: 'PUT', url: "api/clients/" + $routeParams.clientId + scope.resource.path, data: payload, headers:{'Content-Type': 'application/json'},params:{format:format}})
+                        var timeout = scope.settings.timeout.value;
+                        $http({method: 'PUT', url: "api/clients/" + $routeParams.clientId + scope.resource.path, data: payload, headers:{'Content-Type': 'application/json'},params:{format:format, timeout:timeout}})
                         .success(function(data, status, headers, config) {
                             helper.handleResponse(data, scope.resource.write, function (formattedDate){
                                 if (data.success) {
@@ -169,8 +181,12 @@ angular.module('resourceDirectives', [])
                                 }
                             });
                         }).error(function(data, status, headers, config) {
-                            errormessage = "Unable to write resource " + scope.resource.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
-                            dialog.open(errormessage);
+                            if (status == 504){
+                                helper.handleResponse(null, scope.resource.write);
+                            } else { 
+                                errormessage = "Unable to write resource " + scope.resource.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
+                                dialog.open(errormessage);
+                            }
                             console.error(errormessage);
                         });
                     });
@@ -178,12 +194,17 @@ angular.module('resourceDirectives', [])
             };
 
             scope.exec = function() {
-                $http.post("api/clients/" + $routeParams.clientId+ scope.resource.path)
+                var timeout = scope.settings.timeout.value;
+                $http({method:'POST', url:"api/clients/" + $routeParams.clientId+ scope.resource.path, params:{timeout:timeout}})
                 .success(function(data, status, headers, config) {
-                	helper.handleResponse(data, scope.resource.exec);
+                    helper.handleResponse(data, scope.resource.exec);
                 }).error(function(data, status, headers, config) {
-                    errormessage = "Unable to execute resource " + scope.resource.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
-                    dialog.open(errormessage);
+                    if (status == 504){
+                        helper.handleResponse(null, scope.resource.exec);
+                    } else { 
+                        errormessage = "Unable to execute resource " + scope.resource.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
+                        dialog.open(errormessage);
+                    }
                     console.error(errormessage);
                 });
             };
@@ -198,13 +219,17 @@ angular.module('resourceDirectives', [])
 
                     if(value) {
                         $('#writeModal').modal('hide');
-
-                        $http({method: 'POST', url: "api/clients/" + $routeParams.clientId + scope.resource.path, data: value})
+                        var timeout = scope.settings.timeout.value;
+                        $http({method: 'POST', url: "api/clients/" + $routeParams.clientId + scope.resource.path, data: value, params:{timeout:timeout}})
                         .success(function(data, status, headers, config) {
-                        	helper.handleResponse(data, scope.resource.exec);                            
+                            helper.handleResponse(data, scope.resource.exec);
                         }).error(function(data, status, headers, config) {
-                            errormessage = "Unable to execute resource " + scope.resource.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
-                            dialog.open(errormessage);
+                            if (status == 504){
+                                helper.handleResponse(null, scope.resource.exec);
+                            } else { 
+                                errormessage = "Unable to execute resource " + scope.resource.path + " for "+ $routeParams.clientId + " : " + status +" "+ data;
+                                dialog.open(errormessage);
+                            }
                             console.error(errormessage);
                         });
                     }
diff --git a/leshan-server-demo/src/main/resources/webapp/partials/client-detail.html b/leshan-server-demo/src/main/resources/webapp/partials/client-detail.html
index bab356c10f..6f2ed0d1df 100644
--- a/leshan-server-demo/src/main/resources/webapp/partials/client-detail.html
+++ b/leshan-server-demo/src/main/resources/webapp/partials/client-detail.html
@@ -5,6 +5,19 @@
 
 		<span class="pull-right">
 			<form class="form-inline">
+			<abbr title="Timeout used to send request"><a href="https://github.com/eclipse/leshan/wiki/Request-Timeout" target="_blank"=>Response Timeout</a></abbr>
+			<div class="btn-group" dropdown is-open="timeout.status.isopen">
+				<button type="button" class="btn btn-xs btn-default dropdown-toggle dropdown-menu-contentformat" dropdown-toggle ng-disabled="disabled">
+					{{settings.timeout.format}} <span class="caret"></span>
+				</button>
+				<ul class="dropdown-menu dropdown-menu-contentformat" role="menu">
+					<li><a ng-click="settings.timeout.value=5;settings.timeout.format='5s'">5s</a></li>
+					<li><a ng-click="settings.timeout.value=300;settings.timeout.format='5min'">5min</a></li>
+					<li><a ng-click="settings.timeout.value=900;settings.timeout.format='15min'">15min</a></li>
+					<li><a ng-click="settings.timeout.value=1800;settings.timeout.format='30min'">30min</a></li>
+					<li><a ng-click="settings.timeout.value=undefined;settings.timeout.format='No'">No</a></li>
+				</ul>
+			</div>
 			<abbr title="Content Format used for object, object instance and multi-resource instance">Multi-value</abbr>
 			<div class="btn-group" dropdown is-open="multi.status.isopen">
 				<button type="button" class="btn btn-xs btn-default dropdown-toggle dropdown-menu-contentformat" dropdown-toggle ng-disabled="disabled">
diff --git a/leshan-server-demo/src/main/resources/webapp/partials/instance.html b/leshan-server-demo/src/main/resources/webapp/partials/instance.html
index 1fe6612735..332e9c207c 100644
--- a/leshan-server-demo/src/main/resources/webapp/partials/instance.html
+++ b/leshan-server-demo/src/main/resources/webapp/partials/instance.html
@@ -12,6 +12,7 @@
 								'btn': true,
 								'btn-xs': true,
 								'btn-default': instance.observe.status == null,
+								'btn-info': instance.observe.status == 'TIMEOUT',
 								'btn-danger': instance.observe.status == 'ERROR',
 								'btn-warning': instance.observe.status == 'INVALID',
 								'btn-success': instance.observe.status == 'SUCCESS'}">Observe <span class="glyphicon glyphicon-play"></span></button>
@@ -29,6 +30,7 @@
 								'btn': true,
 								'btn-xs': true,
 								'btn-default': instance.read.status == null,
+								'btn-info': instance.read.status == 'TIMEOUT',
 								'btn-danger': instance.read.status == 'ERROR',
 								'btn-warning': instance.read.status == 'INVALID',
 								'btn-success': instance.read.status == 'SUCCESS'}">Read</button>
@@ -40,6 +42,7 @@
 								'btn': true,
 								'btn-xs': true,
 								'btn-default': instance.write.status == null,
+								'btn-info': instance.write.status == 'TIMEOUT',
 								'btn-danger': instance.write.status == 'ERROR',
 								'btn-warning': instance.write.status == 'INVALID',
 								'btn-success': instance.write.status == 'SUCCESS'}">Write</button>
@@ -51,6 +54,7 @@
 								'btn': true,
 								'btn-xs': true,
 								'btn-default': instance.del.status == null,
+								'btn-info': instance.del.status == 'TIMEOUT',
 								'btn-danger': instance.del.status == 'ERROR',
 								'btn-warning': instance.del.status == 'INVALID',
 								'btn-success': instance.del.status == 'SUCCESS'}">Delete</button>
diff --git a/leshan-server-demo/src/main/resources/webapp/partials/object.html b/leshan-server-demo/src/main/resources/webapp/partials/object.html
index b5011094a9..8823f7c7ee 100644
--- a/leshan-server-demo/src/main/resources/webapp/partials/object.html
+++ b/leshan-server-demo/src/main/resources/webapp/partials/object.html
@@ -19,6 +19,7 @@
 								'btn': true,
 								'btn-xs': true,
 								'btn-default': object.create.status == null,
+								'btn-info': object.create.status == 'TIMEOUT',
 								'btn-danger': object.create.status == 'ERROR',
 								'btn-warning': object.create.status == 'INVALID',
 								'btn-success': object.create.status == 'SUCCESS' }">Create New Instance</button>
diff --git a/leshan-server-demo/src/main/resources/webapp/partials/resource.html b/leshan-server-demo/src/main/resources/webapp/partials/resource.html
index 77aecf5c79..0751f6de15 100644
--- a/leshan-server-demo/src/main/resources/webapp/partials/resource.html
+++ b/leshan-server-demo/src/main/resources/webapp/partials/resource.html
@@ -12,6 +12,7 @@
 								'btn': true,
 								'btn-xs': true,
 								'btn-default': resource.observe.status == null,
+								'btn-info': resource.observe.status == 'TIMEOUT',
 								'btn-danger': resource.observe.status == 'ERROR',
 								'btn-warning': resource.observe.status == 'INVALID',
 								'btn-success': resource.observe.status == 'SUCCESS' }">Observe <span class="glyphicon glyphicon-play"></span></button>
@@ -29,6 +30,7 @@
 								'btn': true,
 								'btn-xs': true,
 								'btn-default': resource.read.status == null,
+								'btn-info': resource.read.status == 'TIMEOUT',
 								'btn-danger': resource.read.status == 'ERROR',
 								'btn-warning': resource.read.status == 'INVALID',
 								'btn-success': resource.read.status == 'SUCCESS' }">Read</button>
@@ -40,6 +42,7 @@
 								'btn': true,
 								'btn-xs': true,
 								'btn-default': resource.write.status == null,
+								'btn-info': resource.write.status == 'TIMEOUT',
 								'btn-danger': resource.write.status == 'ERROR',
 								'btn-warning': resource.write.status == 'INVALID',
 								'btn-success': resource.write.status == 'SUCCESS' }">Write</button>
@@ -51,6 +54,7 @@
 								'btn': true,
 								'btn-xs': true,
 								'btn-default': resource.exec.status == null,
+								'btn-info': resource.exec.status == 'TIMEOUT',
 								'btn-danger': resource.exec.status == 'ERROR',
 								'btn-warning': resource.exec.status == 'INVALID',
 								'btn-success': resource.exec.status == 'SUCCESS' }">Exec</button>
@@ -60,6 +64,7 @@
 								'btn': true,
 								'btn-xs': true,
 								'btn-default': resource.exec.status == null,
+								'btn-info': resource.exec.status == 'TIMEOUT',
 								'btn-danger': resource.exec.status == 'ERROR',
 								'btn-warning': resource.exec.status == 'INVALID',
 								'btn-success': resource.exec.status == 'SUCCESS' }"><span class="glyphicon glyphicon-cog"></span></button>