How to Configure Download Methods in Easy Digital Downloads for Secure File Delivery
How you deliver files to customers after purchase is one of the most critical decisions in your digital store setup. Easy Digital Downloads (EDD) supports multiple download methods, each with different trade-offs for security, performance, and server compatibility. Choosing the wrong method can lead to slow downloads, broken links, or unauthorized access to your files.
This guide explains every download method available in EDD, how to configure each one, when to use Amazon S3 or Dropbox for file hosting, and how to set up download limits and expiration for maximum security.
Understanding EDD Download Methods
EDD offers three core download methods. Each controls how the file is transferred from your server to the customer’s browser.
1. Forced Download (Default)
With forced downloads, EDD uses PHP to read the file from the server and stream it to the customer’s browser. The actual file URL is never exposed, customers only see a tokenized download link that expires after use.
How it works: When a customer clicks their download link, EDD verifies the purchase, reads the file with PHP’s readfile() function, and sends it with proper headers that force the browser to download rather than display the file.
Pros:
- Most secure, file URLs are never exposed to the customer
- Works on all hosting environments
- Supports download limits and expiration
Cons:
- Uses PHP memory and execution time, can timeout on large files (100MB+)
- Slower than direct file serving for large files
- May hit PHP memory limits on shared hosting
Best for: Small to medium files (under 100MB), shared hosting, maximum security requirements.
2. Redirect
The redirect method sends the customer directly to the file URL using an HTTP redirect. The file is served by the web server (Apache/Nginx) instead of PHP, which is significantly faster for large files.
How it works: EDD verifies the purchase, then sends a 302 redirect to the actual file URL. The web server handles the file transfer directly.
Pros:
- Fast, web server handles file delivery, not PHP
- No PHP memory or timeout issues
- Works well for large files
Cons:
- Exposes the actual file URL momentarily during the redirect
- Tech-savvy users could potentially share direct file links
- Less secure than forced downloads
Best for: Large files (100MB+), VPS/dedicated servers where you control the web server configuration.
3. X-Accel-Redirect / X-Sendfile
This is the best of both worlds. The web server handles file delivery (fast), but the file URL is never exposed to the customer (secure). It requires specific web server configuration.
How it works: EDD verifies the purchase, then sends a special header (X-Accel-Redirect for Nginx, X-Sendfile for Apache) telling the web server to deliver the file. The customer never sees the file URL.
Pros:
- Fastest delivery method
- Secure, file URL is never exposed
- No PHP resource usage for file transfer
Cons:
- Requires server-level configuration (mod_xsendfile for Apache, or Nginx config)
- Not available on most shared hosting
Best for: VPS/dedicated servers with full server access, stores with high download volume or large files.
Configuring Your Download Method
- Go to Downloads > Settings > Misc in your WordPress admin.
- Find the Download Method dropdown.
- Select your preferred method: Forced, Redirect, or X-Accel-Redirect/X-Sendfile.
- Click Save Changes.
If you switch methods, test a download immediately to verify it works. Add a test product with a small file and complete a test purchase.
File Storage Options
Local Server Storage (Default)
By default, EDD stores downloadable files in your WordPress wp-content/uploads/edd/ directory. EDD adds an .htaccess file (Apache) or expects Nginx rules to prevent direct access to this directory.
Verify your protection is working by trying to access a file directly in your browser: yourdomain.com/wp-content/uploads/edd/2026/02/your-file.zip. You should get a 403 Forbidden error, not the file.
Amazon S3 Integration
For stores with large files or high download volumes, Amazon S3 offloads file storage and delivery from your web server. EDD’s Amazon S3 extension generates pre-signed, time-limited URLs for each download.
Setup steps:
- Create an S3 bucket and upload your files.
- Create an IAM user with
s3:GetObjectpermission on your bucket. - Install the EDD Amazon S3 extension.
- Enter your AWS Access Key and Secret Key in Downloads > Settings > Extensions > Amazon S3.
- When creating products, use the S3 file URL format:
s3://bucket-name/path/to/file.zip.
Benefits: Unlimited storage, global CDN delivery via CloudFront, no server load for file transfers, automatic pre-signed URLs that expire.
Dropbox Integration
EDD’s Dropbox File Store extension lets you host files on Dropbox and deliver them securely. This is simpler than S3 but less configurable.
Connect your Dropbox account in the extension settings, then select Dropbox files when creating products. EDD generates temporary download links that expire after use.
Download Limits and Expiration
Protecting your files doesn’t stop at the download method. EDD provides two additional security layers:
File Download Limit
Set the maximum number of times a customer can download their purchased files.
- Go to Downloads > Settings > Misc.
- Set the File Download Limit field (e.g., 3 or 5).
- This applies globally. To override per-product, edit the product and set a product-specific download limit.
A limit of 3-5 downloads is standard. This prevents link sharing while allowing customers to re-download if needed. If your catalog includes anything customers legitimately need repeat access to over months, a course workbook they’ll revisit, or a plugin they’ll reinstall on a new site later, weigh that against the piracy risk before setting the limit too low. Our guide on setting up file access controls in EDD to prevent unauthorized sharing goes deeper into that trade-off.
Download Link Expiration
Set how long download links remain active after purchase.
- In Downloads > Settings > Misc, find Download Link Expiration.
- Enter the number of hours (e.g., 48 for 2 days, or 0 for no expiration).
A 48-hour expiration is a good default. Customers receive their download link immediately after purchase and via email, giving them ample time to download while limiting exposure of the link.
File Access Logging
EDD logs every file download in Downloads > Reports > Logs > File Downloads. Each log entry includes:
- Customer name and email
- Product and file downloaded
- Date and time
- IP address
Review these logs periodically to spot unusual patterns, like a single customer downloading the same file dozens of times, which could indicate link sharing.
Optimizing Large File Delivery
If you sell files larger than 100MB (video courses, software, design assets), these optimizations are critical:
- Use Amazon S3 + CloudFront for files over 100MB. This eliminates PHP memory issues and provides global CDN delivery.
- Increase PHP limits if using forced downloads: set
memory_limitto 512M andmax_execution_timeto 300 in php.ini. - Switch to X-Accel-Redirect if you control your server. It’s the fastest method for large files.
- Split large products into multiple files instead of one massive archive. Smaller files are more reliable to download and easier to resume if interrupted.
- Provide checksums (MD5 or SHA256) so customers can verify file integrity after download.
CDN and Caching Considerations
A CDN sitting in front of your site changes how download protection behaves, and it’s a common place for stores to accidentally break their own security. If a page caching plugin or a CDN like Cloudflare caches the download-trigger page itself, one customer’s tokenized download link can end up served to a completely different visitor from cache. That’s not a theoretical risk, it’s a support ticket waiting to happen. The fix is straightforward but easy to miss: exclude your account/downloads pages, the checkout confirmation page, and any URL pattern that generates a personalized download link from full-page caching. Most caching plugins let you exclude specific pages or URL patterns by cookie or query string; EDD’s own documentation lists the standard exclusion patterns for the major caching plugins. If you’re running Amazon S3 with CloudFront, this is less of a concern since the pre-signed URLs are generated per-request and aren’t something a page cache would serve twice, which is one more reason S3 is worth considering once your download volume grows past what a single origin server handles comfortably.
Downloads and Software Update Delivery
If what you’re selling is a plugin, theme, or any product where customers expect ongoing version updates rather than a single one-time file, the download method question gets layered on top of a separate concern: how updates get delivered to sites that already have the product installed. That’s a different mechanism than the manual re-download flow covered above, EDD Software Licensing handles automatic update delivery straight to the customer’s WordPress dashboard rather than requiring them to log back in and re-download manually. We cover that setup in detail in how to use the EDD Software Licensing addon to deliver automatic plugin updates securely, which is worth reading alongside this guide if your catalog is software rather than static files like ebooks or media.
A Practical Decision Framework
With three delivery methods and two storage options on the table, it helps to work through the decision as a short sequence of questions rather than trying to weigh everything at once. Start with file size. If everything you sell is under 50MB, forced download on local storage is fine and you can stop there, it’s the safest default and needs no extra configuration. If your average file is over 100MB, forced download is going to cause you problems eventually, either timeouts on slower connections or PHP memory errors on shared hosting, so move to the next question. Next, do you control your server (VPS, dedicated, or a managed host that allows custom Nginx/Apache config)? If yes, X-Accel-Redirect or X-Sendfile gives you speed without giving up the security of hiding the real file URL, and it’s worth the one-time setup effort. If you’re on shared hosting without that level of control, the Redirect method is your fallback for large files, accepting that the file URL becomes briefly visible during the redirect. Finally, what’s your download volume? A store doing a handful of sales a day doesn’t need Amazon S3 regardless of file size, local storage with a sensible download method handles it fine. Once you’re seeing meaningful concurrent download traffic, or your files are large enough that CDN edge delivery meaningfully improves customer experience across different regions, S3 with CloudFront starts paying for itself in reduced server load and faster delivery for customers far from your origin server.
Security Checklist Before You Launch
A few checks worth running through once, before your store goes live with real customer files, rather than discovering a gap after someone reports a problem:
- Confirm direct file access returns a 403, not the file itself, using the browser test described above for your actual production URLs, not just a staging environment.
- Set a download limit and an expiration window rather than leaving both at unlimited, even if you plan to raise the limit later for a specific customer complaint.
- Test the full purchase-to-download flow from an incognito browser window as a fresh customer would experience it, not just from your logged-in admin session, since admin sessions can mask permission issues a real customer would hit.
- If you’re on shared hosting and using forced downloads, check your host’s PHP memory_limit and max_execution_time against your largest file before launch, not after the first customer complaint about a failed download.
- Review the file download log after your first week live to confirm the pattern of downloads looks like real customer behavior rather than a single IP hammering the same file repeatedly.
Troubleshooting Common Issues
Downloads return a blank page or 0-byte file
This usually means PHP ran out of memory during a forced download. Either increase memory_limit in php.ini, switch to the Redirect method, or move files to Amazon S3.
Download links say “expired” immediately
Check your server’s timezone settings. If your server clock is wrong, links may appear expired. Also verify the Download Link Expiration setting isn’t set to 0 hours unintentionally.
Files are accessible without purchase
Your upload directory protection isn’t working. For Apache, verify the .htaccess file exists in wp-content/uploads/edd/. For Nginx, add a location block that denies access to the EDD upload directory.
Customers can’t download after purchase
Check the payment status, downloads are only available for completed payments. Also verify the file URL in the product is correct and the file exists at that location.
Downloads work on desktop but fail on mobile
Some mobile browsers, particularly in-app browsers used by social media apps, handle forced-download headers inconsistently and may try to open the file instead of saving it, or fail silently. If you’re seeing a pattern of mobile-specific download complaints, check whether the affected customers are opening their download link from an in-app browser rather than a full mobile browser, and consider adding a note in your delivery email suggesting customers open the link in Safari or Chrome directly rather than through an embedded app browser.
Download works for the store owner but not for real customers
This almost always traces back to a caching or logged-in-state difference between how the admin tests and how a real customer experiences the flow. An admin account often bypasses page caching entirely on most caching plugin configurations, so a download page that’s serving stale, cached content to logged-out or non-admin visitors can look completely fine from an admin session while failing for everyone else. Always run the final pre-launch test from a logged-out incognito window, and if the problem is isolated to non-admin users, check your caching plugin’s exclusion rules for the account and checkout pages first before assuming it’s an EDD configuration issue.
Frequently Asked Questions
Which download method should I use?
For most stores: Forced Download (default). It’s the most secure and works everywhere. Switch to X-Accel-Redirect if you have VPS access and need better performance. Use Redirect only if forced downloads cause timeout issues and you can’t use X-Accel.
Do I need Amazon S3?
Not for small stores with files under 50MB. S3 becomes valuable when you sell large files, have high download volume, or want CDN delivery for global customers.
Can customers share their download links?
With proper configuration (forced downloads + download limits + link expiration), shared links will either expire or hit the download limit. No system is 100% piracy-proof, but these measures make casual sharing impractical.
Does changing the download method affect past orders?
No. The download method setting only controls how new download requests are served going forward; it doesn’t retroactively regenerate or invalidate links already issued for past purchases. If you switch methods, test with a new purchase rather than assuming it fixes issues on existing orders, and if a customer reports a problem on an older order, check which method was active at the time they purchased.
What if a customer’s download limit runs out before they’ve actually downloaded the file successfully?
This happens more often than store owners expect, usually from a customer’s browser retrying a failed download and burning through the limit on attempts that never completed. EDD doesn’t distinguish between a successful download and a failed one when counting against the limit, so a flaky connection can genuinely exhaust a customer’s allowance through no fault of their own. The practical fix isn’t a plugin setting, it’s a support process: when a legitimate customer reports this, manually reset their download count for that order rather than treating the limit as unbreakable. EDD stores this per-order, so an admin can increase or reset it without touching the global setting that applies to everyone else.
Should download limits and expiration be the same for every product?
Not necessarily. A single ebook and a full software suite with a dozen component files don’t carry the same practical need for repeat downloads. Products customers are more likely to need repeat access to (large software bundles installed on multiple sites, course materials referenced over months) are reasonable candidates for a higher per-product limit or longer expiration window than your global default, set at the product level rather than raising the global setting for your entire catalog.