Tsx folder in temp directory filled with a lot of files
Link to reproduction
No response
Environment Info
$ cross-env PAYLOAD_CONFIG_PATH=src/payload.config.ts payload info
Binaries:
Node: 20.16.0
npm: N/A
Yarn: N/A
pnpm: N/A
Relevant Packages:
payload: 3.0.0-beta.97
next: 15.0.0-canary.138
@payloadcms/db-postgres: 3.0.0-beta.97
@payloadcms/email-nodemailer: 3.0.0-beta.97
@payloadcms/graphql: 3.0.0-beta.97
@payloadcms/next/utilities: 3.0.0-beta.97
@payloadcms/plugin-cloud: 3.0.0-beta.97
@payloadcms/plugin-nested-docs: 3.0.0-beta.97
@payloadcms/plugin-seo: 3.0.0-beta.97
@payloadcms/richtext-lexical: 3.0.0-beta.97
@payloadcms/translations: 3.0.0-beta.97
@payloadcms/ui/shared: 3.0.0-beta.97
react: 19.0.0-rc-e56f4ae3-20240830
react-dom: 19.0.0-rc-e56f4ae3-20240830
Operating System:
Platform: win32
Arch: x64
Version: Windows 10 Pro
Available memory (MB): 65459
Available CPU cores: 24
Describe the Bug
I am working with Payload V3 in development mode. I am on Windows.
After some days of development I noticed my Windows login speed getting slower and slower. It took my login speed from 1 second to 30 seconds to 2 minutes!
After some research this is caused by a huge number of files in my %TMP% directory. It turns out Payload is creating an insane amount of files in the %TMP% directory as you work with it in dev mode.
I have 900k files created by payload in a directory called tsx-Mo where Mo is my user profile name. All files are a few kb in size each but add up to be gigabytes in total file size due to sheer number of files.
Example of files created:
File name
Looks like: 17258-32e4dc7dfab8b9325c327612393a49ed992d5e71.txt
Example 1
{"code":"(()=>{\nvar __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __name=(target,value)=>__defProp(target,\"name\",{value,configurable:true});var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from===\"object\"||typeof from===\"function\"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toCommonJS=mod=>__copyProps(__defProp({},\"__esModule\",{value:true}),mod);var getCollectionIDFieldTypes_exports={};__export(getCollectionIDFieldTypes_exports,{getCollectionIDFieldTypes:()=>getCollectionIDFieldTypes});module.exports=__toCommonJS(getCollectionIDFieldTypes_exports);function getCollectionIDFieldTypes({config,defaultIDType}){return config.collections.reduce((acc,collection)=>{const customCollectionIdField=collection.fields.find(field=>\"name\"in field&&field.name===\"id\");acc[collection.slug]=defaultIDType===\"text\"?\"string\":\"number\";if(customCollectionIdField){acc[collection.slug]=customCollectionIdField.type===\"number\"?\"number\":\"string\"}return acc},{})}__name(getCollectionIDFieldTypes,\"getCollectionIDFieldTypes\");0&&(module.exports={getCollectionIDFieldTypes});\n})()\n","warnings":[],"map":{"version":3,"mappings":";suBAAA,8MAIW,SAAS,0BAA0B,CAAE,OAAQ,aAAc,EAAG,CACrE,OAAO,OAAO,YAAY,OAAO,CAAC,IAAK,aAAa,CAChD,MAAM,wBAA0B,WAAW,OAAO,KAAM,OAAQ,SAAU,OAAS,MAAM,OAAS,IAAI,EACtG,IAAI,WAAW,IAAI,EAAI,gBAAkB,OAAS,SAAW,SAC7D,GAAI,wBAAyB,CACzB,IAAI,WAAW,IAAI,EAAI,wBAAwB,OAAS,SAAW,SAAW,QAClF,CACA,OAAO,GACX,EAAG,CAAC,CAAC,CACT,CAToB","names":[],"ignoreList":[],"sources":["C:\\Git\\mobeigi.com\\app\\node_modules\\payload\\dist\\utilities\\getCollectionIDFieldTypes.js"],"sourcesContent":[null]}}
Example 2
{"code":"(()=>{\nvar __defProp=Object.defineProperty;var __getOwnPropDesc=Object.getOwnPropertyDescriptor;var __getOwnPropNames=Object.getOwnPropertyNames;var __hasOwnProp=Object.prototype.hasOwnProperty;var __name=(target,value)=>__defProp(target,\"name\",{value,configurable:true});var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:true})};var __copyProps=(to,from,except,desc)=>{if(from&&typeof from===\"object\"||typeof from===\"function\"){for(let key of __getOwnPropNames(from))if(!__hasOwnProp.call(to,key)&&key!==except)__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable})}return to};var __toCommonJS=mod=>__copyProps(__defProp({},\"__esModule\",{value:true}),mod);var populateBreadcrumbs_exports={};__export(populateBreadcrumbs_exports,{populateBreadcrumbs:()=>populateBreadcrumbs});module.exports=__toCommonJS(populateBreadcrumbs_exports);var import_formatBreadcrumb=require(\"./formatBreadcrumb.js\");var import_getParents=require(\"./getParents.js\");const populateBreadcrumbs=__name(async(req,pluginConfig,collection,data,originalDoc)=>{const newData=data;const breadcrumbDocs=[...await(0,import_getParents.getParents)(req,pluginConfig,collection,{...originalDoc,...data})];const currentDocBreadcrumb={...originalDoc,...data};if(originalDoc?.id){currentDocBreadcrumb.id=originalDoc?.id}breadcrumbDocs.push(currentDocBreadcrumb);const breadcrumbs=breadcrumbDocs.map((_,i)=>(0,import_formatBreadcrumb.formatBreadcrumb)(pluginConfig,collection,breadcrumbDocs.slice(0,i+1)));return{...newData,[pluginConfig?.breadcrumbsFieldSlug||\"breadcrumbs\"]:breadcrumbs}},\"populateBreadcrumbs\");0&&(module.exports={populateBreadcrumbs});\n})()\n","warnings":[],"map":{"version":3,"mappings":";suBAAA,4MAAiC,iCACjC,sBAA2B,2BACpB,MAAM,oBAAsB,aAAO,IAAK,aAAc,WAAY,KAAM,cAAc,CACzF,MAAM,QAAU,KAChB,MAAM,eAAiB,CACnB,GAAG,QAAM,8BAAW,IAAK,aAAc,WAAY,CAC/C,GAAG,YACH,GAAG,IACP,CAAC,CACL,EACA,MAAM,qBAAuB,CACzB,GAAG,YACH,GAAG,IACP,EACA,GAAI,aAAa,GAAI,CACjB,qBAAqB,GAAK,aAAa,EAC3C,CACA,eAAe,KAAK,oBAAoB,EACxC,MAAM,YAAc,eAAe,IAAI,CAAC,EAAG,OAAI,0CAAiB,aAAc,WAAY,eAAe,MAAM,EAAG,EAAI,CAAC,CAAC,CAAC,EACzH,MAAO,CACH,GAAG,QACH,CAAC,cAAc,sBAAwB,aAAa,EAAG,WAC3D,CACJ,EArBmC","names":[],"ignoreList":[],"sources":["C:\\Git\\mobeigi.com\\app\\node_modules\\@payloadcms\\plugin-nested-docs\\dist\\utilities\\populateBreadcrumbs.js"],"sourcesContent":[null]}}
Reproduction Steps
- Setup Payload v3 project
- Start dev mode
yarn devand work with it for some itme - Notice the build up of files in
%TMP% - Windows login process will become slower and slower as the files build up.
Adapters and Plugins
No response
I've run into this issue as well, and managed to narrow down the source of the problem.
I've started working with Payload 3 two weeks ago. Since then, over time, I've noticed Windows boot time was getting progressively longer, up to four minutes long. I've ran Windows Performance Recorder on boot and analyzed the trace.
I found out svchost was maxing out the CPU while processing one directory - C:/Users/[username]/AppData/Local/Temp/tsx-[username].
Directory contained over a milion of small (few KB each) files, with filenames like 17335-0a5134d8a3380f018513b12d4ac11a8c7f5f3dfa
Clearing out the directory solved the long boot time issue.
In VSCode I've opened Process Explorer, then opened my Payload project and started dev mode npm run dev.
When saving any of the project files, Process Explorer shows a bin.js file being called at [payloadprojectname]\node_modules\payload\bin.js path, and at the same time the amount of files in temp directory grows by a few hundred.
I've opened the bin.js file, commented out everything in it, and now no files are being generated in temp directory after saving a project file.
I'm entirely new to Node, React, Next and Payload, so I don't have necessary knowledge to understand what exactly bin.js is doing, but something in it is responsible for this behavior.
Im running:
Windows 10
VSCode: 1.95.3
Node.js: 20.18.0
Next: 15.0.3
Payload: 3.4.0
React: 19.0.0-rc-66855b96-20241106
I've found code responsible for this behavior, and a workaround for this.
When Payload's generate:types is executed (either automatically on file save, or manually from the terminal) it invokes \payload\bin.js, this part specifically:
if (!useSwc) {
const start = async () => {
// Use tsx
let tsImport = (await import('tsx/esm/api')).tsImport
const { bin } = await tsImport('./dist/bin/index.js', url)
await bin()
}
void start()
(...)
}
It utilizes Type Script Execute which creates a temp folder using Windows user name as an id and, on Windows, it doesn't clean up after itself. It's not a bug, it's like that by design. This is a Windows specific issue.
Workaround
TSX temp folder path is generated by \node_modules\.pnpm\node_modules\tsx\dist\temporary-directory-CwHp0_NW.mjs file. Path can be overwritten there.
I've set up a RamDisk (I'm using ImDisk) and hardcoded the TSX temp path to it.
It's more of a hack than a solution, but it works fine and my SSD is not getting spammed with thousands of unnecessary write cycles anymore.
@pan-czlowiek Thanks for the investigation work! I haven't worked with Payload in some time, I am now updating everything to the latest and seeing if this issue reoccurs for me again (I was on Windows 10 but am now on Windows 11 but that likely makes no difference).
So it looks like an OS "issue" - Mac cleans up after 3 days.
- Linux info: https://serverfault.com/questions/377348/when-does-tmp-get-cleared/377349#377349
- Windows info: https://superuser.com/questions/318497/do-files-in-the-temporary-folders-get-automatically-deleted/1599897#1599897
This issue has been automatically locked. Please open a new issue if this issue persists with any additional detail.