diff --git a/cubicweb_s3storage/storages.py b/cubicweb_s3storage/storages.py
index 8c41ae0c2e502caa74f688c92ebce846399b6f92_Y3ViaWN3ZWJfczNzdG9yYWdlL3N0b3JhZ2VzLnB5..3e07e7b1b10aee73b45581fe63dfd92d6c629d58_Y3ViaWN3ZWJfczNzdG9yYWdlL3N0b3JhZ2VzLnB5 100644
--- a/cubicweb_s3storage/storages.py
+++ b/cubicweb_s3storage/storages.py
@@ -86,4 +86,6 @@
             self.entity_deleted(entity, attr)
         else:
             oldkey = self.get_s3_key(entity, attr)
+            if oldkey is not None:
+                oldkey, _ = self.parse_key(oldkey)
             key = self.new_s3_key(entity, attr)
@@ -89,8 +91,4 @@
             key = self.new_s3_key(entity, attr)
-            # save S3 key
-            entity.cw_edited.edited_attribute(
-                attr, Binary(key.encode('utf-8')))
-
             # copy Binary value, workaround for boto3 bug
             # https://github.com/boto/s3transfer/issues/80
             # .read() is required since Binary can't wrap itself
@@ -103,8 +101,8 @@
                 upload_key = key
             extra_args = self.get_upload_extra_args(entity, attr, key)
 
-            s3_object = self.bucket.put_object(
-                    Body=buffer,
-                    Key=upload_key,
-                    **extra_args)
+            put_object_result = self.s3cnx.put_object(Body=buffer,
+                                                      Bucket=self.bucket,
+                                                      Key=upload_key,
+                                                      **extra_args)
             buffer.close()
@@ -110,4 +108,7 @@
             buffer.close()
+            version_id = put_object_result.get('VersionId', None)
+            # save S3 key
+            entity = self.save_s3_key(entity, attr, upload_key, version_id)
 
             # when key is suffixed, move to final key in post commit event
             # remove temporary key on rollback
@@ -133,7 +134,7 @@
 
     def entity_deleted(self, entity, attr):
         """an entity using this storage for attr has been deleted"""
-        key = self.get_s3_key(entity, attr)
+        key, _ = self.parse_key(self.get_s3_key(entity, attr))
         if key is None:
             # no key to remove
             return
@@ -160,6 +161,31 @@
             source.doexec(cnx, sql, attrs)
         entity.cw_edited = None
 
+    def save_s3_key(self, entity, attr, key, version_id=None):
+        """
+        Save the s3 key into the entity bytes attribute
+        """
+        id_string = key
+        if entity._cw.repo.config['s3-activate-object-versioning'] and \
+           version_id is not None:
+            id_string = self.format_version_id_suffix(key, version_id)
+        entity.cw_edited.edited_attribute(attr,
+                                          Binary(id_string.encode('utf-8')))
+        return entity
+
+    def parse_key(self, key):
+        try:
+            key, version = key.rsplit(self.KEY_SEPARATOR, 1)
+        except ValueError:
+            return key, None
+        return key, version
+
+    def format_version_id_suffix(self, key, version_id):
+        """
+        Format the string that will store key and version id
+        """
+        return f"{key}#{version_id}"
+
     def get_s3_key(self, entity, attr):
         """
         Return the S3 key of the S3 object storing the content of attribute