diff --git a/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java b/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
index e5d0b04c54b0fd8652f5d284cb8690eaf14d3acf..8e0178479cfd31a1838d23462a61926458aaa7f6 100644
--- a/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
+++ b/src/main/java/eu/hbp/mip/controllers/ExperimentAPI.java
@@ -103,7 +103,8 @@ public class ExperimentAPI {
     @ApiOperation(value = "Create a transient experiment", response = ExperimentDTO.class)
     @RequestMapping(value = "/transient", method = RequestMethod.POST)
     public ResponseEntity<String> createTransientExperiment(Authentication authentication, @RequestBody ExperimentDTO experimentDTO) {
-        experimentDTO = experimentService.createTransientExperiment(authentication, experimentDTO, new Logger(activeUserService.getActiveUser().getUsername(), "(POST) /experiments/transient"));
+        experimentDTO = experimentService.
+                runTransientExperiment(authentication, experimentDTO, new Logger(activeUserService.getActiveUser().getUsername(), "(POST) /experiments/transient"));
         return new ResponseEntity<>(JsonConverters.convertObjectToJsonString(experimentDTO), HttpStatus.OK);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
index b776b6c46d147e0c146305b4567a0c518b3ea11c..4960f27c44a7f81c5a53dfa5eb811d250b48ab21 100644
--- a/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
+++ b/src/main/java/eu/hbp/mip/repositories/ExperimentRepository.java
@@ -104,7 +104,9 @@ public interface ExperimentRepository extends CrudRepository<ExperimentDAO, UUID
         try {
             save(experimentDAO);
         } catch (Exception e) {
-            logger.LogUserAction( "Attempted to save changes to database but an error ocurred  : " + e.getMessage() + ".");
+            logger.LogUserAction(
+                    "Attempted to save changes to database but an error occurred  : " + e.getMessage() + "."
+            );
             throw new InternalServerError(e.getMessage());
         }
     }
diff --git a/src/main/java/eu/hbp/mip/services/ExperimentService.java b/src/main/java/eu/hbp/mip/services/ExperimentService.java
index 1bd848ed64f22c27c2170a450ca103a723199f0c..8ba1332614bc0941d8dbedfceb31445e8f545751 100644
--- a/src/main/java/eu/hbp/mip/services/ExperimentService.java
+++ b/src/main/java/eu/hbp/mip/services/ExperimentService.java
@@ -1,14 +1,16 @@
 package eu.hbp.mip.services;
 
 import com.google.gson.Gson;
-import com.google.gson.internal.LinkedTreeMap;
 import eu.hbp.mip.models.DAOs.ExperimentDAO;
 import eu.hbp.mip.models.DAOs.UserDAO;
 import eu.hbp.mip.models.DTOs.*;
 import eu.hbp.mip.repositories.ExperimentRepository;
 import eu.hbp.mip.services.Specifications.ExperimentSpecifications;
 import eu.hbp.mip.utils.ClaimUtils;
-import eu.hbp.mip.utils.Exceptions.*;
+import eu.hbp.mip.utils.Exceptions.BadRequestException;
+import eu.hbp.mip.utils.Exceptions.InternalServerError;
+import eu.hbp.mip.utils.Exceptions.NoContent;
+import eu.hbp.mip.utils.Exceptions.UnauthorizedException;
 import eu.hbp.mip.utils.HTTPUtil;
 import eu.hbp.mip.utils.JsonConverters;
 import eu.hbp.mip.utils.Logger;
@@ -19,6 +21,7 @@ import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.domain.Specification;
 import org.springframework.security.core.Authentication;
 import org.springframework.stereotype.Service;
+
 import java.util.*;
 
 
@@ -50,16 +53,16 @@ public class ExperimentService {
     /**
      * The getExperiments will retrieve the experiments from database according to the filters.
      *
-     * @param name       is optional, in case it is required to filter the experiments by name
-     * @param algorithm  is optional, in case it is required to filter the experiments by algorithm name
-     * @param shared     is optional, in case it is required to filter the experiments by shared
-     * @param viewed     is optional, in case it is required to filter the experiments by viewed
-     * @param includeShared     is optional, in case it is required to retrieve the experiment that is shared
-     * @param page       is the page that is required to be retrieve
-     * @param size       is the size of each page
-     * @param orderBy    is the column that is required to ordered by
-     * @param descending is a boolean to determine if the experiments will be order by descending or ascending
-     * @param logger    contains username and the endpoint.
+     * @param name          is optional, in case it is required to filter the experiments by name
+     * @param algorithm     is optional, in case it is required to filter the experiments by algorithm name
+     * @param shared        is optional, in case it is required to filter the experiments by shared
+     * @param viewed        is optional, in case it is required to filter the experiments by viewed
+     * @param includeShared is optional, in case it is required to retrieve the experiment that is shared
+     * @param page          is the page that is required to be retrieve
+     * @param size          is the size of each page
+     * @param orderBy       is the column that is required to ordered by
+     * @param descending    is a boolean to determine if the experiments will be order by descending or ascending
+     * @param logger        contains username and the endpoint.
      * @return a list of mapped experiments
      */
 
@@ -70,16 +73,14 @@ public class ExperimentService {
         if (size > 50)
             throw new BadRequestException("Invalid size input, max size is 50.");
         Specification<ExperimentDAO> spec;
-        if(!authenticationIsEnabled  || ClaimUtils.validateAccessRightsOnExperiments(authentication, logger))
-        {
+        if (!authenticationIsEnabled || ClaimUtils.validateAccessRightsOnExperiments(authentication, logger)) {
             spec = Specification
                     .where(new ExperimentSpecifications.ExperimentWithName(name))
                     .and(new ExperimentSpecifications.ExperimentWithAlgorithm(algorithm))
                     .and(new ExperimentSpecifications.ExperimentWithShared(shared))
                     .and(new ExperimentSpecifications.ExperimentWithViewed(viewed))
                     .and(new ExperimentSpecifications.ExperimentOrderBy(orderBy, descending));
-        }
-        else {
+        } else {
             spec = Specification
                     .where(new ExperimentSpecifications.MyExperiment(user.getUsername()))
                     .or(new ExperimentSpecifications.SharedExperiment(includeShared))
@@ -111,8 +112,8 @@ public class ExperimentService {
     /**
      * The getExperiment will retrieve the experiment from database according to the input uuid
      *
-     * @param uuid     is the id of the experiment to be retrieved
-     * @param logger    contains username and the endpoint.
+     * @param uuid   is the id of the experiment to be retrieved
+     * @param logger contains username and the endpoint.
      * @return the experiment information that was retrieved from the database
      */
     public ExperimentDTO getExperiment(Authentication authentication, String uuid, Logger logger) {
@@ -125,9 +126,9 @@ public class ExperimentService {
         experimentDAO = experimentRepository.loadExperiment(uuid, logger);
         if (
                 !experimentDAO.isShared()
-                && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername())
-                && authenticationIsEnabled
-                && ClaimUtils.validateAccessRightsOnExperiments(authentication, logger)
+                        && !experimentDAO.getCreatedBy().getUsername().equals(user.getUsername())
+                        && authenticationIsEnabled
+                        && ClaimUtils.validateAccessRightsOnExperiments(authentication, logger)
         ) {
             logger.LogUserAction("Accessing Experiment is unauthorized.");
             throw new UnauthorizedException("You don't have access to the experiment.");
@@ -143,7 +144,7 @@ public class ExperimentService {
      *
      * @param authentication is the role of the user
      * @param experimentDTO  is the experiment information
-     * @param logger    contains username and the endpoint.
+     * @param logger         contains username and the endpoint.
      * @return the experiment information which was created
      */
     public ExperimentDTO createExperiment(Authentication authentication, ExperimentDTO experimentDTO, Logger logger) {
@@ -154,7 +155,7 @@ public class ExperimentService {
         // Get the type and name of algorithm
         String algorithmType = experimentDTO.getAlgorithm().getType();
 
-        if(algorithmType == null){
+        if (algorithmType == null) {
             logger.LogUserAction("Please provide algorithm type.");
             throw new BadRequestException("Please provide algorithm type.");
         }
@@ -169,22 +170,22 @@ public class ExperimentService {
         // Run with the appropriate engine
         if (algorithmType.equals("workflow")) {
             logger.LogUserAction("Algorithm runs on Galaxy.");
-            return galaxyService.runGalaxyWorkflow(experimentDTO, logger);
+            return galaxyService.createGalaxyExperiment(experimentDTO, logger);
         } else {
             logger.LogUserAction("Algorithm runs on Exareme.");
-            return createExperiment(experimentDTO, logger);
+            return createSynchronousExperiment(experimentDTO, logger);
         }
     }
 
     /**
-     * The createTransientExperiment will run synchronous a transient experiment into exareme and provide results
+     * Will run synchronously an experiment and return the result
      *
      * @param authentication is the role of the user
      * @param experimentDTO  is the experiment information
-     * @param logger    contains username and the endpoint.
+     * @param logger         contains username and the endpoint.
      * @return the experiment information which was created
      */
-    public ExperimentDTO createTransientExperiment(Authentication authentication, ExperimentDTO experimentDTO, Logger logger) {
+    public ExperimentDTO runTransientExperiment(Authentication authentication, ExperimentDTO experimentDTO, Logger logger) {
 
         //Checking if check (POST) /experiments has proper input.
         checkPostExperimentProperInput(experimentDTO, logger);
@@ -192,7 +193,7 @@ public class ExperimentService {
         // Get the type and name of algorithm
         String algorithmType = experimentDTO.getAlgorithm().getType();
 
-        if(algorithmType.equals("workflow")){
+        if (algorithmType.equals("workflow")) {
             logger.LogUserAction("You can not run workflow algorithms transiently.");
             throw new BadRequestException("You can not run workflow algorithms transiently.");
         }
@@ -206,13 +207,17 @@ public class ExperimentService {
 
         logger.LogUserAction("Completed, returning: " + experimentDTO);
 
-        // Results are stored in the experiment object
-        ExaremeAlgorithmResultDTO exaremeAlgorithmResultDTO = runExperiment(experimentDTO, logger);
+        ExaremeAlgorithmResultDTO exaremeAlgorithmResultDTO = runSynchronousExperiment(experimentDTO, logger);
 
-        logger.LogUserAction("Experiment with uuid: " + experimentDTO.getUuid() + "gave response code: " + exaremeAlgorithmResultDTO.getCode() + " and result: " + exaremeAlgorithmResultDTO.getResult());
+        logger.LogUserAction(
+                "Experiment with uuid: " + experimentDTO.getUuid()
+                        + "gave response code: " + exaremeAlgorithmResultDTO.getCode()
+                        + " and result: " + exaremeAlgorithmResultDTO.getResult()
+        );
 
-        experimentDTO.setResult((exaremeAlgorithmResultDTO.getCode() >= 400) ? null : exaremeAlgorithmResultDTO.getResult());
-        experimentDTO.setStatus((exaremeAlgorithmResultDTO.getCode() >= 400) ? ExperimentDAO.Status.error : ExperimentDAO.Status.success);
+        experimentDTO.setResult(exaremeAlgorithmResultDTO.getResult());
+        experimentDTO.setStatus((exaremeAlgorithmResultDTO.getCode() >= 400)
+                ? ExperimentDAO.Status.error : ExperimentDAO.Status.success);
 
         return experimentDTO;
     }
@@ -222,7 +227,7 @@ public class ExperimentService {
      *
      * @param uuid          is the id of the experiment to be updated
      * @param experimentDTO is the experiment information to be updated
-     * @param logger    contains username and the endpoint.
+     * @param logger        contains username and the endpoint.
      */
     public ExperimentDTO updateExperiment(String uuid, ExperimentDTO experimentDTO, Logger logger) {
         ExperimentDAO experimentDAO;
@@ -264,8 +269,8 @@ public class ExperimentService {
     /**
      * The deleteExperiment will delete an experiment from the database
      *
-     * @param uuid     is the id of the experiment to be deleted
-     * @param logger    contains username and the endpoint.
+     * @param uuid   is the id of the experiment to be deleted
+     * @param logger contains username and the endpoint.
      */
     public void deleteExperiment(String uuid, Logger logger) {
         ExperimentDAO experimentDAO;
@@ -301,49 +306,49 @@ public class ExperimentService {
                         && experimentDTO.getUuid() == null;
 
         if (!properInput) {
-            logger.LogUserAction( "Invalid input.");
+            logger.LogUserAction("Invalid input.");
             throw new BadRequestException("Please provide proper input.");
         }
     }
 
     private void verifyPatchExperimentNonEditableFields(ExperimentDTO experimentDTO, Logger logger) {
-        if (experimentDTO.getUuid() != null ) {
-            logger.LogUserAction( "Uuid is not editable.");
+        if (experimentDTO.getUuid() != null) {
+            logger.LogUserAction("Uuid is not editable.");
             throw new BadRequestException("Uuid is not editable.");
         }
 
-        if (experimentDTO.getAlgorithm() != null ) {
-            logger.LogUserAction( "Algorithm is not editable.");
+        if (experimentDTO.getAlgorithm() != null) {
+            logger.LogUserAction("Algorithm is not editable.");
             throw new BadRequestException("Algorithm is not editable.");
         }
 
         if (experimentDTO.getCreated() != null) {
-            logger.LogUserAction( "Created is not editable.");
+            logger.LogUserAction("Created is not editable.");
             throw new BadRequestException("Created is not editable.");
         }
 
         if (experimentDTO.getCreatedBy() != null) {
-            logger.LogUserAction( "CreatedBy is not editable.");
+            logger.LogUserAction("CreatedBy is not editable.");
             throw new BadRequestException("CreatedBy is not editable.");
         }
 
         if (experimentDTO.getUpdated() != null) {
-            logger.LogUserAction( "Updated is not editable.");
+            logger.LogUserAction("Updated is not editable.");
             throw new BadRequestException("Updated is not editable.");
         }
 
         if (experimentDTO.getFinished() != null) {
-            logger.LogUserAction( "Finished is not editable.");
+            logger.LogUserAction("Finished is not editable.");
             throw new BadRequestException("Finished is not editable.");
         }
 
         if (experimentDTO.getResult() != null) {
-            logger.LogUserAction( "Result is not editable.");
+            logger.LogUserAction("Result is not editable.");
             throw new BadRequestException("Result is not editable.");
         }
 
         if (experimentDTO.getStatus() != null) {
-            logger.LogUserAction( "Status is not editable.");
+            logger.LogUserAction("Status is not editable.");
             throw new BadRequestException("Status is not editable.");
         }
     }
@@ -365,7 +370,7 @@ public class ExperimentService {
      * The getDatasetFromExperimentParameters will retrieve the dataset from the experiment parameters
      *
      * @param experimentDTO is the experiment information
-     * @param logger    contains username and the endpoint.
+     * @param logger        contains username and the endpoint.
      * @return the dataset from the experiment
      */
     private String getDatasetFromExperimentParameters(ExperimentDTO experimentDTO, Logger logger) {
@@ -385,142 +390,175 @@ public class ExperimentService {
         return experimentDatasets;
     }
 
-    private ExaremeAlgorithmResultDTO convertMIPEngineResultToExaremeAlgorithmResult(int code, String result) {
-        MIPEngineAlgorithmResultDTO mipVisualization = JsonConverters.convertJsonStringToObject(result, MIPEngineAlgorithmResultDTO.class);
-        LinkedTreeMap<String,Object> data = new LinkedTreeMap<>();
-        data.put("data", new TabularVisualizationDTO(mipVisualization));
-        data.put("type", "application/vnd.dataresource+json");
-        List<Object> finalObject = new ArrayList<>();
-        finalObject.add(data);
-        return new ExaremeAlgorithmResultDTO(code, finalObject);
+    private List<Object> convertMIPEngineToExaremeAlgorithmResult(
+            MIPEngineAlgorithmResultDTO mipEngineAlgorithmResultDTO
+    ) {
+        Map<String, Object> exaremeResultElement = new HashMap<>();
+        exaremeResultElement.put("data", new TabularVisualizationDTO(mipEngineAlgorithmResultDTO));
+        exaremeResultElement.put("type", "application/vnd.dataresource+json");
+
+        List<Object> exaremeResult = new ArrayList<>();
+        exaremeResult.add(exaremeResultElement);
+        return exaremeResult;
     }
 
     /**
-     * The runExperiment will run the experiment to exareme or MIPEngine.
+     * Creates an experiment and runs it on the background.
+     * Uses the exareme or mip-engine engine that run an experiment synchronously.
      *
      * @param experimentDTO is the request with the experiment information
-     * @return the result of experiment as well as the http status that was retrieved
+     * @param logger        contains username and the endpoint.
+     * @return the experiment information that was retrieved from exareme
      */
-    public ExaremeAlgorithmResultDTO runExperiment(ExperimentDTO experimentDTO, Logger logger) {
+    private ExperimentDTO createSynchronousExperiment(ExperimentDTO experimentDTO, Logger logger) {
 
-        // Algorithm type
-        String algorithmType = experimentDTO.getAlgorithm().getType();
+        logger.LogUserAction("Running the algorithm...");
 
-        // Run the 1st algorithm from the list
-        String algorithmName = experimentDTO.getAlgorithm().getName();
+        ExperimentDAO experimentDAO = experimentRepository.createExperimentInTheDatabase(experimentDTO, activeUserService.getActiveUser(), logger);
+        logger.LogUserAction("Created experiment with uuid :" + experimentDAO.getUuid());
 
-        // Run with the appropriate engine
+        logger.LogUserAction("Starting execution in thread");
+        ExperimentDTO finalExperimentDTO = experimentDTO;
+        new Thread(() -> {
+
+            try {
+                ExaremeAlgorithmResultDTO exaremeAlgorithmResultDTO = runSynchronousExperiment(finalExperimentDTO, logger);
+
+                logger.LogUserAction(
+                        "Experiment with uuid: " + experimentDAO.getUuid()
+                                + " gave response code: " + exaremeAlgorithmResultDTO.getCode()
+                                + " and result: " + exaremeAlgorithmResultDTO.getResult()
+                );
+
+                experimentDAO.setResult(JsonConverters.convertObjectToJsonString(exaremeAlgorithmResultDTO.getResult()));
+                experimentDAO.setStatus((exaremeAlgorithmResultDTO.getCode() >= 400)
+                        ? ExperimentDAO.Status.error : ExperimentDAO.Status.success);
+            } catch (Exception e) {
+                logger.LogUserAction("There was an exception: " + e.getMessage());
+
+                experimentDAO.setStatus(ExperimentDAO.Status.error);
+            }
+
+            experimentRepository.finishExperiment(experimentDAO, logger);
+            logger.LogUserAction("Finished the experiment: " + experimentDAO);
+        }).start();
+
+        experimentDTO = new ExperimentDTO(true, experimentDAO);
+        return experimentDTO;
+    }
+
+    /**
+     * Runs the experiment to exareme or MIPEngine, waiting for the response from them.
+     * Exareme and MIP-Engine do not support async fetching of an algorithm result.
+     *
+     * @param experimentDTO is the request with the experiment information
+     * @return the result of experiment as well as the http status that was retrieved
+     */
+    private ExaremeAlgorithmResultDTO runSynchronousExperiment(ExperimentDTO experimentDTO, Logger logger) {
+        String algorithmType = experimentDTO.getAlgorithm().getType();
         if (algorithmType.equals("mipengine")) {
-            MIPEngineAlgorithmRequestDTO mipEngineAlgorithmRequestDTO = new MIPEngineAlgorithmRequestDTO(experimentDTO.getAlgorithm().getParameters());
-            String body = JsonConverters.convertObjectToJsonString(mipEngineAlgorithmRequestDTO);
-            String url =  mipengineAlgorithmsUrl + "/" + algorithmName.toLowerCase();
-            logger.LogUserAction("url: " + url + ", body: " + body);
-            logger.LogUserAction("Algorithm runs on MIPEngine.");
-            return runMIPEngineExperiment(url, body);
+            return runMIPEngineExperiment(experimentDTO, logger);
         } else {
-            List<ExaremeAlgorithmRequestParamDTO> algorithmParameters
-                    = experimentDTO.getAlgorithm().getParameters();
-            String body = gson.toJson(algorithmParameters);
-            String url = queryExaremeUrl + "/" + algorithmName;
-            logger.LogUserAction("url: " + url + ", body: " + body);
-            logger.LogUserAction("Algorithm runs on Exareme.");
-            return runExaremeExperiment(url, body);
+            return runExaremeExperiment(experimentDTO, logger);
         }
     }
 
-
     /**
-     * The runExaremeExperiment will run to exareme the experiment
+     * The runExaremeExperiment will run an experiment using Exareme
      *
-     * @param url           is the url that contain the results of the experiment
-     * @param body          is the parameters of the algorithm
+     * @param experimentDTO contains the information needed to run the experiment
+     * @param logger        used to log information
      * @return the result of exareme as well as the http status that was retrieved
      */
-    public ExaremeAlgorithmResultDTO runExaremeExperiment(String url, String body) {
+    private ExaremeAlgorithmResultDTO runExaremeExperiment(ExperimentDTO experimentDTO, Logger logger) {
+        String algorithmName = experimentDTO.getAlgorithm().getName();
+        logger.LogUserAction("Starting Exareme algorithm execution, algorithm: " + algorithmName);
 
-        StringBuilder results = new StringBuilder();
-        int code;
+        String algorithmEndpoint = queryExaremeUrl + "/" + algorithmName;
+        List<ExaremeAlgorithmRequestParamDTO> algorithmParameters
+                = experimentDTO.getAlgorithm().getParameters();
+        String algorithmBody = gson.toJson(algorithmParameters);
+        logger.LogUserAction("Exareme algorithm execution. Endpoint: " + algorithmEndpoint);
+        logger.LogUserAction("Exareme algorithm execution. Body: " + algorithmBody);
+
+        StringBuilder requestResponseBody = new StringBuilder();
+        int requestReponseCode;
         try {
-            code = HTTPUtil.sendPost(url, body, results);
+            requestReponseCode = HTTPUtil.sendPost(algorithmEndpoint, algorithmBody, requestResponseBody);
         } catch (Exception e) {
             throw new InternalServerError("Error occurred : " + e.getMessage());
         }
 
         // Results are stored in the experiment object
         ExaremeAlgorithmResultDTO exaremeResult = JsonConverters.convertJsonStringToObject(
-                String.valueOf(results), ExaremeAlgorithmResultDTO.class
+                String.valueOf(requestResponseBody), ExaremeAlgorithmResultDTO.class
         );
-        exaremeResult.setCode(code);
+        exaremeResult.setCode(requestReponseCode);
 
         return exaremeResult;
     }
 
     /**
-     * The runExaremeExperiment will run to exareme the experiment
+     * The runMIPEngineExperiment will run an experiment using the MIP-Engine
      *
-     * @param url           is the url that contain the results of the experiment
-     * @param body          is the parameters of the algorithm
-     * @return the result of exareme as well as the http status that was retrieved
+     * @param experimentDTO contains the information needed to run the experiment
+     * @param logger        is used to log
+     * @return the result of the algorithm
      */
-    public ExaremeAlgorithmResultDTO runMIPEngineExperiment(String url, String body) {
+    private ExaremeAlgorithmResultDTO runMIPEngineExperiment(ExperimentDTO experimentDTO, Logger logger) {
+        String algorithmName = experimentDTO.getAlgorithm().getName();
+        logger.LogUserAction("Starting MIP-Engine algorithm execution, algorithm: " + algorithmName);
 
-        StringBuilder results = new StringBuilder();
-        int code;
+        String algorithmEndpoint = mipengineAlgorithmsUrl + "/" + algorithmName.toLowerCase();
+        MIPEngineAlgorithmRequestDTO mipEngineAlgorithmRequestDTO =
+                new MIPEngineAlgorithmRequestDTO(experimentDTO.getAlgorithm().getParameters());
+        String algorithmBody = JsonConverters.convertObjectToJsonString(mipEngineAlgorithmRequestDTO);
+        logger.LogUserAction("MIP-Engine algorithm execution. Endpoint: " + algorithmEndpoint);
+        logger.LogUserAction("MIP-Engine algorithm execution. Body: " + algorithmBody);
+
+        StringBuilder requestResponseBody = new StringBuilder();
+        int requestResponseCode;
         try {
-            code = HTTPUtil.sendPost(url, body, results);
+            requestResponseCode = HTTPUtil.sendPost(algorithmEndpoint, algorithmBody, requestResponseBody);
         } catch (Exception e) {
-            throw new InternalServerError("Error occurred : " + e.getMessage());
+            logger.LogUserAction("An unexpected error occurred when running a mip experiment: " + e.getMessage());
+            throw new InternalServerError("");
         }
-        System.out.println(results);
-        // Results are stored in the experiment object
-        return convertMIPEngineResultToExaremeAlgorithmResult(code, String.valueOf(results));
-    }
-
-    /* --------------------------------------  EXAREME CALLS ---------------------------------------------------------*/
 
-    /**
-     * The createExaremeExperiment will POST the algorithm to the exareme client
-     *
-     * @param experimentDTO is the request with the experiment information
-     * @param logger    contains username and the endpoint.
-     * @return the experiment information that was retrieved from exareme
-     */
-    public ExperimentDTO createExperiment(ExperimentDTO experimentDTO, Logger logger) {
-
-        logger.LogUserAction("Running the algorithm...");
-
-        ExperimentDAO experimentDAO = experimentRepository.createExperimentInTheDatabase(experimentDTO, activeUserService.getActiveUser(), logger);
-        logger.LogUserAction("Created experiment with uuid :" + experimentDAO.getUuid());
+        List<Object> exaremeAlgorithmResult = new ArrayList<>();
+        if (requestResponseCode == 200) {
+            MIPEngineAlgorithmResultDTO mipEngineAlgorithmResultDTO =
+                    JsonConverters.convertJsonStringToObject(String.valueOf(requestResponseBody), MIPEngineAlgorithmResultDTO.class);
+            exaremeAlgorithmResult = convertMIPEngineToExaremeAlgorithmResult(mipEngineAlgorithmResultDTO);
+
+        } else if (requestResponseCode == 400) {
+            Map<String, Object> exaremeAlgorithmResultElement = new HashMap<>();
+            exaremeAlgorithmResultElement.put("data", String.valueOf(requestResponseBody));
+            exaremeAlgorithmResultElement.put("type", "text/plain+error");
+            exaremeAlgorithmResult.add(exaremeAlgorithmResultElement);
+
+        } else if (requestResponseCode == 460) {
+            Map<String, Object> exaremeAlgorithmResultElement = new HashMap<>();
+            exaremeAlgorithmResultElement.put("data", String.valueOf(requestResponseBody));
+            exaremeAlgorithmResultElement.put("type", "text/plain+user_error");
+            exaremeAlgorithmResult.add(exaremeAlgorithmResultElement);
+
+        } else if (requestResponseCode == 500) {
+            Map<String, Object> exaremeAlgorithmResultElement = new HashMap<>();
+            exaremeAlgorithmResultElement.put("data",
+                    "Something went wrong. Please inform the system administrator or try again later."
+            );
+            exaremeAlgorithmResultElement.put("type", "text/plain+error");
+            exaremeAlgorithmResult.add(exaremeAlgorithmResultElement);
 
-        logger.LogUserAction("Starting execution in thread");
-        ExperimentDTO finalExperimentDTO = experimentDTO;
-        new Thread(() -> {
-
-            // ATTENTION: Inside the Thread only LogExperimentAction should be used, not LogUserAction!
-            Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Thread named :" + Thread.currentThread().getName() + " with id :" + Thread.currentThread().getId() + " started!");
-
-            try {
-
-                // Results are stored in the experiment object
-                ExaremeAlgorithmResultDTO exaremeAlgorithmResultDTO = runExperiment(finalExperimentDTO, logger);
-
-                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Experiment with uuid: " + experimentDAO.getUuid() + "gave response code: " + exaremeAlgorithmResultDTO.getCode() + " and result: " + exaremeAlgorithmResultDTO.getResult());
-
-                experimentDAO.setResult((exaremeAlgorithmResultDTO.getCode() >= 400) ? null : JsonConverters.convertObjectToJsonString(exaremeAlgorithmResultDTO.getResult()));
-                experimentDAO.setStatus((exaremeAlgorithmResultDTO.getCode() >= 400) ? ExperimentDAO.Status.error : ExperimentDAO.Status.success);
-            } catch (Exception e) {
-                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "There was an exception: " + e.getMessage());
+        } else {
+            logger.LogUserAction(
+                    "MIP-Engine execution responded with an unexpected status code: " + requestResponseCode
+            );
+            throw new InternalServerError("");
+        }
 
-                experimentDAO.setStatus(ExperimentDAO.Status.error);
-            }
+        return new ExaremeAlgorithmResultDTO(requestResponseCode, exaremeAlgorithmResult);
 
-            experimentRepository.finishExperiment(experimentDAO, logger);
-            Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Finished the experiment: " + experimentDAO);
-        }).start();
-        experimentDTO = new ExperimentDTO(true, experimentDAO);
-        return experimentDTO;
     }
-
-    /* ---------------------------------------  GALAXY CALLS ---------------------------------------------------------*/
-
 }
diff --git a/src/main/java/eu/hbp/mip/services/GalaxyService.java b/src/main/java/eu/hbp/mip/services/GalaxyService.java
index cc10afebdfdff26008947c6b24b7eb5865e6918b..61d5629fdc0e5ce52845638be65f71b8608574a2 100644
--- a/src/main/java/eu/hbp/mip/services/GalaxyService.java
+++ b/src/main/java/eu/hbp/mip/services/GalaxyService.java
@@ -56,12 +56,12 @@ public class GalaxyService {
     private static final Gson gson = new Gson();
 
     /**
-     * The runWorkflow will POST the algorithm to the galaxy client
+     * Creates an experiment and runs it on Galaxy
      *
      * @param experimentDTO is the request with the experiment information
      * @return the response to be returned
      */
-    public ExperimentDTO runGalaxyWorkflow(ExperimentDTO experimentDTO, Logger logger) {
+    public ExperimentDTO createGalaxyExperiment(ExperimentDTO experimentDTO, Logger logger) {
         logger.LogUserAction("Running a workflow...");
 
         ExperimentDAO experimentDAO = experimentRepository.createExperimentInTheDatabase(experimentDTO, activeUserService.getActiveUser(), logger);
@@ -161,8 +161,8 @@ public class GalaxyService {
         String experimentName = experimentDAO.getName();
         UUID experimentId = experimentDAO.getUuid();
 
-        // ATTENTION: This function is used from a Thread. Only LogExperimentAction should be used, not LogUserAction!
-        Logger.LogExperimentAction(experimentName, experimentId, " History Id : " + historyId);
+        // ATTENTION: This function is used from a Thread. Only LogBackgroundAction should be used, not LogUserAction!
+        Logger.LogBackgroundAction(experimentName, experimentId, " History Id : " + historyId);
 
         // Create the request client
         RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
@@ -172,15 +172,15 @@ public class GalaxyService {
         try {
             Response<Object> response = call.execute();
             if (response.code() >= 400) {
-                Logger.LogExperimentAction(experimentName, experimentId, " Response code: "
+                Logger.LogBackgroundAction(experimentName, experimentId, " Response code: "
                         + response.code() + "" + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
                 return "internalError";
             }
             result = new Gson().toJson(response.body());
-            Logger.LogExperimentAction(experimentName, experimentId, " ResultDTO: " + result);
+            Logger.LogBackgroundAction(experimentName, experimentId, " ResultDTO: " + result);
 
         } catch (IOException e) {
-            Logger.LogExperimentAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
+            Logger.LogBackgroundAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
             return "internalError";
         }
 
@@ -189,11 +189,11 @@ public class GalaxyService {
             JSONObject resultJson = new JSONObject(result);
             state = resultJson.getString("state");
         } catch (JSONException e) {
-            Logger.LogExperimentAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
+            Logger.LogBackgroundAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
             return "internalError";
         }
 
-        Logger.LogExperimentAction(experimentName, experimentId, " Completed!");
+        Logger.LogBackgroundAction(experimentName, experimentId, " Completed!");
         switch (state) {
             case "ok":
                 return "success";
@@ -218,7 +218,7 @@ public class GalaxyService {
         String historyId = experimentDAO.getWorkflowHistoryId();
         String experimentName = experimentDAO.getName();
         UUID experimentId = experimentDAO.getUuid();
-        Logger.LogExperimentAction(experimentName, experimentId, " historyId : " + historyId);
+        Logger.LogBackgroundAction(experimentName, experimentId, " historyId : " + historyId);
 
         RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
         Call<List<GalaxyWorkflowResult>> call = service.getWorkflowResultsFromGalaxy(historyId, galaxyApiKey);
@@ -227,19 +227,19 @@ public class GalaxyService {
         try {
             Response<List<GalaxyWorkflowResult>> response = call.execute();
             if (response.code() >= 400) {
-                Logger.LogExperimentAction(experimentName, experimentId, " Response code: "
+                Logger.LogBackgroundAction(experimentName, experimentId, " Response code: "
                         + response.code() + "" + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
                 return null;
             }
             getGalaxyWorkflowResultList = response.body();
-            Logger.LogExperimentAction(experimentName, experimentId, " ResultDTO: " + response.body());
+            Logger.LogBackgroundAction(experimentName, experimentId, " ResultDTO: " + response.body());
 
         } catch (IOException e) {
-            Logger.LogExperimentAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
+            Logger.LogBackgroundAction(experimentName, experimentId, " An exception happened: " + e.getMessage());
             return null;
         }
 
-        Logger.LogExperimentAction(experimentName, experimentId, " Completed!");
+        Logger.LogBackgroundAction(experimentName, experimentId, " Completed!");
         return getGalaxyWorkflowResultList;
 
     }
@@ -255,7 +255,7 @@ public class GalaxyService {
         String experimentName = experimentDAO.getName();
         UUID experimentId = experimentDAO.getUuid();
 
-        Logger.LogExperimentAction(experimentName, experimentId, " historyId : " + historyId);
+        Logger.LogBackgroundAction(experimentName, experimentId, " historyId : " + historyId);
 
         RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
         Call<Object> call =
@@ -265,20 +265,20 @@ public class GalaxyService {
         try {
             Response<Object> response = call.execute();
             if (response.code() >= 400) {
-                Logger.LogExperimentAction(experimentName, experimentId, " Response code: "
+                Logger.LogBackgroundAction(experimentName, experimentId, " Response code: "
                         + response.code() + "" + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
                 return null;
             }
             resultJson = new Gson().toJson(response.body());
-            Logger.LogExperimentAction(experimentName, experimentId, " ResultDTO: " + resultJson);
+            Logger.LogBackgroundAction(experimentName, experimentId, " ResultDTO: " + resultJson);
 
         } catch (IOException e) {
-            Logger.LogExperimentAction(experimentName, experimentId,
+            Logger.LogBackgroundAction(experimentName, experimentId,
                     " An exception happened: " + e.getMessage());
             return null;
         }
 
-        Logger.LogExperimentAction(experimentName, experimentId, " Completed!");
+        Logger.LogBackgroundAction(experimentName, experimentId, " Completed!");
         return formattingGalaxyResult(resultJson);
     }
 
@@ -300,7 +300,7 @@ public class GalaxyService {
         String experimentName = experimentDAO.getName();
         UUID experimentId = experimentDAO.getUuid();
 
-        Logger.LogExperimentAction(experimentName, experimentId, " jobId : " + jobId);
+        Logger.LogBackgroundAction(experimentName, experimentId, " jobId : " + jobId);
         RetroFitGalaxyClients service = RetrofitClientInstance.getRetrofitInstance().create(RetroFitGalaxyClients.class);
         Call<Object> callError = service.getErrorMessageOfWorkflowFromGalaxy(jobId, galaxyApiKey);
 
@@ -309,7 +309,7 @@ public class GalaxyService {
         try {
             Response<Object> response = callError.execute();
             if (response.code() >= 400) {
-                Logger.LogExperimentAction(experimentName, experimentId, "Response code: "
+                Logger.LogBackgroundAction(experimentName, experimentId, "Response code: "
                         + response.code() + " with body: " + (response.errorBody() != null ? response.errorBody().string() : " "));
                 return null;
             }
@@ -319,19 +319,19 @@ public class GalaxyService {
             JsonElement jsonElement = new JsonParser().parse(jsonString);
             JsonObject rootObject = jsonElement.getAsJsonObject();
             fullError = rootObject.get("stderr").getAsString();
-            Logger.LogExperimentAction(experimentName, experimentId, "Error: " + fullError);
+            Logger.LogBackgroundAction(experimentName, experimentId, "Error: " + fullError);
 
             String[] arrOfStr = fullError.split("ValueError", 0);
             String specError = arrOfStr[arrOfStr.length - 1];
             returnError = specError.substring(1);
-            Logger.LogExperimentAction(experimentName, experimentId, "Parsed Error: " + returnError);
+            Logger.LogBackgroundAction(experimentName, experimentId, "Parsed Error: " + returnError);
 
         } catch (IOException e) {
-            Logger.LogExperimentAction(experimentName, experimentId, "Exception: " + e.getMessage());
+            Logger.LogBackgroundAction(experimentName, experimentId, "Exception: " + e.getMessage());
             return null;
         }
 
-        Logger.LogExperimentAction(experimentName, experimentId, "Completed successfully!");
+        Logger.LogBackgroundAction(experimentName, experimentId, "Completed successfully!");
 
         return returnError;
     }
@@ -358,40 +358,40 @@ public class GalaxyService {
         logger.LogUserAction("Starting Thread...");
         new Thread(() -> {
             while (true) {
-                // ATTENTION: Inside the Thread only LogExperimentAction should be used, not LogExperimentAction!
-                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Thread is running...");
+                // ATTENTION: Inside the Thread only LogBackgroundAction should be used, not LogUserAction!
+                Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Thread is running...");
 
                 try {
                     sleep(2000);
                 } catch (InterruptedException e) {
-                    Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Sleep was disrupted: " + e.getMessage());
+                    Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Sleep was disrupted: " + e.getMessage());
                     throw new InternalServerError(e.getMessage());
                 }
 
-                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Fetching status for experiment Id: " + experimentDAO.getUuid());
+                Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Fetching status for experiment Id: " + experimentDAO.getUuid());
 
                 String state = getWorkflowStatus(experimentDAO);
-                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "State is: " + state);
+                Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "State is: " + state);
 
                 switch (state) {
                     case "pending":
                         // Do nothing, when the experiment is created the status is set to running
-                        Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Workflow is still running.");
+                        Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Workflow is still running.");
                         break;
 
                     case "success":
                         // Get only the job result that is visible
                         List<GalaxyWorkflowResult> workflowJobsResults = getWorkflowResults(experimentDAO);
-                        Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Results are: " + workflowJobsResults.toString());
+                        Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Results are: " + workflowJobsResults.toString());
 
                         boolean resultFound = false;
                         for (GalaxyWorkflowResult jobResult : workflowJobsResults) {
                             if (jobResult.getVisible()) {
-                                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Visible result are: " + jobResult.getId());
+                                Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Visible result are: " + jobResult.getId());
 
                                 String result = getWorkflowResultBody(experimentDAO, jobResult.getId());
 
-                                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO: " + result);
+                                Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO: " + result);
                                 if (result == null) {
                                     experimentDAO.setStatus(ExperimentDAO.Status.error);
                                 } else {
@@ -403,7 +403,7 @@ public class GalaxyService {
                         }
 
                         if (!resultFound) {      // If there is no visible result
-                            Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "No visible result");
+                            Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "No visible result");
                             experimentDAO.setStatus(ExperimentDAO.Status.error);
                         }
 
@@ -413,16 +413,16 @@ public class GalaxyService {
                     case "error":
                         // Get the job result that failed
                         workflowJobsResults = getWorkflowResults(experimentDAO);
-                        Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Error results are: " + workflowJobsResults.toString());
+                        Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Error results are: " + workflowJobsResults.toString());
 
                         boolean failedJobFound = false;
                         for (GalaxyWorkflowResult jobResult : workflowJobsResults) {
                             if (jobResult.getState().equals("error")) {
-                                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Failed job is: " + jobResult.getId());
+                                Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Failed job is: " + jobResult.getId());
 
                                 String result = getWorkflowJobError(jobResult.getId(), experimentDAO);
 
-                                Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "Job result: " + result);
+                                Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "Job result: " + result);
                                 if (result == null) {
                                     experimentDAO.setStatus(ExperimentDAO.Status.error);
                                 }
@@ -432,14 +432,14 @@ public class GalaxyService {
                         }
 
                         if (!failedJobFound) {      // If there is no visible failed job
-                            Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "No failed result");
+                            Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "No failed result");
                             experimentDAO.setStatus(ExperimentDAO.Status.error);
                         }
                         experimentRepository.finishExperiment(experimentDAO, logger);
                         break;
 
                     default:        // InternalError or unexpected result
-                        Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "An unexpected error occurred.");
+                        Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "An unexpected error occurred.");
                         experimentDAO.setStatus(ExperimentDAO.Status.error);
                         experimentRepository.finishExperiment(experimentDAO, logger);
                         break;
@@ -447,7 +447,7 @@ public class GalaxyService {
 
                 // If result exists return
                 if (experimentDAO.getResult() != null) {
-                    Logger.LogExperimentAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO exists: " + experimentDAO.getResult());
+                    Logger.LogBackgroundAction(experimentDAO.getName(), experimentDAO.getUuid(), "ResultDTO exists: " + experimentDAO.getResult());
                     return;
                 }
             }
diff --git a/src/main/java/eu/hbp/mip/utils/Logger.java b/src/main/java/eu/hbp/mip/utils/Logger.java
index 1e25d2c921f0338235bed01c2f2fcd55ab4cf94a..c21e2fdc9391be017fed2b470ff04e11d29a45fd 100644
--- a/src/main/java/eu/hbp/mip/utils/Logger.java
+++ b/src/main/java/eu/hbp/mip/utils/Logger.java
@@ -22,8 +22,8 @@ public class Logger {
                 + "Info ->  " + actionInfo);
     }
 
-    // Used from Threads because threads can't get userName.
-    public static void LogExperimentAction(String experimentName, UUID experimentId, String actionInfo) {
+    // Deprecated, should be removed
+    public static void LogBackgroundAction(String experimentName, UUID experimentId, String actionInfo) {
         LOGGER.info(" Experiment -> " + experimentName
                 + "(" + experimentId + ") ,"
                 + "Info -> " + actionInfo);