diff --git a/mercurial/configitems.py b/mercurial/configitems.py
--- a/mercurial/configitems.py
+++ b/mercurial/configitems.py
@@ -941,6 +941,9 @@
 coreconfigitem('push', 'pushvars.server',
     default=False,
 )
+coreconfigitem('storage', 'new-repo-backend',
+    default='revlogv1',
+)
 coreconfigitem('storage', 'revlog.optimize-delta-parent-choice',
     default=True,
     alias=[('format', 'aggressivemergedeltas')],
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -2808,14 +2808,26 @@
 def islocal(path):
     return True
 
-def newreporequirements(ui, createopts=None):
+def defaultcreateopts(ui, createopts=None):
+    """Populate the default creation options for a repository.
+
+    A dictionary of explicitly requested creation options can be passed
+    in. Missing keys will be populated.
+    """
+    createopts = dict(createopts or {})
+
+    if 'backend' not in createopts:
+        # experimental config: storage.new-repo-backend
+        createopts['backend'] = ui.config('storage', 'new-repo-backend')
+
+    return createopts
+
+def newreporequirements(ui, createopts):
     """Determine the set of requirements for a new local repository.
 
     Extensions can wrap this function to specify custom requirements for
     new repositories.
     """
-    createopts = createopts or {}
-
     # If the repo is being created from a shared repository, we copy
     # its requirements.
     if 'sharedrepo' in createopts:
@@ -2827,6 +2839,14 @@
 
         return requirements
 
+    if 'backend' not in createopts:
+        raise error.ProgrammingError('backend key not present in createopts; '
+                                     'was defaultcreateopts() called?')
+
+    if createopts['backend'] != 'revlogv1':
+        raise error.Abort(_('unable to determine repository requirements for '
+                            'storage backend: %s') % createopts['backend'])
+
     requirements = {'revlogv1'}
     if ui.configbool('format', 'usestore'):
         requirements.add('store')
@@ -2885,6 +2905,7 @@
     they know how to handle.
     """
     known = {
+        'backend',
         'narrowfiles',
         'sharedrepo',
         'sharedrelative',
@@ -2901,6 +2922,8 @@
 
     The following keys for ``createopts`` are recognized:
 
+    backend
+       The storage backend to use.
     narrowfiles
        Set up repository to support narrow file storage.
     sharedrepo
@@ -2912,7 +2935,7 @@
     shareditems
        Set of items to share to the new repository (in addition to storage).
     """
-    createopts = createopts or {}
+    createopts = defaultcreateopts(ui, createopts=createopts)
 
     unknownopts = filterknowncreateopts(ui, createopts)
 
diff --git a/mercurial/upgrade.py b/mercurial/upgrade.py
--- a/mercurial/upgrade.py
+++ b/mercurial/upgrade.py
@@ -199,7 +199,8 @@
 
     @staticmethod
     def _newreporequirements(ui):
-        return localrepo.newreporequirements(ui)
+        return localrepo.newreporequirements(
+            ui, localrepo.defaultcreateopts(ui))
 
     @classmethod
     def fromrepo(cls, repo):
@@ -747,7 +748,8 @@
 
     # FUTURE there is potentially a need to control the wanted requirements via
     # command arguments or via an extension hook point.
-    newreqs = localrepo.newreporequirements(repo.ui)
+    newreqs = localrepo.newreporequirements(
+        repo.ui, localrepo.defaultcreateopts(repo.ui))
     newreqs.update(preservedrequirements(repo))
 
     noremovereqs = (repo.requirements - newreqs -