diff --git a/src/api.js b/src/api.js
index 2b324942ccc5b643b84ed1df7036cefda26217cb..cb1a088dd1616b2dbfe7c311d659f709f85d5a75 100644
--- a/src/api.js
+++ b/src/api.js
@@ -302,5 +302,79 @@ export const api = {
     } catch (error) {
       return null
     }
+  },
+  async postModel (model) {
+    const url = this.$serverurl + 'models'
+    const token = await localStorage.getItem('token')
+    try {
+      const response = await fetch(url, {
+        method: 'POST',
+        headers: {
+          Accept: 'application/json',
+          'Content-Type': 'application/json',
+          Authorization: 'Bearer ' + token
+        },
+        body: JSON.stringify({
+          name: model.name,
+          shortDescription: model.shortDescription,
+          longDescription: model.longDescription,
+          performance: model.performance,
+          performanceUnit: model.performanceUnit,
+          parameterCount: model.parameterCount,
+          tags: model.tags
+        })
+      })
+      return await response.json()
+    } catch (error) {
+      return null
+    }
+  },
+  async putModel (id, model) {
+    const url = serverurl + 'models' + '?id=' + id
+    const token = await localStorage.getItem('token')
+    const response = await fetch(url, {
+      method: 'PUT',
+      headers: {
+        Accept: 'application/json',
+        'Content-Type': 'application/json',
+        Authorization: 'Bearer ' + token
+      },
+      body: JSON.stringify({
+        name: model.name,
+        shortDescription: model.shortDescription,
+        longDescription: model.longDescription,
+        performance: model.performance,
+        performanceUnit: model.performanceUnit,
+        parameterCount: model.parameterCount,
+        tags: model.tags
+      })
+    })
+    try {
+      return await response.json()
+    } catch (error) {
+      return null
+    }
+  },
+  async uploadModelFile (id, file) {
+    const data = new FormData()
+    const url = serverurl + 'models/upload'
+    const token = await localStorage.getItem('token')
+
+    data.append('file', file)
+    data.append('id', id)
+
+    try {
+      const response = await fetch(url, {
+        method: 'POST',
+        headers: {
+          Authorization: 'Bearer ' + token
+        },
+        body: data
+      })
+      if (response.status !== 200) return false
+      return true
+    } catch (error) {
+      return false
+    }
   }
 }
diff --git a/src/components/MarkdownEditor.vue b/src/components/MarkdownEditor.vue
index 24798291d48282509eda207cc5b901febfbd625d..42d3660a51cfaff9d3c49ec91d1e4047b392035a 100644
--- a/src/components/MarkdownEditor.vue
+++ b/src/components/MarkdownEditor.vue
@@ -2,7 +2,7 @@
   <div class="markdownEditor container">
     <b-tabs>
       <b-tab-item label="Edit" class="edit">
-        <b-input type="textarea" v-model="input"/>
+        <b-input type="textarea" v-model="input" maxlength="5000"/>
       </b-tab-item>
 
       <b-tab-item label="Preview">
diff --git a/src/components/ModelUpdate.vue b/src/components/ModelUpdate.vue
new file mode 100644
index 0000000000000000000000000000000000000000..ee91af24b8c83c7fce186752dbe2133ecdc7e3ae
--- /dev/null
+++ b/src/components/ModelUpdate.vue
@@ -0,0 +1,154 @@
+<template>
+  <div class="modal-card">
+    <b-progress :value="progress" size="is-large" show-value :type="status">
+      {{statusMessage}}
+    </b-progress>
+    <b-progress v-if="subProgress" size="is-large">
+      {{subMessage}}
+    </b-progress>
+    <b-button
+     v-if="progress === 100"
+     type="is-success"
+     tag="router-link"
+     :to="{ name: 'Model', query: { id: model.id } }"
+    >
+    Go to model page
+    </b-button>
+  </div>
+</template>
+
+<script>
+import { api } from '@/api.js'
+
+export default {
+  name: 'ModelUpdate',
+  props: {
+    model: {
+      type: Object,
+      default: function () {
+        return {}
+      }
+    }
+  },
+  data () {
+    return {
+      progress: 0,
+      status: 'is-primary',
+      statusMessage: '',
+      subProgress: false,
+      subMessage: '',
+      modelId: null
+    }
+  },
+  mounted () {
+    this.saveModel()
+  },
+  methods: {
+    preCheck () {
+      if (this.model.name === undefined || this.model.name === null || this.model.name === '') {
+        this.setError('The model name is empty')
+        return false
+      }
+
+      return true
+    },
+    setProgress (step) {
+      switch (step) {
+        case 0:
+          this.statusMessage = 'Sending description'
+          this.progress = 25
+          break
+        case 1:
+          this.statusMessage = 'Sending model file'
+          this.progress = 50
+          break
+        case 2:
+          this.statusMessage = 'Sending custom layers model'
+          this.progress = 75
+          break
+        case 3:
+          this.statusMessage = 'Update completed !'
+          this.progress = 100
+          this.status = 'is-success'
+          break
+      }
+    },
+    setError (message) {
+      this.statusMessage = message
+      this.status = 'is-danger'
+    },
+    setSubMessage (message) {
+      this.subMessage = message
+    },
+    async saveModel () {
+      if (!this.preCheck()) return
+      this.setProgress(0)
+      var response = await api.putModel(this.model.id, this.model)
+      if (response.error) {
+        this.setError(response.message)
+        return
+      } else {
+        this.modelId = response.message
+      }
+
+      if (this.model.file !== undefined) {
+        console.log('Upload model ' + this.model.file)
+        this.setProgress(1)
+        if (!await api.uploadModelFile(this.model.id, this.model.file)) {
+          this.setError('Model upload error')
+          return
+        }
+      }
+
+      if (this.model.customLayers !== undefined) {
+        console.log('Upload layers ' + this.model.customLayers)
+        this.setProgress(2)
+        if (!await this.uploadLayers()) {
+          this.setError('Custom layer upload error')
+          return
+        }
+      }
+
+      this.setProgress(3)
+    },
+    async uploadLayers () {
+      this.subProgress = true
+      const token = await localStorage.getItem('token')
+      for (var i = 0; i < this.model.customLayers.length; i++) {
+        const layer = this.model.customLayers[i]
+        const data = new FormData()
+        const url = this.$serverurl + 'models/uploadLayer'
+
+        this.subMessage = 'Uploading ' + layer.name
+
+        console.log('Uploading layer ' + i + ' | ' + layer.file)
+        if (layer.file === undefined) continue
+        if (layer.name === undefined) continue
+
+        data.append('file', layer.file)
+        data.append('name', layer.name)
+        data.append('id', this.modelId)
+
+        try {
+          const response = await fetch(url, {
+            method: 'POST',
+            headers: {
+              Authorization: 'Bearer ' + token
+            },
+            body: data
+          })
+          if (response.status !== 200) return false
+        } catch (error) {
+          return false
+        }
+      }
+      this.subProgress = false
+      return true
+    }
+  }
+}
+</script>
+
+<style>
+
+</style>
diff --git a/src/components/ModelUpload.vue b/src/components/ModelUpload.vue
index 1d1e304ad2ff49e9dc7f9d9e9fac8c7f09cd6595..8f451e4316424cbaf72c2f5551ec1168aa1a2475 100644
--- a/src/components/ModelUpload.vue
+++ b/src/components/ModelUpload.vue
@@ -18,6 +18,8 @@
 </template>
 
 <script>
+import { api } from '@/api.js'
+
 export default {
   name: 'ModelUpload',
   props: {
@@ -42,6 +44,14 @@ export default {
     this.saveModel()
   },
   methods: {
+    preCheck () {
+      if (this.model.name === undefined || this.model.name === null || this.model.name === '') {
+        this.setError('The model name is empty')
+        return false
+      }
+
+      return true
+    },
     setProgress (step) {
       switch (step) {
         case 0:
@@ -71,8 +81,9 @@ export default {
       this.subMessage = message
     },
     async saveModel () {
+      if (!this.preCheck()) return
       this.setProgress(0)
-      var response = await this.uploadModel()
+      var response = await api.postModel(this.model)
       if (response.error) {
         this.setError(response.message)
         return
@@ -83,7 +94,7 @@ export default {
       if (this.model.file !== undefined) {
         console.log('Upload model ' + this.model.file)
         this.setProgress(1)
-        if (!await this.uploadModelFile()) {
+        if (!await api.uploadModelFile(this.modelId, this.model.file)) {
           this.setError('Model upload error')
           return
         }
@@ -100,54 +111,6 @@ export default {
 
       this.setProgress(3)
     },
-    async uploadModel () {
-      const url = this.$serverurl + 'models'
-      const token = await localStorage.getItem('token')
-      try {
-        const response = await fetch(url, {
-          method: 'POST',
-          headers: {
-            Accept: 'application/json',
-            'Content-Type': 'application/json',
-            Authorization: 'Bearer ' + token
-          },
-          body: JSON.stringify({
-            name: this.model.name,
-            shortDescription: this.model.shortDescription,
-            longDescription: this.model.longDescription,
-            performance: this.model.performance,
-            performanceUnit: this.model.performanceUnit,
-            parameterCount: this.model.parameterCount,
-            tags: this.model.tags
-          })
-        })
-        return await response.json()
-      } catch (error) {
-        return null
-      }
-    },
-    async uploadModelFile () {
-      const data = new FormData()
-      const url = this.$serverurl + 'models/upload'
-      const token = await localStorage.getItem('token')
-
-      data.append('file', this.model.file)
-      data.append('id', this.modelId)
-
-      try {
-        const response = await fetch(url, {
-          method: 'POST',
-          headers: {
-            Authorization: 'Bearer ' + token
-          },
-          body: data
-        })
-        if (response.status !== 200) return false
-        return true
-      } catch (error) {
-        return false
-      }
-    },
     async uploadLayers () {
       this.subProgress = true
       const token = await localStorage.getItem('token')
diff --git a/src/components/ModelValidator.vue b/src/components/ModelValidator.vue
deleted file mode 100644
index d100af2e24a9f1b19fa8938fe07c76586b0a2552..0000000000000000000000000000000000000000
--- a/src/components/ModelValidator.vue
+++ /dev/null
@@ -1,38 +0,0 @@
-<template>
-  <div class="modelValidator">
-
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'ModelValidator',
-  props: {
-    model: {
-      type: Object,
-      default: function () {
-        return {}
-      }
-    }
-  },
-  data () {
-    return {
-      errorMessage: ''
-    }
-  },
-  methods: {
-    validate () {
-      if (this.model.name === undefined || this.model.name === null || this.model.name === '') {
-        this.errorMessage = 'The model name is empty'
-        return false
-      }
-
-      return true
-    }
-  }
-}
-</script>
-
-<style>
-
-</style>
diff --git a/src/views/Model.vue b/src/views/Model.vue
index bee31850496dae3eb98445aec406f368d7d192dc..c147cc3994ae8316ba1138ded1da2c3a84893dde 100644
--- a/src/views/Model.vue
+++ b/src/views/Model.vue
@@ -31,9 +31,14 @@
           <small>{{model.performanceUnit}}: </small><strong>{{model.performance}}</strong>
           <br>
           <br>
-          <b-button v-if="model.checksum" type="is-primary" size="is-medium" icon-left="download">
-            Download model
-          </b-button>
+          <div v-if="model.checksum">
+            <b-button v-if="model.checksum" type="is-primary" size="is-medium" icon-left="download">
+              Download model
+            </b-button>
+            <br>
+            <br>
+            <small>Checksum: {{model.checksum}}</small>
+          </div>
           <h2 v-else class="title is-5">No file provided</h2>
           <hr>
           <strong>{{model.customLayers.length}} customs layers</strong>
diff --git a/src/views/ModelAdd.vue b/src/views/ModelAdd.vue
index 9acae99427ec4c358de2cffbb7787c0d84b47863..ea3716f577354bec04993295da213e6e49d3b52f 100644
--- a/src/views/ModelAdd.vue
+++ b/src/views/ModelAdd.vue
@@ -3,7 +3,7 @@
     <b-steps v-model="activeStep">
       <b-step-item step="1" label="Description" clickable>
         <b-field label="Model name">
-          <b-input maxlength="30" size="is-large" v-model="model.name"/>
+          <b-input minlength="3" maxlength="100" size="is-large" v-model="model.name"/>
         </b-field>
 
         <b-field label="Short description">
@@ -16,13 +16,13 @@
 
         <b-field label="Performance">
           <b-field>
-            <b-input type="number" placeholder="98" step="0.01" v-model="model.performance"/>
-            <b-autocomplete open-on-focus placeholder="accuracy" :data="performanceTypes" v-model="model.performanceUnit"/>
+            <b-input type="number" placeholder="98" max="10000000" step="0.01" v-model="model.performance"/>
+            <b-autocomplete open-on-focus placeholder="accuracy" :data="performanceTypes" v-model="model.performanceUnit" maxlength="50"/>
           </b-field>
         </b-field>
 
         <b-field label="Number of parameters">
-          <b-input type="number" min="0" placeholder="0" v-model="model.parameterCount"/>
+          <b-input type="number" min="0" max="10000000" placeholder="0" v-model="model.parameterCount"/>
         </b-field>
       </b-step-item>
 
diff --git a/src/views/ModelEdit.vue b/src/views/ModelEdit.vue
index 87b39ebf0e9007b54c97d6c08c1d40c02e6d8b28..5b1f89af37a11d122cdfe464ed0484e9cb349343 100644
--- a/src/views/ModelEdit.vue
+++ b/src/views/ModelEdit.vue
@@ -1,73 +1,76 @@
 <template>
   <div class="modelEdit container">
     <div class="box">
-      <h1 class="title">Model name</h1>
-      <b-field>
-        <b-input maxlength="30" size="is-large" v-model="model.name"/>
-      </b-field>
-
-      <hr>
-      <h1 class="title">Description</h1>
-      <b-field label="Short description">
-        <b-input maxlength="200" type="textarea" v-model="model.shortDescription"/>
-      </b-field>
-
-      <b-field label="Long description">
-        <markdownEditor v-bind:input="model.longDescription" v-on:update-description="model.longDescription = $event"/>
-      </b-field>
+      <b-tabs>
+        <b-tab-item label="Description">
+          <h1 class="title">Description</h1>
+          <b-field label="Model name">
+            <b-input minlength="3" maxlength="100" size="is-large" v-model="model.name"/>
+          </b-field>
 
-      <b-field label="Performance">
-        <b-field>
-          <b-input type="number" placeholder="98" step="0.01" v-model="model.performance"/>
-          <b-autocomplete open-on-focus placeholder="accuracy" :data="performanceTypes" v-model="model.performanceUnit"/>
-        </b-field>
-      </b-field>
+          <b-field label="Short description">
+            <b-input maxlength="200" type="textarea" v-model="model.shortDescription"/>
+          </b-field>
 
-      <b-field label="Number of parameters">
-        <b-input type="number" min="0" placeholder="0" v-model="model.parameterCount"/>
-      </b-field>
+          <b-field label="Long description">
+            <markdownEditor v-bind:input="model.longDescription" v-on:update-description="model.longDescription = $event"/>
+          </b-field>
 
-      <hr>
-      <h1 class="title">Tags</h1>
-      <tagEditor v-bind:modelTags="model.tags" v-on:update-tags="model.tags = $event"/>
+          <b-field label="Performance">
+            <b-field>
+              <b-input type="number" placeholder="98" max="10000000" step="0.01" v-model="model.performance"/>
+              <b-autocomplete open-on-focus placeholder="accuracy" :data="performanceTypes" v-model="model.performanceUnit" maxlength="50"/>
+            </b-field>
+          </b-field>
 
-      <hr>
-      <h1 class="title">Files</h1>
-      <div class="columns">
-        <div class="column">
-          <b-field label="Model">
-            <b-upload v-model="model.file" drag-drop expanded>
-              <section class="section">
-                <div class="content has-text-centered">
-                  <p>
-                    <b-icon icon="upload" size="is-large"/>
-                  </p>
-                  <p>Drop your model here or click to upload</p>
-                </div>
-              </section>
-            </b-upload>
-            <span v-if="model.file" class="file-name">{{ model.file.name }}</span>
+          <b-field label="Number of parameters">
+            <b-input type="number" min="0" max="10000000" placeholder="0" v-model="model.parameterCount"/>
           </b-field>
-        </div>
+        </b-tab-item>
 
-        <div class="column rightColumn">
-          <layersEditor v-bind:layers="model.customLayers" v-on:update-layers="model.customLayers = $event"/>
-        </div>
-      </div>
+        <b-tab-item label="Tags">
+          <h1 class="title">Tags</h1>
+          <tagEditor v-bind:modelTags="model.tags" v-on:update-tags="model.tags = $event"/>
+        </b-tab-item>
 
-    </div>
+        <b-tab-item label="Files">
+          <h1 class="title">Files</h1>
+          <h2 class="subtitle has-text-danger">Uploading files will replace the current files</h2>
+          <div class="columns">
+            <div class="column">
+              <b-field label="Model">
+                <b-upload v-model="model.file" drag-drop expanded>
+                  <section class="section">
+                    <div class="content has-text-centered">
+                      <p>
+                        <b-icon icon="upload" size="is-large"/>
+                      </p>
+                      <p>Drop your model here or click to upload</p>
+                    </div>
+                  </section>
+                </b-upload>
+                <span v-if="model.file" class="file-name">{{ model.file.name }}</span>
+              </b-field>
+            </div>
+            <div class="column rightColumn">
+              <layersEditor v-bind:layers="model.customLayers" v-on:update-layers="model.customLayers = $event"/>
+            </div>
+          </div>
+        </b-tab-item>
 
-    <div class="box">
-      <b-button type="is-danger" @click="removePrompt" expanded>Delete model</b-button>
+        <b-tab-item label="Danger">
+          <b-button type="is-danger" @click="removePrompt" expanded>Delete model</b-button>
+        </b-tab-item>
+      </b-tabs>
     </div>
 
     <div class="box buttons">
       <b-button tag="router-link" :to="{ name: 'Account' }">Cancel</b-button>
-      <b-button type="is-success" @click="openUploadModal">Save</b-button>
+      <b-button type="is-success" @click="openUpdateModal">Save</b-button>
     </div>
 
-    <b-modal :active.sync="isUploadModalActive" has-modal-card trap-focus aria-role="dialog" aria-modal>
-      <ModelUpload v-bind:model="model"/>
+    <b-modal :active.sync="isUpdateModalActive" has-modal-card trap-focus aria-role="dialog" aria-modal>
+      <ModelUpdate v-bind:model="model"/>
     </b-modal>
   </div>
 </template>
@@ -76,7 +79,7 @@
 import markdownEditor from '@/components/MarkdownEditor.vue'
 import tagEditor from '@/components/TagEditor.vue'
 import layersEditor from '@/components/LayersEditor.vue'
-import ModelUpload from '@/components/ModelUpload.vue'
+import ModelUpdate from '@/components/ModelUpdate.vue'
 import { api } from '@/api.js'
 
 export default {
@@ -85,7 +88,7 @@ export default {
     markdownEditor,
     tagEditor,
     layersEditor,
-    ModelUpload
+    ModelUpdate
   },
   props: {
     model: {
@@ -97,7 +100,12 @@ export default {
   },
   data () {
     return {
-      isUploadModalActive: false
+      isUpdateModalActive: false,
+      performanceTypes: [
+        'accuracy',
+        'error rate',
+        'MSE'
+      ]
     }
   },
   mounted () {
@@ -123,6 +131,9 @@ export default {
         hasIcon: true,
         onConfirm: () => api.removeModel(this.model.id)
       })
+    },
+    openUpdateModal () {
+      this.isUpdateModalActive = true
     }
   }
 }