How to Migrate from Amazon EFS to EBS on EC2

Recently, I was working with a client who was experiencing unusually high AWS bills, particularly from EFS metadata IO operations. After investigating, I found that their WordPress site’s files were mounted on EFS, which turned out to be the root cause of their cost issues. If you’re wondering why EFS and WordPress don’t play well together, here’s the thing, WordPress and PHP applications in general need to access many small files for each request. With EFS using the NFS protocol, these frequent small file operations create a massive overhead in metadata operations, leading to both performance issues and increased costs.

While the client wasn’t using any caching solutions which made things even worse, I wanted to address the root cause first before getting into any optimizations. EFS is great for many use cases, but for WordPress sites, it needs careful consideration. If your use case requires you to use EFS with WordPress or any PHP application, it’s important to implement proper caching mechanisms like PHP OPcache to reduce the overhead of file operations. However, since EFS wasn’t a requirement for this particular site, we decided to go with EBS instead of optimizing the WordPress installation on EFS. Here’s how we did the migration, step by step.

Before You Begin

You’ll need these things ready before starting:

  • SSH access to the EC2 instance ( or shell access via EC2 Connect )
  • Root or sudo access on the EC2 instance
  • Enough space on your target EBS volume for the migration ( increase if needed )

Note: Before doing anything, take a backup of your EFS. While the migration is straightforward, it’s always better to be safe than sorry.

Step 1: Check Current Setup

First, let’s see what we’re working with. In our case, the EFS was mounted to `/var/www/html` where the WordPress files were stored. Let’s check the current setup by running these commands:

# Check current mounts
df -h

# See what's in fstab
cat /etc/fstab

# Look for EFS mounts
mount | grep efs

Step 2: Get Your EBS Volume Ready

If you need more space on your EBS volume, now’s the time to extend it. You can do this from the AWS Console or using the AWS CLI. After extending the volume, you’ll need to grow the filesystem on the EC2 instance:

# For Nitro instances
sudo growpart /dev/nvme0n1 1
sudo xfs_growfs -d /          # For XFS
# OR
sudo resize2fs /dev/nvme0n1p1 # For EXT4

# For Xen instances
sudo growpart /dev/xvda 1
sudo xfs_growfs -d /          # For XFS
# OR
sudo resize2fs /dev/xvda1     # For EXT4

You can find detailed instructions in this AWS user guide.

Step 3: Backing up the Files

Now comes the main part, moving your files to a backup directory. We’ll use rsync for this since it shows progress and handles permissions:

# Create the target directory
sudo mkdir -p /path/to/backup/location

# Copy everything with rsync to a temporary location
# We'll move files to their final destination after unmounting EFS
sudo rsync -a --info=progress2 /path/to/efs/mount/ /path/to/new/location/

# Compare file counts to make sure everything copied
find /path/to/efs/mount -type f | wc -l
find /path/to/backup/location -type f | wc -l

Note: We’re using a temporary location here because we’ll need to unmount the EFS folder first before moving the files back to their original path.

Step 4: Stop Services and Unmount EFS

Before we can finish the migration, we need to stop the web server and unmount EFS:

# Stop web server ( depending on what you're using)
sudo systemctl stop nginx
sudo systemctl stop apache2
sudo systemctl stop httpd
sudo systemctl stop php-fpm

# Unmount EFS
sudo umount /path/to/efs/mount

Note: If you get a “device is busy” error, make sure you’re not in the EFS directory and no processes are using it.

Step 5: Move Files to Original Location

Now that we’ve unmounted EFS, we need to move our files back to the original location (in our case /var/www/html):

# Confirm EFS is no longer mounted
df -h

# Move all files including hidden ones
sudo rsync -av --progress /path/to/backup/location/ /var/www/html/

# Verify all files were moved, including hidden ones
ls -la /var/www/html/
ls -la /path/to/backup/location/

# Fix permissions for WordPress
sudo chown -R www-data:www-data /var/www/html/
sudo find /var/www/html/ -type d -exec chmod 755 {} \;
sudo find /var/www/html/ -type f -exec chmod 644 {} \;

Note: We’re using rsync here instead of mv to ensure all files, including hidden ones (dot files), are transferred correctly. This is especially important for WordPress as many configuration files like .htaccess start with a dot.

Step 6: Update System Configuration

Now we need to update the system configuration to remove EFS:

# Backup fstab
sudo cp /etc/fstab /etc/fstab.backup

# Remove EFS entry from fstab
sudo sed -i '/fs-/d' /etc/fstab

Step 6: Start Everything Back Up

# Start services
sudo systemctl start nginx  # Or apache2/httpd
sudo systemctl start php-fpm

# Check service status
sudo systemctl status nginx
sudo systemctl status php-fpm

Final Cleanup

Once everything is working smoothly (give it a few days to be sure), you can delete the EFS volume from AWS Console.

That’s it! After the migration, you should notice both better performance and lower costs. The WordPress site will be more responsive since it’s not dealing with NFS overhead for every file access, and your AWS bill will thank you for eliminating all those metadata operations.