diff --git a/mercurial/configitems.py b/mercurial/configitems.py
index aaececb4b0668d5750be70cdea9f44681c8ba6e9_bWVyY3VyaWFsL2NvbmZpZ2l0ZW1zLnB5..1fac9b931d4617f1ea6bc76a9c25fd3d4308ad29_bWVyY3VyaWFsL2NvbmZpZ2l0ZW1zLnB5 100644
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -992,6 +992,9 @@
 coreconfigitem('storage', 'revlog.reuse-external-delta-parent',
     default=None,
 )
+coreconfigitem('storage', 'revlog.zlib.level',
+    default=None,
+)
 coreconfigitem('server', 'bookmarks-pushkey-compat',
     default=True,
 )
diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
index aaececb4b0668d5750be70cdea9f44681c8ba6e9_bWVyY3VyaWFsL2hlbHAvY29uZmlnLnR4dA==..1fac9b931d4617f1ea6bc76a9c25fd3d4308ad29_bWVyY3VyaWFsL2hlbHAvY29uZmlnLnR4dA== 100644
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -1881,6 +1881,11 @@
     This option is enabled by default. When disabled, it also disables the
     related ``storage.revlog.reuse-external-delta-parent`` option.
 
+``revlog.zlib.level``
+    Zlib compression level used when storing data into the repository. Accepted
+    Value range from 1 (lowest compression) to 9 (highest compression). Zlib
+    default value is 6.
+
 ``server``
 ----------
 
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
index aaececb4b0668d5750be70cdea9f44681c8ba6e9_bWVyY3VyaWFsL2xvY2FscmVwby5weQ==..1fac9b931d4617f1ea6bc76a9c25fd3d4308ad29_bWVyY3VyaWFsL2xvY2FscmVwby5weQ== 100644
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -797,6 +797,12 @@
         if r.startswith(b'exp-compression-'):
             options[b'compengine'] = r[len(b'exp-compression-'):]
 
+    options[b'zlib.level'] = ui.configint(b'storage', b'revlog.zlib.level')
+    if options[b'zlib.level'] is not None:
+        if not (0 <= options[b'zlib.level'] <= 9):
+            msg = _('invalid value for `storage.revlog.zlib.level` config: %d')
+            raise error.Abort(msg % options[b'zlib.level'])
+
     if repository.NARROW_REQUIREMENT in requirements:
         options[b'enableellipsis'] = True
 
diff --git a/mercurial/revlog.py b/mercurial/revlog.py
index aaececb4b0668d5750be70cdea9f44681c8ba6e9_bWVyY3VyaWFsL3JldmxvZy5weQ==..1fac9b931d4617f1ea6bc76a9c25fd3d4308ad29_bWVyY3VyaWFsL3JldmxvZy5weQ== 100644
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -371,6 +371,7 @@
         self._nodecache = {nullid: nullrev}
         self._nodepos = None
         self._compengine = 'zlib'
+        self._compengineopts = {}
         self._maxdeltachainspan = -1
         self._withsparseread = False
         self._sparserevlog = False
@@ -416,6 +417,8 @@
             self._lazydeltabase = bool(opts.get('lazydeltabase', False))
         if 'compengine' in opts:
             self._compengine = opts['compengine']
+        if 'zlib.level' in opts:
+            self._compengineopts['zlib.level'] = opts['zlib.level']
         if 'maxdeltachainspan' in opts:
             self._maxdeltachainspan = opts['maxdeltachainspan']
         if self._mmaplargeindex and 'mmapindexthreshold' in opts:
@@ -526,7 +529,8 @@
 
     @util.propertycache
     def _compressor(self):
-        return util.compengines[self._compengine].revlogcompressor()
+        engine = util.compengines[self._compengine]
+        return engine.revlogcompressor(self._compengineopts)
 
     def _indexfp(self, mode='r'):
         """file object for the revlog's index file"""
@@ -1981,7 +1985,7 @@
         except KeyError:
             try:
                 engine = util.compengines.forrevlogheader(t)
-                compressor = engine.revlogcompressor()
+                compressor = engine.revlogcompressor(self._compengineopts)
                 self._decompressors[t] = compressor
             except KeyError:
                 raise error.RevlogError(_('unknown compression type %r') % t)
diff --git a/mercurial/utils/compression.py b/mercurial/utils/compression.py
index aaececb4b0668d5750be70cdea9f44681c8ba6e9_bWVyY3VyaWFsL3V0aWxzL2NvbXByZXNzaW9uLnB5..1fac9b931d4617f1ea6bc76a9c25fd3d4308ad29_bWVyY3VyaWFsL3V0aWxzL2NvbXByZXNzaW9uLnB5 100644
--- a/mercurial/utils/compression.py
+++ b/mercurial/utils/compression.py
@@ -505,7 +505,10 @@
                                          stringutil.forcebytestr(e))
 
     def revlogcompressor(self, opts=None):
-        return self.zlibrevlogcompressor()
+        level = None
+        if opts is not None:
+            level = opts.get('zlib.level')
+        return self.zlibrevlogcompressor(level)
 
 compengines.register(_zlibengine())
 
diff --git a/tests/test-repo-compengines.t b/tests/test-repo-compengines.t
index aaececb4b0668d5750be70cdea9f44681c8ba6e9_dGVzdHMvdGVzdC1yZXBvLWNvbXBlbmdpbmVzLnQ=..1fac9b931d4617f1ea6bc76a9c25fd3d4308ad29_dGVzdHMvdGVzdC1yZXBvLWNvbXBlbmdpbmVzLnQ= 100644
--- a/tests/test-repo-compengines.t
+++ b/tests/test-repo-compengines.t
@@ -82,3 +82,59 @@
       0x78 (x)  : 199 (100.00%)
 
 #endif
+
+checking zlib options
+=====================
+
+  $ hg init zlib-level-default
+  $ hg init zlib-level-1
+  $ cat << EOF >> zlib-level-1/.hg/hgrc
+  > [storage]
+  > revlog.zlib.level=1
+  > EOF
+  $ hg init zlib-level-9
+  $ cat << EOF >> zlib-level-9/.hg/hgrc
+  > [storage]
+  > revlog.zlib.level=9
+  > EOF
+
+
+  $ commitone() {
+  >    repo=$1
+  >    cp $RUNTESTDIR/bundles/issue4438-r1.hg $repo/a
+  >    hg -R $repo add $repo/a
+  >    hg -R $repo commit -m some-commit
+  > }
+
+  $ for repo in zlib-level-default zlib-level-1 zlib-level-9; do
+  >     commitone $repo
+  > done
+
+  $ $RUNTESTDIR/f -s */.hg/store/data/*
+  zlib-level-1/.hg/store/data/a.i: size=4146
+  zlib-level-9/.hg/store/data/a.i: size=4138
+  zlib-level-default/.hg/store/data/a.i: size=4138
+
+Test error cases
+
+  $ hg init zlib-level-invalid
+  $ cat << EOF >> zlib-level-invalid/.hg/hgrc
+  > [storage]
+  > revlog.zlib.level=foobar
+  > EOF
+  $ commitone zlib-level-invalid
+  abort: storage.revlog.zlib.level is not a valid integer ('foobar')
+  abort: storage.revlog.zlib.level is not a valid integer ('foobar')
+  [255]
+
+  $ hg init zlib-level-out-of-range
+  $ cat << EOF >> zlib-level-out-of-range/.hg/hgrc
+  > [storage]
+  > revlog.zlib.level=42
+  > EOF
+
+  $ commitone zlib-level-out-of-range
+  abort: invalid value for `storage.revlog.zlib.level` config: 42
+  abort: invalid value for `storage.revlog.zlib.level` config: 42
+  [255]
+