Bulk PHP Upgrades With Kinsta’s API

One of my most requested features for Kinsta was for them to build an API. Well, they listened and have been regularly rolling out new API endpoints: https://api-docs.kinsta.com. Any hosting provider with a powerful API is an open invitation for amazing products to be built on top. Recently I used the Kinsta API to bulk upgrade PHP. The results exceeded my expectations.

Planning out PHP upgrades

Kinsta regularly removes unsupported versions of PHP from their platform. As of today PHP 8.0 is scheduled to be removed as an option and existing sites running 8.0 will be upgraded to 8.1 in the next several weeks. Personally, I like to control how and when PHP upgrades happen so I can roll back if needed. The following is how I ran bulk upgrades over 500 sites from version 8.0 to 8.3 using Kinsta’s API. Spoiler alert… being able to script PHP upgrades/downgrades is crazy powerful.

Email from Kinsta regarding PHP upgrades.

Extracting environments from Kinsta’s internal API using Insomnia.

While Kinsta’s API is already very powerful, it can’t do everything. There is currently no way to request a list of all environments with details like PHP versions. If you only have 100 sites then you could easily request a list of sites and then loop over each to retrieve environment details. However, with 1000s of sites, I’d really like a single API request to fetch all environments with a few details. Luckily it is still possible to hook into Kinsta’s internal API. The following GraphQL request to https://graphql-router.kinsta.com will give was just what we need, PHP version info and primary domain. This does require logging into MyKinsta and reusing your X-Token as explained in the readme here: https://github.com/austinginder/kinsta-internal-api.

query ExportSites($idCompany: String!) {
  company(id: $idCompany) {
    sites {
      environment(name: "live") {
				activeContainer {
				primaryDomain {

We can then manually talk to MyKinsta using Insomina like this. Let’s save this output to a payload.json file.

Talking to MyKinsta using Insomina

Concurrent requests using BASH and WP-CLI

This might seem a bit messy but I enjoy using a combination of BASH, PHP and WP-CLI to accomplish bulk tasks. BASH is great at running tasks quickly with its built-in multithreading capabilities. PHP makes it easy to store and retrieve data from a simple JSON file. Lastly, WP-CLI allows me to use code from any WordPress plugin. So with that here is how I structured my code:

  • kinsta-bulk-update-php.sh <php-version-from> <php-version-to>
    This is the main script that handles running concurrent threads and collecting results.
  • wp eval-file kinsta-environment-php-update.php <environment-id> <php-version>
    This is a WP-CLI script that takes in a Kinsta environment ID and handles running the PHP upgrade. The underly API calls are handled with CaptainCore, my WordPress maintenance toolkit, using a simple wrapper like this: CaptainCore\Remote\Kinsta::get().
  • php kinsta.php <action> <name> <value>
    This PHP script handles storing results, retrieving environment info, and processes results from the concurrent script.

Running kinsta-bulk-update-php.sh 8.0 8.3 reads in contents from payload.json and outputs data.json which is populated with just the environment info we need to perform our upgrades, like environment ID, site ID, PHP version, and primary domain. It then targets all environments running a certain version of PHP, like 8.0, and upgrades them to a certain version of PHP, like 8.3, concurrently. Since requests to Kinsta’s API only start the PHP upgrade, it responds immediately with an operation ID which can be used to track the progress. The actual PHP upgrade completed in the background after a few minutes. Due to BASH concurrency, this all happens lightning fast. I was shocked when my initial PHP upgrades on 500+ environments was done in under 5 minutes!

Planning for extra checks and downgrades

Upgrading PHP can cause outdated code to break. This is especially true when upgrading between major versions. Going from PHP 7.4 to 8 was painful and required code wrangling to many WordPress customers. So being able to downgrade to an older version of PHP quickly is critical when errors are found. Just knowing how fast these environments can be bulk upgraded or downgraded will be a huge deal when the next major release of PHP.

Moving from PHP 8.0 to PHP 8.3 is very minor and unlikely to break anything. I only ran into one minor issue with a plugin, which the plugin author is already fixing. For now, my scripting just handles the actual updates however in the future I’d like to extend it to handle a few safety checks. For example, if the frontend of the website changes or there are new PHP fatals in the server logs then automatically roll back PHP. You can check out the full code here: https://github.com/austinginder/kinsta-bulk-tools.