If you are here, you must be finding the answer for “How to upgrade to Magento 2.3?”. In addition, you are ready to move from your 2.2.x store and upgrade to Magento 2.3Found in this article a stronger & proven “why” for 2.3 upgrade: Why you need Magento 2.3.

As Magento 2.3 is the hottest trend these days, learning Magento 2.3 upgrade is necessary to make a fresh start for your web store. Soon, you will all need to switch to Magento 2.3 because the latest version always provide better supports and features.

In a hurry? There are 4 popular ways to upgrade to Magento 2.3:

If you are wondering where to download Magento 2.3, Magestore also provide a huge resource to download any Magento versions.

Magento 2.3 Upgrade Requirements

You must meet the requirements to install/upgrade Magento 2.3.

1, Operating systems, Web servers, Database and php

To install Magento 2.3, you need a Linux-based operating system (Linux x86-64), such as RedHat Enterprise Linux (RHEL), CentOS, Ubuntu, Debian, and similar.

Also, the Web servers for Magento 2.3 is either Apache 2.2/2.4 or nginx 1.x.

For the Database, Magento 2.3 is compatible with MySQL 5.6 or 5.7, MySQL NDB Cluster 7.4.*, MariaDB 10.0, 10.1, 10.2, Percona 5.7, and other binary-compatible MySQL technologies.

Magento 2.3 only support php 7.1.3 and later, or php 7.2.

If you are reading how to upgrade to Magento 2.3 from Magento 2.2.x version, you can safely pass this step.

2, Version requirement to upgrade

To upgrade to Magento 2.3, you need current version of Magento to be 2.1.4 and later. If you are running a 2.1.3 and earlier version, you must upgrade to version 2.1.4 or later before you continue.

Prerequisites for Magento 2.3 Upgrade

Before running any System upgrade (which includes Magento 2.3 Upgrade), you must complete the task:

1, Set up cron for upgrade

To upgrade your system, you must have two cron jobs. Each cron job should run every minute.

The Magento crontab is inside #~ MAGENTO START and #~ MAGENTO END comments in your crontab.

To create the Magento crontab:

  1. Log in as, or switch to, the Magento file system owner.
  2. Change to your Magento installation directory.
  3. Enter the following command:
    php bin/magento cron:install [--force]

Use –force  to rewrite an existing Magento crontab.

After all, you can view the crontab via command:

crontab -l

2, Set ulimit for the web server user

Magento requires you to set the ulimit for the Magento file system user to a value of 65536 or more.

Why you need to set ulimit? Because a rollback to a previous backup can silently fail, resulting in incomplete data being written to the file system or database.

To set ulimit, you only need to follow this:

  1. Open in a text editor:
  2. Add the following line:
    ulimit -s 65536
  3. Save your changes to .bashrc and exit the text editor.


Magento 2.3 is the unique version with security enhancements that needs converting data from serialized format to JSON encoded format. If you have a large amount of data, you can improve performance by setting the value of an environment variable, DATA_CONVERTER_BATCH_SIZE. By default, it’s set to a value of 50,000.

You can set value for DATA_CONVERTER_BATCH_SIZE in a bash shell prompt:


The value depends on you, we suggest you to set to 10000.

After upgrading to Magento 2.3, you can change back the variable as follows:


Upgrade Magento 2.3 with System Upgrade utility

To run System Upgrade utility:

Step 1Log in to the Magento Admin as administrator.

Step 2Navigate System > Tools > Web Setup Wizard.

magento 2.3 upgrade

Source: Magento.com

Step 3Click System Configuration.

Check your authentication keys in the provided fields if possible. Below is an example if you have already entered your keys.

magento 2.3 upgrade

Source: Magento.com

Step 4Click Save Config.

Step 5Click System Upgrade.

Then, you need Magento to check the readiness. If you want to add other components, simply click Yes.

magento 2.3 upgrade

Source: Magento.com

After that, you are ready to upgrade to Magento 2.3.

Step 6Select versions to upgrade.

Magento 2.3 upgrade

Source: Magento.com

Upgrade Magento 2.3 manually

If you use Magento Open Source and install the Magento Open Source GitHub repository via git clone, you are a contributing developer and can upgrade Magento 2.3 manually. Follow these steps to upgrade Magento 2.3 manually.

Step 1 Log in to your Magento server.

Step 2Save a backup for composer.json because the following steps will overwrite it. The commands are as below:

cd <your Magento install dir>
cp composer.json composer.json.old

Step 3Update your local repository: 

git pull origin develop

Step 4Merge both composer.json.old and composer.json

Step 5Use command: 

composer update

Step 6Update the Magento database with this command: 

php <your Magento install dir>/bin/magento setup:upgrade

Command-line upgrade

Also, you can upgrade Magento 2.3 with a command line.

Step 1Backup the existing composer.json file in the Magento installation directory.

Step 2Remove any unnecessary packages before upgrading to Magento 2.3.

$ composer remove --dev sjparkinson/static-review fabpot/php-cs-fixer --no-update

Step 3Then you need to deactivate the Magento Open Source update.

$ composer remove magento/product-community-edition --no-update

Step 4Indicate to Magento 2.3

1, For Magento Open Source

$ composer require magento/product-community-edition=2.3.0 --no-update

2, For Magento Commerce

$ composer require magento/product-enterprise-edition=2.3.0 --no-update

Specify additional packages

$ composer require --dev phpunit/phpunit:~6.2.0 friendsofphp/php-cs-fixer:~2.10.1 lusitanian/oauth:~0.8.10 pdepend/pdepend:2.5.2 sebastian/phpcpd:~3.0.0 squizlabs/php_codesniffer:3.2.2 --no-update

Step 5Open composer.json and edit the “autoload

"autoload": {
"psr-4": {
"Magento\\Framework\\": "lib/internal/Magento/Framework/",
"Magento\\Setup\\": "setup/src/Magento/Setup/",
"Magento\\": "app/code/Magento/",
"Zend\\Mvc\\Controller\\": "setup/src/Zend/Mvc/Controller/"

Step 6Modify the Magento updater

You need to modify the Magento updater if it is installed (which located in <Magento install dir>/update). First, you need to backup and remove the old updater. Then, create a Composer project.

1, For Magento Open Source

$ composer create-project --repository=https://repo.magento.com magento/project-community-edition=2.3.0 temp_dir --no-install

2, For Magento Commerce

$ composer create-project --repository=https://repo.magento.com magento/project-enterprise-edition=2.3.0 temp_dir --no-install

Finally, move the new project to <Magento install dir>/update directory:

$ mkdir update
$ mv temp_dir/update <Magento install dir>/update
$ rm -rf temp_dir

Step 7Check metadata in “name“, “version“, and “description” fields in the <Magento install dir>/composer.json file. If everything is okay, apply update.

$ composer update

Step8Clear caches and generated content

$ rm -rf <Magento install dir>/var/cache/*
$ rm -rf <Magento install dir>/var/page_cache/*
$ rm -rf <Magento install dir>/generated/code/*

Step 9Update the database schema and data

$ php bin/magento setup:upgrade

Step 10Disable maintenance mode

$ php bin/magento maintenance:disable

Step 11Restart Varnish

$ service varnish restart

Upgrade via changing pre_composer_update_2.3.php script

This is the easiest and quickest way to upgrade to Magento 2.3. We all thanks other Magento developers (including Webkul) to share the upgrade. You can download, or copy, the script file from the magento/magento2 repo:

<a href="https://raw.githubusercontent.com/magento/magento2/2.3.0/dev/tools/UpgradeScripts/pre_composer_update_2.3.php" target="_blank" rel="noopener noreferrer">/dev/tools/UpgradeScripts/pre_composer_update_2.3.php</a>

Or simply change pre_composer_update_2.3.php to:

* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.

$_scriptName = basename(__FILE__);

Updates Magento with 2.3 requirements that can't be done by `composer update` or `bin/magento setup:upgrade`.
Run this script after upgrading to PHP 7.1/7.2 and before running `composer update` or `bin/magento setup:upgrade`.

Steps included:
- Require new version of the metapackage
- Update "require-dev" section
- Add "Zend\\Mvc\\Controller\\": "setup/src/Zend/Mvc/Controller/" to composer.json "autoload":"psr-4" section
- Update Magento/Updater if it's installed
- Update name, version, and description fields in the root composer.json

Usage: php -f $_scriptName -- --root='</path/to/magento/root/>' [--composer='</path/to/composer/executable>']
[--edition='<community|enterprise>'] [--repo='<composer_repo_url>'] [--version='<version_constraint>']

Path to the Magento installation root directory

Path to the composer executable
- Default: The composer found in the system PATH

Target Magento edition for the update. Open Source = 'community', Commerce = 'enterprise'
- Default: The edition currently required in composer.json

The Magento repository url to use to pull the new packages
- Default: The Magento repository configured in composer.json

A composer version constraint for allowable 2.3 packages. Versions other than 2.3 are not handled by this script
See https://getcomposer.org/doc/articles/versions.md#writing-version-constraints for more information.
- Default: The latest 2.3 version available in the Magento repository

Display this message

$opts = getopt('', [

// Log levels available for use with output() function
define('INFO', 0);
define('WARN', 1);
define('ERROR', 2);

if (isset($opts['help'])) {

try {
if (version_compare(PHP_VERSION, '7.1', '<') || version_compare(PHP_VERSION, '7.3', '>=')) {
preg_match('/^\d+\.\d+\.\d+/',PHP_VERSION, $matches);
$phpVersion = $matches[0];
throw new Exception("Invalid PHP version '$phpVersion'. Magento 2.3 requires PHP 7.1 or 7.2");

/**** Populate and Validate Settings ****/

if (empty($opts['root']) || !is_dir($opts['root'])) {
throw new BadMethodCallException('Existing Magento root directory must be supplied with --root');
$rootDir = $opts['root'];

$composerFile = "$rootDir/composer.json";
if (!file_exists($composerFile)) {
throw new InvalidArgumentException("Supplied Magento root directory '$rootDir' does not contain composer.json");

$composerData = json_decode(file_get_contents($composerFile), true);

$metapackageMatcher = '/^magento\/product\-(?<edition>community|enterprise)\-edition$/';
foreach (array_keys($composerData['require']) as $requiredPackage) {
if (preg_match($metapackageMatcher, $requiredPackage, $matches)) {
$edition = $matches['edition'];
if (empty($edition)) {
throw new InvalidArgumentException("No Magento metapackage found in $composerFile");

// Override composer.json edition if one is passed to the script
if (!empty($opts['edition'])) {
$edition = $opts['edition'];
$edition = strtolower($edition);

if ($edition !== 'community' && $edition !== 'enterprise') {
throw new InvalidArgumentException("Only 'community' and 'enterprise' editions allowed; '$edition' given");

$composerExec = (!empty($opts['composer']) ? $opts['composer'] : 'composer');
if (basename($composerExec, '.phar') != 'composer') {
throw new InvalidArgumentException("'$composerExec' is not a composer executable");

// Use 'command -v' to check if composer is executable
exec("command -v $composerExec", $out, $composerFailed);
if ($composerFailed) {
if ($composerExec == 'composer') {
$message = 'Composer executable is not available in the system PATH';
else {
$message = "Invalid composer executable '$composerExec'";
throw new InvalidArgumentException($message);

// The composer command uses the Magento root as the working directory so this script can be run from anywhere
$composerExec = "$composerExec --working-dir='$rootDir'";

// Set the version constraint to any 2.3 package if not specified
$constraint = !empty($opts['version']) ? $opts['version'] : '2.3.0-beta8';

// Composer package names
$project = "magento/project-$edition-edition";
$metapackage = "magento/product-$edition-edition";

// Get the list of potential Magento repositories to search for the update package
$mageUrls = [];
$authFailed = [];
if (!empty($opts['repo'])) {
$mageUrls[] = $opts['repo'];
else {
foreach ($composerData['repositories'] as $label => $repo) {
output($label); output(strpos($repo['url'], '.mage'));
if (strpos(strtolower((string)$label), 'mage') !== false || strpos($repo['url'], '.mage') !== false) {
$mageUrls[] = $repo['url'];

if (count($mageUrls) == 0) {
throw new InvalidArgumentException('No Magento repository urls found in composer.json');

$tempDir = findUnusedFilename($rootDir, 'temp_project');
$projectConstraint = "$project='$constraint'";
$version = null;
$description = null;

output("**** Searching for a matching version of $project ****");

// Try to retrieve a 2.3 package from each Magento repository until one is found
foreach ($mageUrls as $repoUrl) {
try {
output("\\nChecking $repoUrl");
output("create-project --repository=$repoUrl $projectConstraint $tempDir --no-install");
runComposer("create-project --repository=$repoUrl $projectConstraint $tempDir --no-install");

// Make sure the downloaded package is 2.3
$newComposer = json_decode(file_get_contents("$tempDir/composer.json"), true);
$version = $newComposer['version'];
$description = $newComposer['description'];

if (strpos($version, '2.3.') !== 0) {
throw new InvalidArgumentException("Bad 2.3 version constraint '$constraint'; version $version found");

// If no errors occurred, set this as the correct repo, forget errors from previous repos, and move forward
output("\\n**** Found compatible $project version: $version ****");
$repo = $repoUrl;
catch (Exception $e) {
// If this repository doesn't have a valid package, save the error but continue checking any others
output("Failed to find a valid 2.3 $project package on $repoUrl", WARN);
$exception = $e;

// If a valid project package hasn't been found, throw the last error
if (isset($exception)) {
throw $exception;

output("\\n**** Executing Updates ****");

$composerBackup = findUnusedFilename($rootDir, 'composer.json.bak');
output("\\nBacking up $composerFile to $composerBackup");
copy($composerFile, $composerBackup);

// Add the repository to composer.json if needed without overwriting any existing ones
$repoUrls = array_map(function ($r) { return $r['url']; }, $composerData['repositories']);
if (!in_array($repo, $repoUrls)) {
$repoLabels = array_map('strtolower',array_keys($composerData['repositories']));
$newLabel = 'magento';
if (in_array($newLabel, $repoLabels)) {
$count = count($repoLabels);
for ($i = 1; $i <= $count; $i++) {
if (!in_array("$newLabel-$i", $repoLabels)) {
$newLabel = "$newLabel-$i";
output("\\nAdding $repo to composer repositories under label '$newLabel'");
runComposer("config repositories.$newLabel composer $repo");

output("\\nUpdating Magento metapackage requirement to $metapackage=$version");
if ($edition == 'enterprise') {
// Community -> Enterprise upgrades need to remove the community edition metapackage
runComposer('remove magento/product-community-edition --no-update');
runComposer("require $metapackage=$version --no-update");

output('\nUpdating "require-dev" section of composer.json');
runComposer('require --dev ' .
'phpunit/phpunit:~6.2.0 ' .
'friendsofphp/php-cs-fixer:~2.10.1 ' .
'lusitanian/oauth:~0.8.10 ' .
'pdepend/pdepend:2.5.2 ' .
'sebastian/phpcpd:~3.0.0 ' .
'squizlabs/php_codesniffer:3.2.2 --no-update');
runComposer('remove --dev sjparkinson/static-review fabpot/php-cs-fixer --no-update');

output('\nAdding "Zend\\\\Mvc\\\\Controller\\\\": "setup/src/Zend/Mvc/Controller/" to "autoload": "psr-4"');
$composerData['autoload']['psr-4']['Zend\\Mvc\\Controller\\'] = 'setup/src/Zend/Mvc/Controller/';

if (preg_match('/^magento\/project\-(community|enterprise)\-edition$/', $composerData['name'])) {
output('\nUpdating project name, version, and description');
$composerData['name'] = $project;
$composerData['version'] = $version;
$composerData['description'] = $description;

file_put_contents($composerFile, json_encode($composerData, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT));

// Update Magento/Updater if it's installed
$updateDir = "$rootDir/update";
if (file_exists($updateDir)) {
$updateBackup = findUnusedFilename($rootDir, 'update.bak');
output("\\nBacking up Magento/Updater directory $updateDir to $updateBackup");
rename($updateDir, $updateBackup);
output('\nUpdating Magento/Updater');
rename("$tempDir/update", $updateDir);

// Remove temp project directory that was used for repo/version validation and new source for Magento/Updater

output("\\n**** Script Complete! $composerFile updated to Magento version $version ****");
if (count($authFailed) > 0) {
output('Repository authentication failures occurred!', WARN);
output(' * Failed authentication could result in incorrect package versions', WARN);
output(' * To resolve, add credentials for the repositories to auth.json', WARN);
output(' * URL(s) failing authentication: ' . join(', ', array_keys($authFailed)), WARN);
} catch (Exception $e) {
if ($e->getPrevious()) {
$e = $e->getPrevious();

try {
output($e->getMessage(), ERROR, get_class($e));
output('Script failed! See usage information with --help', ERROR);

if (isset($composerBackup) && file_exists($composerBackup)) {
output("Resetting $composerFile backup");
rename($composerBackup, $composerFile);
if (isset($updateBackup) && file_exists($updateBackup)) {
output("Resetting $updateDir backup");
rename($updateBackup, $updateDir);
if (isset($tempDir) && file_exists($tempDir)) {
output('Removing temporary project directory');
catch (Exception $e2) {
output($e2->getMessage(), ERROR, get_class($e2));
output('Backup restoration or directory cleanup failed', ERROR);

exit($e->getCode() == 0 ? 1 : $e->getCode());

* Gets a variant of a filename that doesn't already exist so we don't overwrite anything
* @param string $dir
* @param string $filename
* @return string
function findUnusedFilename($dir, $filename) {
$unique = "$dir/$filename";
if (file_exists($unique)) {
$unique = tempnam($dir, "$filename.");
return $unique;

* Execute a composer command, reload $composerData afterwards, and check for repo authentication warnings
* @param string $command
* @return array Command output split by lines
* @throws RuntimeException
function runComposer($command)
global $composerExec, $composerData, $composerFile, $authFailed;
$command = "$composerExec $command --no-interaction";
output(" Running command:\\n $command");
exec("$command 2>&1", $lines, $exitCode);
$output = ' ' . join('\n ', $lines);

// Reload composer object from the updated composer.json
$composerData = json_decode(file_get_contents($composerFile), true);

if (0 !== $exitCode) {
$output = "Error encountered running command:\\n $command\\n$output";
throw new RuntimeException($output, $exitCode);

if (strpos($output, 'URL required authentication.') !== false) {
preg_match("/'(https?:\/\/)?(?<url>[^\/']+)(\/[^']*)?' URL required authentication/", $output, $matches);
$authUrl = $matches['url'];
$authFailed[$authUrl] = 1;
output("Repository authentication failed; make sure '$authUrl' exists in auth.json", WARN);

return $lines;

* Deletes a file or a directory and all its contents
* @param string $path
* @throws Exception
function deleteFilepath($path) {
if (!file_exists($path)) {
if (is_dir($path)) {
$files = array_diff(scandir($path), array('..', '.'));
foreach ($files as $file) {
else {
if (file_exists($path)) {
throw new Exception("Failed to delete $path");

* Logs the given text with \n newline replacement and log level formatting
* @param string $string Text to log
* @param int $level One of INFO, WARN, or ERROR
* @param string $label Optional message label; defaults to WARNING for $level = WARN and ERROR for $level = ERROR
function output($string, $level = INFO, $label = '') {
$string = str_replace('\n', PHP_EOL, $string);

if (!empty($label)) {
$label = "$label: ";
else if ($level == WARN) {
$label = 'WARNING: ';
else if ($level == ERROR) {
$label = 'ERROR: ';
$string = "$label$string";

if ($level == WARN) {
elseif ($level == ERROR) {
error_log(PHP_EOL . $string);
else {
echo $string . PHP_EOL;

Also, you need to update composer.json like this.

"name": "magento/project-community-edition",
"description": "eCommerce Platform for Growth (Community Edition)",
"type": "project",
"version": "2.3.0-beta8",
"license": [
"require": {
"magento/product-community-edition": "2.3.0-beta8",
"composer/composer": "@alpha"
"require-dev": {
"phpunit/phpunit": "~6.2.0",
"squizlabs/php_codesniffer": "3.2.2",
"phpmd/phpmd": "@stable",
"pdepend/pdepend": "2.5.2",
"friendsofphp/php-cs-fixer": "~2.10.1",
"lusitanian/oauth": "~0.8.10",
"sebastian/phpcpd": "~3.0.0"
"autoload": {
"psr-4": {
"Magento\\Framework\\": "lib/internal/Magento/Framework/",
"Magento\\Setup\\": "setup/src/Magento/Setup/",
"Magento\\": "app/code/Magento/",
"Zend\\Mvc\\Controller\\": "setup/src/Zend/Mvc/Controller/"
"psr-0": {
"": [
"files": [
"exclude-from-classmap": [
"autoload-dev": {
"psr-4": {
"Magento\\Sniffs\\": "dev/tests/static/framework/Magento/Sniffs/",
"Magento\\Tools\\": "dev/tools/Magento/Tools/",
"Magento\\Tools\\Sanity\\": "dev/build/publication/sanity/Magento/Tools/Sanity/",
"Magento\\TestFramework\\Inspection\\": "dev/tests/static/framework/Magento/TestFramework/Inspection/",
"Magento\\TestFramework\\Utility\\": "dev/tests/static/framework/Magento/TestFramework/Utility/"
"minimum-stability": "beta",
"repositories": [
"type": "composer",
"url": "https://repo.magento.com/"
"extra": {
"magento-force": "override"

Why Magestore? We believe in building a meaningful & long-term relationship with you.


  1. Great. But What about Your Omnichanell extension? Where can I expect support for Magento 2.3 ???

    • Hi Kris,

      You’ll get the same support you’ve had for Omnichannel Solution, as well as all other products of Magestore. So no worries at all 🙂

      For Magento 2.3, we are developing a specialized POS that makes a perfect combo for online-to-offline businesses. You can explore more info about our upcoming POS for magento 2.3 here For any other questions, please feel free to contact us We’ll be happy to clarify your concerns 🙂

Write A Comment