AWS to NAS Migration: Best Practices for Cloud Repatriation
A practical guide for migrating data from AWS S3, EFS, or FSx back to on-premises NAS. Covers planning, bandwidth, verification, and common mistakes.
TL;DR
Migrating from AWS back to on-premises NAS requires planning that most cloud migration guides skip. This guide covers the practical steps: estimating egress costs and transfer times, choosing between direct download and physical transfer, handling protocol translation (S3 to NFS/SMB), and verifying data integrity after the move.
Cloud repatriation is no longer a fringe move. According to IDC, 80% of organizations that moved workloads to the cloud have repatriated some of them back on-premises. The reasons vary: egress costs, latency, compliance, or simply realizing that a file server in your own datacenter is cheaper for large datasets.
This guide covers the practical steps for migrating data from AWS (S3, EFS, or FSx) back to on-premises NAS storage.
Step 1: Inventory Your AWS Storage
Before anything else, understand what you’re moving.
S3 Buckets
# List all buckets and their sizes
aws s3 ls
aws s3 ls s3://your-bucket --recursive --summarize
Key questions:
- How many objects total? (Millions of small files take longer than a few large ones)
- What storage classes are in use? (Glacier retrieval takes hours and costs extra)
- Are there versioned objects? (Each version counts as a separate object)
- What’s the total size?
EFS File Systems
# Check EFS size via CloudWatch
aws cloudwatch get-metric-statistics \
--namespace AWS/EFS \
--metric-name StorageBytesTotal \
--dimensions Name=FileSystemId,Value=fs-12345678 \
--start-time 2026-04-01T00:00:00Z \
--end-time 2026-04-15T00:00:00Z \
--period 86400 \
--statistics Average
FSx for Windows / Lustre / NetApp ONTAP
FSx comes in multiple flavors. Check which one you’re using, as the migration path differs:
- FSx for Windows exposes SMB shares. Migrate via SMB protocol.
- FSx for Lustre is POSIX. Migrate via NFS or direct mount.
- FSx for NetApp ONTAP exposes NFS, SMB, and iSCSI. Use the appropriate protocol.
Step 2: Calculate Egress Costs and Transfer Time
Egress Costs
AWS charges for data leaving their network:
| Data range | Cost per GB |
|---|---|
| First 10 TB/month | $0.09 |
| Next 40 TB/month | $0.085 |
| Next 100 TB/month | $0.07 |
| Over 150 TB/month | $0.05 |
Example: Downloading 200 TB in one month costs approximately $12,500 in egress fees.
Negotiate egress
For large repatriations (100+ TB), contact your AWS account manager. AWS sometimes offers egress fee waivers or discounts for customers migrating workloads, especially if you’re maintaining other AWS services.
Transfer Time
Calculate how long the transfer will take over your internet connection:
| Connection | 100 TB transfer time |
|---|---|
| 1 Gbps | ~10 days |
| 10 Gbps | ~1 day |
| 100 Mbps | ~100 days |
If your connection is under 1 Gbps and you’re moving over 50 TB, consider AWS Snowball (physical device shipped to your datacenter). The break-even point is roughly:
- Under 10 TB: Direct download is faster and cheaper
- 10-50 TB: Direct download if you have 1+ Gbps; Snowball otherwise
- Over 50 TB: Snowball or dedicated AWS Direct Connect
Glacier Retrieval
If data is in Glacier or Glacier Deep Archive, you need to restore it before downloading:
| Retrieval tier | Time | Cost per GB |
|---|---|---|
| Expedited | 1-5 minutes | $0.03 |
| Standard | 3-5 hours | $0.01 |
| Bulk | 5-12 hours | $0.0025 |
For large repatriations, use Bulk retrieval. Restore data in batches to avoid concurrent restore limits.
Step 3: Prepare Your Destination
Choose the Right Protocol
| Source | Destination | Protocol |
|---|---|---|
| S3 | Linux NAS | NFS |
| S3 | Windows file server | SMB |
| EFS | Linux NAS | NFS |
| FSx for Windows | Windows file server | SMB |
| FSx for ONTAP | Any | NFS or SMB |
Size Your Storage
Provision at least 120% of your source data size:
- Filesystem overhead (inodes, metadata, journals)
- Different block sizes between source and destination
- Hard link resolution (links on S3 become separate files)
- Future growth buffer
Configure NFS/SMB Exports
Set up your NFS exports or SMB shares before starting the migration. Test access from the machine that will run the transfer:
# Test NFS mount
mount -t nfs your-nas:/export /mnt/test
touch /mnt/test/write-test && rm /mnt/test/write-test
# Test SMB mount
mount -t cifs //your-nas/share /mnt/test -o username=admin
touch /mnt/test/write-test && rm /mnt/test/write-test
Step 4: Choose Your Transfer Method
Option A: AWS CLI (Small datasets, under 10 TB)
aws s3 sync s3://your-bucket /mnt/nas-destination/ \
--no-progress \
--storage-class STANDARD
Pros: Simple, built-in. Cons: Single-threaded, no verification report, no cross-protocol support.
Option B: AWS DataSync (AWS-managed)
AWS DataSync can transfer from S3 or EFS to on-premises NFS/SMB shares via a DataSync agent running in your datacenter.
Pros: Managed by AWS, good throughput. Cons: Requires deploying a DataSync agent VM, costs $0.0125/GB transferred, adds to egress costs.
Option C: rclone (S3 to local filesystem)
rclone sync s3:your-bucket /mnt/nas-destination/ \
--transfers 16 \
--checkers 32 \
--progress
Pros: Multi-threaded, supports many backends. Cons: No NFS/SMB mount support (writes to local filesystem only), no cross-protocol migration, limited verification.
Option D: Dedicated Migration Tool
For large datasets (50+ TB), cross-protocol requirements (S3 to SMB), or compliance needs (auditable verification), use a purpose-built migration tool.
syncopio for AWS repatriation
syncopio connects to S3-compatible storage as a source and writes to NFS or SMB destinations. Distributed workers parallelize the transfer, and built-in checksum verification produces an auditable report confirming every file arrived intact. No DataSync agent needed.
Step 5: Handle S3-to-NAS Translation
S3 is object storage. NAS is file storage. They’re fundamentally different, and the translation requires decisions.
Object Keys to File Paths
S3 object keys like projects/2026/report.pdf become directory paths /projects/2026/report.pdf on the filesystem. Most tools handle this automatically, but watch for:
- Leading slashes in object keys (rare but possible)
- Empty “directories” in S3 (zero-byte objects ending in
/) - Special characters in keys that are invalid on NTFS:
:*?"and others
Metadata Translation
| S3 metadata | NAS equivalent | Notes |
|---|---|---|
| Content-Type | File extension | No direct mapping |
| Last-Modified | mtime | Preserved by most tools |
| x-amz-meta-* | Extended attributes | Tool-dependent |
| Storage class | N/A | Not applicable on NAS |
| Object tags | N/A | No filesystem equivalent |
| ACL | POSIX permissions / NTFS ACL | Requires explicit mapping |
Permissions
S3 uses IAM policies and bucket ACLs. NAS uses POSIX permissions (NFS) or NTFS ACLs (SMB). There’s no automatic translation. You need to decide:
- What UID/GID should files have on NFS?
- What NTFS permissions should files have on SMB?
- Should all files get the same permissions, or should you map from S3 metadata?
For most repatriations, a uniform permission set (e.g., 755 for directories, 644 for files, owned by a service account) is the simplest approach.
Step 6: Verify Everything
Never decommission your cloud storage until verification is complete.
Minimum Verification
- File count: Source object count matches destination file count
- Total size: Byte totals match (accounting for filesystem overhead)
- Spot checks: Randomly sample files and compare content
Full Verification
- Checksum every file: Compute checksums on source and destination, compare
- Permission audit: Verify ownership and permissions match your expectations
- Timestamp check: Confirm modification times were preserved
- Report generation: Produce an auditable document for compliance
Don't skip verification
The most common repatriation failure: decommissioning cloud storage before confirming every file transferred correctly. Keep the S3 bucket until you have a verified, checksummed report showing 100% integrity.
Step 7: Cutover and Decommission
- Final sync: Run one last incremental transfer to catch files changed since the initial copy
- Redirect clients: Update DNS, mount points, or application configs to point to the new NAS location
- Monitor: Watch for errors, missing files, or permission issues for at least one week
- Decommission: Delete S3 objects and close the bucket only after the monitoring period
S3 Lifecycle Policy for Safety
Instead of deleting immediately, set a lifecycle policy to move objects to Glacier Deep Archive for 30 days, then delete. This gives you a safety net at minimal cost ($0.00099/GB/month).
{
"Rules": [
{
"ID": "PostMigrationCleanup",
"Status": "Enabled",
"Transitions": [
{
"Days": 0,
"StorageClass": "DEEP_ARCHIVE"
}
],
"Expiration": {
"Days": 30
}
}
]
}
Common Mistakes
| Mistake | Consequence | Prevention |
|---|---|---|
| Not budgeting egress fees | Bill shock ($90/TB) | Calculate total egress before starting |
| Forgetting Glacier restore time | Migration delayed by hours/days | Restore in batches, start early |
| Single-threaded transfer | Weeks instead of days | Use parallel transfers |
| No verification | Silent data loss | Checksum every file before decommission |
| Deleting S3 before verification | Data loss if files were missed | Keep source for 30+ days after cutover |
| Ignoring filename restrictions | Files with :*? fail on NTFS/SMB | Pre-scan for illegal characters |
| Wrong NFS/SMB permissions | Users locked out of their files | Test access with real user accounts |
Checklist
- Inventory all AWS storage (S3 buckets, EFS, FSx)
- Calculate egress costs
- Estimate transfer time based on bandwidth
- Consider Snowball for 50+ TB datasets
- Restore any Glacier data using Bulk retrieval
- Provision destination NAS with 120% capacity
- Configure and test NFS/SMB exports
- Run initial full transfer
- Run incremental sync to catch changes
- Verify file counts, sizes, and checksums
- Generate verification report
- Redirect clients to new storage
- Monitor for one week minimum
- Set S3 lifecycle policy (Glacier 30 days, then delete)
- Decommission S3 storage after monitoring period