Why ERPNext attachment storage grows and what to do about it
ERPNext stores uploaded files on the local filesystem of the server by design, so a full disk on a running ERPNext is usually an attachment capacity problem that was never sized, not a fault. The fix is planning capacity, access and backups for ERPNext attachment storage growth together. Deleting files to free space is a short-term step that can remove records your auditors or customers still need, and it leaves the growth pattern in place.
Teams usually reach this point after attaching scanned supplier invoices, signed delivery proofs, engineering drawings and inspection photos to Sales Invoices, Purchase Receipts, Work Orders or Quality Inspections. Each attachment looks small, but volume grows with transaction count, image resolution and the number of sites or companies sharing one server. Before choosing a fix, check where files land in your bench, how much space the public and private file folders already use, and how many attachments each document type carries each month. Ask your partner or internal team to confirm these figures in your own environment, because growth rates vary widely between businesses.
Each option has different consequences. Adding disk is quick but must be repeated, and the new volume has to be included in backups and restore tests. Moving files to object storage is a separate design decision: ERPNext has no native S3 upload setting, so any object storage path needs a custom approach that you must test for access control, file URLs and restore. Decide early whether the business needs private files for sensitive documents, what retention applies to them, and who may download them, because those answers drive the storage and backup design.
Private versus public files and who can reach them
A public file is served from a URL that anyone holding the link can open, with no desk session required. A private file is served only after ERPNext confirms that the requester is logged in and allowed to read the document it is attached to. The choice is made per attachment or per field, so one document can hold a private scanned contract and a public product image.
- Exposure follows the link: A public URL keeps working for anyone who has it, even after the user who uploaded the file is disabled.
- Default visibility: Check custom fields, web forms and print formats for attachment fields that default to public.
- Path predictability: Confirm in your installed version how file names and paths are generated and whether directory listing is exposed by your web server.
- Outbound copies: Files sent by email or pasted into external tools carry their links outside ERPNext's permission checks.
Ask your team to test each attachment type from a logged-out browser session before go-live.
Visibility does not change how much disk space a file uses, so the split does not reduce storage growth on its own. What it changes is where the bytes land on disk. Private and public files are kept in separate folders for each site, so capacity plans, monitoring and backups must cover both locations.
- Two locations per site: Map the private and public folders for each site in your bench layout and include both in capacity alerts.
- Backup scope: Confirm that your backup job captures both folders and that a restore brings back files that open through ERPNext.
- Fastest-growing sources: Bulk imports, scanned documents and attachments on high-volume transactions usually drive growth more than the visibility setting.
- Container volumes: If you run ERPNext with Docker, make sure both folders sit on persistent volumes that survive container replacement.
Ask the vendor or your own team to confirm the exact folder layout for your installed version before you size the disk.
For records management, visibility decides who can produce a copy of a file and whether that access can be traced. A private file is opened through a document that has permissions, which gives you a path for access reviews. A public URL gives you no such path, because anyone with the link can open it.
- Classify by record type: Set default visibility for contracts, employee records, tax documents and customer identity documents as private unless a documented business need says otherwise.
- Retention follows the document: Confirm whether deleting or archiving a parent record also removes its attached files in your version.
- Changing visibility later: Test whether switching a file from public to private stops the earlier public URL from working, since copies may already be in circulation.
- Written rule set: Record the classification rules and the people who approve exceptions before the first bulk upload.
A written rule and a sample check of stored files give auditors something to test, but the assessment itself belongs to the auditor.
The quickest verification is to open the file record after upload, confirm its visibility, and then open the file URL in a logged-out browser. Compare what a user actually receives with the setting you intended, because the form and the stored record can disagree.
- Visibility flag: Open the File record and confirm whether it is marked private or public.
- URL form: Private files should resolve under a
/private/files/path and public files under a/files/path, so check the address your users copy. - Logged-out result: A private URL should prompt for login or refuse access, while a public URL should open directly. Confirm both behaviors in your version.
- Bulk imports: Check files brought in through imports or scripts separately, since they may not follow the same path as a manual upload.
- Form and print outputs: Repeat the test for each attachment field and each print format that shows a file link.
Repeat these checks for every attachment field before users start working in the system.
Storage options and when each one fits
This table compares the five realistic ways to handle attachment growth in a self-hosted ERPNext bench, from keeping files on local disk to archiving old records. Read each row against your recovery objectives, access rules and the team that will run the storage layer. The main takeaway is that moving bytes off the bench is rarely the first step, and every option changes how backups and restores work.
| Option | Trade-off in cost, recovery, access and risk | When it fits |
|---|---|---|
| Larger local volume | Lowest change risk and no new moving parts. Cost recurs as disk grows, backups grow with it, and a single volume remains a single failure point. | Growth is modest and predictable, and the team wants to keep the stock bench layout unchanged. |
| Bench files directory on network or block volume | Keeps ERPNext reading a normal path. Adds storage network latency and a dependency on the volume platform. Snapshots and restores must cover the same volume as the database. | The host cannot be resized easily, but your infrastructure team already runs reliable network or block storage. |
| Object storage mounted at filesystem level | Avoids application changes but adds a FUSE-style layer. Performance, file locking and consistency under concurrent writes need testing. Access control depends on the bucket policy and mount options, not ERPNext permissions. | Only as a tested stopgap. Confirm behavior with your storage vendor before production use. |
| Custom app that writes to object storage | Gives ERPNext-aware control over storage location and access. Requires code ownership, upgrade testing across Frappe releases and careful handling of private file URLs. Backups must include both database rows and bucket contents. | You need object storage at scale and have engineers who will maintain the app through each upgrade. |
| Archive or purge through a documented process | Reduces live data and backup size, but removed attachments may be needed for audit or legal holds. Requires dry runs, a backup taken first and an approval record for each batch. | Old attachments have a defined retention period and business owners can confirm which records may go. |
Disk planning: what drives growth
Attachment growth follows the business, not the software. Volume depends on which document types people attach files to, how large those files are, how long the business keeps them, and whether integrations add copies on their own. Measure each driver on your own sites before you size the disk, because the same ERPNext version can produce very different growth on a manufacturer's shop floor than on a services firm's sales desk.
Attachment volume by document type
Purchase invoices, delivery notes, journal entries, employee documents and project records each collect attachments at a different rate. A purchasing team that scans every supplier invoice generates far more files than a team that attaches only exceptions. Break the File list down by the attached-to doctype and rank the top five. That ranking shows where the growth will come from and which workflows to review first with the process owners.
Average file size
Average size matters more than file count once you move past a few thousand attachments. A single high-resolution photo from a mobile device, a multi-page drawing or a spreadsheet export can weigh many times more than a one-page PDF. Sample a month of uploads and calculate the mean and the largest files per doctype. Ask whether users may attach raw camera images, CAD exports or archive files, because those formats usually drive the outliers.
Scanned versus native formats
Scanned documents are usually image-based PDFs at scanner resolution, and they are often much larger than the same content exported natively from the source system. Scanning policy therefore changes storage per record more than most teams expect. Agree on a standard scan resolution, color mode and page limit with the records team, and decide whether originals are kept alongside scans. Test a few sample scans against the agreed setting before you publish the policy.
Business retention periods
Retention is set by tax, contract and audit obligations, not by the disk. Every year of retention adds another full year of attachments to the disk and to every backup, so an unclear retention rule quietly multiplies the bill. Ask the finance and legal owners which record classes must be kept, for how long, and which can be archived or deleted. Write those answers down before you choose a volume size, and confirm the requirements with your own auditors or counsel rather than assuming a period.
Duplicate uploads from integrations
Connectors, email ingestion, scheduled imports and custom scripts can attach the same file more than once. A mailbox rule that retries after a timeout, or an integration that re-sends a document on every status change, can fill storage with identical copies. Check the File list for repeated file names, sizes and content hashes tied to the same parent record, and review the logic of each integration that writes attachments. Remove duplicates only after confirming with the owner of that integration and taking a backup.
Steps to assess and reduce attachment growth safely
This sequence moves from measurement to cleanup in a fixed order, so each reduction is backed by known file locations, agreed retention rules and a verified backup. The output is a documented storage target and a tested change that has been proven on a staging copy before production.
Inventory sites and bench file paths
On the bench host, list every site in the bench and record where its files live. ERPNext stores attachments on the local filesystem under each site's
sites/<site>/private/filesandsites/<site>/public/filesfolders, so confirm those paths on each site and note any custom mount points or symlinks. The operator running this step owns the list, and it is done when every site has a row with its two folder paths and their mount source on the host.Measure size by site and file visibility
Measure disk usage for the private and public folder of each site separately, and record file counts alongside sizes. Private files are served only to authorized users, while public files are reachable without login, so the split matters for both access review and backup planning. Keep the output in a dated table. The step is complete when the totals reconcile with the host disk usage for the bench volume, within what your monitoring tool reports.
Identify the largest attachment doctypes
Query the File doctype grouped by attached-to doctype and by owner to see which documents account for the most storage. Typical large sources include scanned purchase documents, product images, and print or email attachments generated repeatedly, but confirm these against your own data rather than assuming them. Sort the results by total size. The check is that the sum of File sizes from the query is close to the folder totals from the previous step, and any large gap is explained before you continue.
Agree retention rules with the business
Meet with finance, operations and compliance owners to decide which attachments must be kept, for how long, and in which visibility class. Record the rule per doctype, including any legal hold or audit requirement that your records policy sets, and name the approver. Do not delete anything based on file age alone. The output is a signed retention table, and the step is done when every doctype from the previous step has an explicit keep, archive or remove decision.
Take and verify a full backup
Run a full backup of each site, including the database and both file folders, using the Frappe backup command or your own snapshot process, and store it away from the bench host. Restore the backup into a separate environment and confirm that the restored site opens, that File record counts match the source, and that a sample of private and public attachments downloads from a desk session. The step is done when the restore check passes and the restore log is kept with the change record.
Set the storage target
Using the measurements and retention table, write a target for the disk or volume that states the maximum usage you will accept and the threshold at which the team is alerted. Include the growth rate you observed over the measurement period and the planned headroom for backups and temporary files. Ask your infrastructure team to confirm whether the volume can be extended or whether an external storage arrangement is supported in your environment. The check is that the target is approved and monitored with an alert on the bench host.
Apply cleanup or migration in staging first
Restore the verified backup to a staging copy and apply the chosen change there, whether that is archiving old private files, moving a folder to larger storage, or removing files the retention table marks for deletion. Test in staging before you touch production, and review every removal with the owner from the retention step. After the change, confirm file counts, check that the expected records still show their attachments, and open a sample of attachments from a desk session with a standard user account. Repeat the same change in production only after the staging checks pass, and record the before and after measurements.
How attachment growth changes backup size and restore time
Attachment growth raises the size of every backup, and a database backup alone cannot restore the files. ERPNext keeps uploaded attachments on the local file system of the bench, in the site's private/files and public/files folders, while the database holds only the records that point to them. A backup that captures only the database will restore invoices, purchase orders and item records with broken attachment links. Each new scan or supplier document therefore adds to the file portion of the backup, and that growth affects backup duration, the bandwidth needed to move the copies off the server, and the time required to bring a site back after a failure. Because file growth tends to accumulate faster than table growth in document-heavy deployments, the restore window often lengthens before anyone notices the change in the database.
Confirm the backup scope for both folders before you rely on any schedule. Ask your operator or partner to show, for each site, whether the backup job includes the private files folder, the public files folder, the site configuration and the database, and where each copy is stored. Private attachments carry access rules that public files do not, so a backup that omits one of them may still look successful in the logs while leaving part of the document set unprotected. Check the backup tool's documentation for the current options, because the exact flags and retention settings depend on your installed version and on whether you use bench backup commands or a managed backup service.
Test a restore on a separate copy of the server at least once before you finalize retention. Restore the database and both file folders to a non-production host, open several old attachments from different years and document types, and time the whole process, since that measured figure is the restore time you can actually promise. Then set retention in line with the storage plan: the number of retained file snapshots multiplies the attachment footprint, so the disk and object storage you budget for must cover the retained copies as well as the live folders. Record the decision, the retention period and the restore test result together so that the next growth review can compare them against current file volumes.
Security and operational considerations for stored files
Attachments in ERPNext often hold invoices, contracts, employee documents and customer data, so the files you store carry the same obligations as the records they belong to. The cards below cover the controls that sit alongside storage growth: who can reach a file, how the disk and mounts are protected, and how files are scanned, retained, deleted and logged.
File access checks on private files
Private attachments in ERPNext are served through an access check tied to the document they belong to, so a user needs permission on the parent record to open the file. Test this with a user who lacks access to the parent document, and confirm that the same rule applies to attachments added through API calls, imports and scripts. Check whether any custom code or print format bypasses the check.
Exposure risk from public URLs
Public files are reachable by anyone who holds the URL, and that URL does not expire or require a login. Before you move or expand storage, list which attachments are marked public, and confirm that sensitive doctypes such as payroll, bank details and customer identity documents cannot be uploaded as public. Also confirm that your reverse proxy does not expose the private files path directly.
Filesystem and mount permissions
The files directory is read and written by the Frappe bench process, so its owner, group and mode should allow that account and nothing broader. If you mount network storage or a separate volume for attachments, confirm the mount options, the ownership after reboot and the backup account's read access. Ask your storage team who else has shell or hypervisor access to the volume that holds the files.
Malware scanning of uploads
ERPNext does not replace an antivirus or content scanning control for uploaded files. Confirm whether your organization requires scanning at upload time, on a schedule, or before files leave the system, and who owns the scanner and its signature updates. Decide what happens to a file that fails a scan, including whether it is quarantined, removed or kept with a warning.
Retention and deletion of personal data
Attachments that contain personal data fall under the same retention rules as the records they support, and deleting a customer or employee record does not automatically remove its files from disk. Agree retention periods with your legal or privacy team, then confirm how a deletion request reaches attachments, backups and any copies made for reports. Document which files are kept for tax or audit reasons.
Logging of file access
Confirm which file views, downloads and deletions your deployment records, and where those logs are kept and how long they live. Standard application logs may not capture every download, so decide whether you need web server access logs or an additional audit trail for files tied to regulated data. Make sure log retention does not outlast the file retention policy for the same personal data.
Questions teams ask about ERPNext attachment storage
Can ERPNext store attachments in S3 natively?
No. Based on the current design, ERPNext has no native setting that uploads attachments to S3 or any other object store, so attachments are written to the local filesystem of the site, in its private and public files directories. Moving them to object storage means adding a custom storage layer or a third-party app. That work has to cover uploads, downloads, previews, deletion, permission checks and backups, and it has to be tested on a staging copy first. Confirm the behavior of your exact ERPNext version before you plan around it, because file handling is an area where changes are possible between releases.
What does an attachment storage project cost?
The cost depends on what you change, not on the ERPNext license, which is free to self-host according to the ERPNext pricing page. The main drivers are the number of sites and benches, the total volume and count of files, whether you only trim and archive or also move storage to a new backend, the amount of custom code, and the testing and rollback plan. Hosting is a separate line: the same pricing page lists Frappe Cloud shared site hosting from 5 US dollars per month and servers from 20 US dollars per month for shared instances. Ask for a quote built from a written scope that lists each of these items, with one-time work and recurring costs shown separately.
How long does an attachment cleanup take?
Duration follows the data volume and the number of records that reference files. The biggest factors are the count and total size of the files, how many documents link to them, how much of the cleanup must be verified by a person, and the change window your business allows. Batching matters too: ERPNext's Data Import documentation advises importing only a few thousand records at a time, and bulk file operations benefit from the same discipline. The most reliable estimate comes from a dry run on a recent copy of the production database and file directories, which shows how many files would be affected and how long the process takes at that scale.
Can our team manage attachment growth in-house?
Your team can usually handle the first steps alone: measure which doctypes hold the most attachments, identify large or obsolete files, and write a retention rule. The harder parts need a skilled operator: changing the storage backend, writing and testing cleanup code, and proving that restores return both the database and the files in a consistent state. Check your team's experience with bench, MariaDB, Linux and Python. If you want server-side scripts for the cleanup, note that from version 15, Server Scripts are disabled by default and must be enabled with the server_script_enabled setting, and Frappe Cloud public shared benches do not allow them.
What does the work need from our side?
Expect to provide access and decisions, not just time. The work typically needs administrative access to the servers or Frappe Cloud bench, read access to the database and file directories, and a staging copy that matches production closely enough to test deletions and restores. You will also need written retention rules from your records, legal or compliance owners, a list of doctypes that hold regulated documents, a named approver for deletions, and a change window with a rollback plan. Confirm these items during scoping so that testing does not stall while approvals are sorted out.
How do backups change when attachments move or get trimmed?
Backups must cover both the database and the file directories, and they must stay consistent with each other. If attachments move to object storage, the backup scope has to include the bucket, its versioning and lifecycle settings, and the cross-reference between file records and stored objects. Deletions also change backup behavior: old backups may keep deleted files for as long as your backup retention allows, which can conflict with a deletion obligation. Test a full restore after each change, and confirm with your backup tool how it handles large file sets and incremental runs before you set the new retention window.
Why does private versus public file handling matter for storage?
Private and public files follow different access paths, so moving them changes who can read them. Private attachments are meant to be served only after ERPNext checks the user's permission, which is what protects invoices, contracts and employee documents. Public files can be reached by direct URL. Before you move anything, classify each attachment type, keep private files behind permission checks in any new storage design, and confirm that public URLs cannot expose records that should stay restricted. Review access controls with your security team, because a storage change can quietly widen exposure.
How DeployOpen scopes and delivers attachment storage work
DeployOpen starts attachment storage work with a written scope agreed before any change is made. The scope follows an environment review of the ERPNext sites, the bench layout, the disk or volume that holds the site directories, and the backup tooling in use. The review confirms where attachments live, how fast they grow, and which sites share the same storage. DeployOpen implements, hardens, backs up and supports ERPNext inside your own infrastructure, so every change runs in your cloud account, data center or air-gapped network, not on a DeployOpen-hosted system. Most engagements are fixed-scope, and a quote follows from the written scope.
Growth is measured before anything is moved or deleted. DeployOpen records current usage per site, the split between public and private files, and how the backup job treats the files directory, so the team knows what a backup actually contains and how long it takes. The backup scope is agreed explicitly, because any storage change affects restore time and retention. Proposed changes, such as a new volume, a cleanup of unused attachments, or a revised retention rule, are first applied to a staging copy of the site, where the file operations, restores and access checks are verified before production is touched.
Documentation is the last deliverable and the one operations teams depend on most. It covers the directory layout, the monitoring thresholds to set, the backup and restore steps that were tested, and the procedure for the next disk expansion. Ongoing support can be taken as a retainer, so the same engineers who made the change can review disk growth and backup results over time. Ask any partner, including DeployOpen, to confirm in writing which systems are in scope, who performs restores, and what the handover includes.

