My first Drupal migration was onto a heavily patched version of Drupal 4.0, back in 2002. I previously ran a popular kernel development blog called KernelTrap, using PHPNuke. I conducted interviews with prominent kernel developers, and posted blog entries about other interesting kernel news, all of which were frequently linked to from the front page of Slashdot (the leading tech news aggregator at the time). This resulted in huge traffic spikes, which would frequently bring the website down, commonly known as "the Slashdot effect”.

In early March of 2002, I received a friendly email from a Belgian developer named Dries Buytaert about a relatively new CMS called Drupal. He told me the CMS would be gaining a near magical-sounding performance-feature called "the page cache," which allowed an entire page to be served out of the database with only a single query, theoretically making Drupal able to withstand even a Slashdotting.

During his 2015 keynote at DrupalCon Los Angeles, Dries explained that before starting Drupal, he was following Linux kernel development, "I considered contributing to the Linux kernel and so I would follow a website called KernelTrap. KernelTrap was managed by Jeremy Andrews, and at the time Linux and the Linux kernel was a very hot topic. Everybody wanted to read about it. Jeremy basically listened in on the kernel mailing list and would blog about interesting conversations.”

In his first email, Dries offered me complete admin access to, the original and very active community from which Drupal was born. This allowed me to better understand how it would feel to manage KernelTrap with Drupal, and receiving this trust was my introduction to the amazing Drupal community. Dries approached me very confidently, later summarizing this exchange in his keynote, "I basically said [to Jeremy] if you convert your website to Drupal it will never crash again." He went on to acknowledge, "Jeremy did convert his website to Drupal, and of course the first time he ended up on Slashdot the site crashed.”

I have kept that original email, as it literally changed the course of my life:

Date: Tue, 9 Mar 2002 10:28:36 +0200 (SAST)
From: Dries Buytaert
To: Jeremy Andrews <>
Subject: Drupal as a replacement for PHPNuke

Hey Jeremy,

After having read, I decided I'd let you know about the Drupal engine [1] as a replacement for PHPNuke. You can see Drupal in action at [2] and you can learn more about it at [3]. If you'd like to get an idea of how the admin pages look like and what sort of things can be configured, drop me a line, and I can give you temporary admin access to Like that you don't have to install it yourself. [Note: I'm the main Drupal developer.]

Note that Drupal caches pages, and that it can pull out entire pages with just one SQL query. Furthermore, Drupal is designed to be modular so you can remove all the functionality you don't see fit - or you can easily add your own.


Amongst other things, I'm *really* into the weblog development scene (it is a hobby), so if you want my opinion on any of the existing weblog tools (such as PHPNuke, PostNuke, Geeklog, DaCode, Scoop, Slash, Drupal, Zope, etc), just ask.

Dries Buytaert

At that time, was running one of the final 3.0 releases of Drupal. While I was very excited about the page cache, I found a few critical pieces that were still missing: there was no good way to categorize blog posts, the statistics Drupal collected were too limited, and there was no good way to browse older content.

Dries informed me that an amazing new module, called Taxonomy, was going to be a big new feature in Drupal 4.0. Indeed, a month and a half later, Marco Molinari's revolutionary Taxonomy patch was committed into the Drupal codebase, becoming one of Drupal's most powerful features. On June 15th, 2002, Drupal 4.0.0 was released and included both the page cache and the Taxonomy module.

At this point, my first Drupal migration started in earnest. I wrote scripts that read data directly out of the PHPNuke database, and then wrote it directly into the Drupal database. I had to learn more about Drupal's bootstrap process and hooks in order to get the content to properly load. My solution was not the most elegant, but in the end it was successful at repeatedly migrating users, content, and metadata like categorizations (taxonomy) into a Drupal 4.0 installation.

During this process, I read a book on PHP and spent a few days enhancing the Drupal statistics module to collect all the information I needed to properly maintain KernelTrap. I also got to work implementing what became Drupal core’s pager logic, which made it possible to browse older blog stories - similar to navigating pages of Google search results. This done, I spent a weekend migrating the live KernelTrap from PHPNuke to a now heavily patched version of Drupal 4.0.0.

A few days later, KernelTrap again found itself on the front page of Slashdot, and though now Drupal-powered and page cache enabled, the website immediately crashed! I was at work, but I remember jumping on IRC and asking for help. Amid a number of excited comments and suggestions, Moshe Weitzman, another early Drupal developer, suggested I purge the block table, which effectively disabled all blocks on the website and, suddenly, KernelTrap was serving pages again. (Later, after the traffic surge ended, I had to manually restore the various blocks used on the website.)

This led to my next Drupal contribution, the Throttle module. Dries described it during his 2015 keynote, "the Throttle module was cool because it would look for spikes in traffic and then automatically disable features based on the load. For example, if the load reached level 5 you could disable the forum module block, and when the load reached level 6 you could disable commenting altogether." This was essentially automating the initial purging of the block table, reducing expensive site functionality to continue serving content when the site was at great load, and then restoring functionality when the load returned to normal levels without having to manually add back all the things!

After a fair amount of conversation and feedback on the Drupal developer mailing list (this pre-dated the issue queues, and was how Drupal core was developed at the time), my statistics module rewrite and new Throttle module were merged into core. Shortly after, my pager logic was also merged. And finally, on February 1st, 2003, Drupal 4.1.0 was released, KernelTrap was updated, and my first Drupal migration was complete.

(The Throttle module was a relatively short-lived member of the Drupal community, removed from core five years later in November of 2008. It was overly complicated, and made it impossible to enable more aggressive caching, which was the preferred solution. However, at the time, it helped KernelTrap serve pages for over 50,000 unique users per day while running on a single small server living in an ISP's closet.)

Fast forward over twenty years, and Drupal has a very powerful and well-proven Migration API built into core. The project was originally written by Moshe Weitzman and Mike Ryan (both now working at Tag1), and is currently maintained by several other developers, including Tag1 engineers Benji Fisher and Lucas Hedding.

With Drupal 7 going End-of-Life in January 2025, we will be posting a steady stream of how-tos with code examples and informational blogs to help you plan and execute your migration from Drupal 7 (or from Drupal 9, or other CMSs, even PHPNuke), to the latest Drupal release. While I'll never regret all the development and learning required for my first Drupal migration, decades of improvement and shared community experience now provide a rich and powerful upgrade path that make it significantly easier to migrate onto the latest version of Drupal.

Please let us know if you have specific migration-related topics you'd like to see us cover. Or, reach out and let us know if we can be an active part of ensuring your migration is a success!

Photo by NASA on Unsplash