iCloud Drive not uploading on Mac is especially frustrating when the file that refuses to leave your laptop is inside a software project. A single document may upload after a restart. A project folder is different: node_modules, .git, virtual environments, build output, caches, and logs can keep changing faster than iCloud can prepare the upload queue.
If you are trying to get code from one Mac to another, or you expect iCloud Drive to behave like a lightweight project backup, do not start by resetting your Apple ID. First prove whether uploads are broken globally or whether one developer folder is overwhelming the sync engine. The distinction saves time and avoids the common trap: forcing iCloud to rescan an even larger pile of generated files.
iCloud Drive not uploading on Mac: why developer folders are different
Most iCloud troubleshooting advice assumes a document workflow. A PDF changes. A Keynote file is saved. A photo lands on Desktop. iCloud notices one object, uploads it, and updates status on your other devices. Development folders behave more like a small database than a normal document folder.
One normal command can create an upload storm:
npm install,pnpm install, oryarn installcan add tens of thousands of files belownode_modules.git fetch,git checkout,git rebase, andgit gcupdate refs, indexes, lock files, packed objects, and loose objects inside.git.python -m venv .venv,pip install,bundle install, and similar tools create local dependency trees that can be rebuilt from manifest files.- Frameworks and build tools rewrite
.next,.nuxt,dist,build,coverage,target,DerivedData, and.cache. - Watch mode keeps writing while iCloud is still scanning the previous batch.
The hard part is not raw size. A single 3 GB archive is often simpler than a 300 MB dependency tree split into 70,000 tiny files. iCloud has to notice each filesystem event, track metadata, decide whether the file is eligible for upload, handle renames and deletes, and retry failures. If the tree keeps changing, Finder may report “uploading” without visible progress or your other Mac may never see the latest file.
Step 1: prove whether uploads fail everywhere or only in one project
Start with a clean control test outside the suspected project. Create one tiny file directly in iCloud Drive:
cd ~/Library/Mobile\ Documents/com~apple~CloudDocs
printf 'upload test\n' > lsyncer-icloud-upload-test.txt
Check icloud.com/iclouddrive or another Apple device after a few minutes. If this tiny file uploads, your Apple ID, network, and basic iCloud path are probably working. The issue is likely the folder shape or activity level of the project that is not uploading.
Remove the test file after the check:
rm lsyncer-icloud-upload-test.txt
If the tiny file does not upload either, keep the fix broad: verify you are signed in, confirm iCloud Drive is enabled, check available iCloud storage, restart the Mac, and test a different network. Avoid deleting CloudDocs caches or signing out as a reflex. Those actions can force a large rescan, which is the last thing you want if an active repository is already inside iCloud Drive.
Step 2: stop the processes that keep feeding the upload queue
iCloud cannot finish uploading a folder that never stops changing. Before moving files or running cleanup commands, quit the writers:
- package managers and installers:
npm,pnpm,yarn,pip,bundle,cargo - dev servers and watchers:
vite,next dev, webpack, Rails, Django, Phoenix, test watchers - IDEs that are indexing a freshly moved project
- Docker bind mounts, local databases, coverage reporters, and log-heavy scripts writing inside the repo
From Terminal, a quick process check can help you see whether iCloud and indexing are busy:
ps aux | egrep 'bird|cloudd|fileproviderd|mds|mdworker|node|python|ruby|xcodebuild' | grep -v grep
High CPU from bird, cloudd, or fileproviderd does not prove corruption. It often means the sync engine is reacting to a workload you created. The goal is to make the folder quiet long enough to inspect it.
Step 3: find generated folders that should not upload
Move into the project folder that is failing to upload and measure the usual suspects. These commands are intentionally simple. They give you a feel for file count, not a perfect inventory:
find node_modules -type f 2>/dev/null | wc -l
find .git -type f 2>/dev/null | wc -l
find .venv venv vendor/bundle -type f 2>/dev/null | wc -l
find .next .nuxt dist build coverage target DerivedData .cache -type f 2>/dev/null | wc -l
Then look for recent churn:
find . -type f -mmin -10 | head -80
If the output is mostly dependencies, build artifacts, cache files, logs, compiled assets, test output, or Git internals, iCloud is not failing because the project is valuable. It is struggling because the folder includes a lot of machine-generated state that does not belong in a cloud document sync queue.
Fix 1: remove rebuildable folders from the iCloud copy
If the project is already in iCloud Drive and the upload queue is clogged, reduce the queue. Keep the files that represent your work: source, docs, hand-written assets, configs, manifests, lockfiles, scripts, and small fixtures. Remove folders that can be recreated by tools.
For Node.js and frontend projects:
rm -rf node_modules .next .nuxt dist build coverage .turbo .parcel-cache .cache
For Python projects:
rm -rf .venv venv __pycache__ .pytest_cache .mypy_cache .ruff_cache
For Ruby projects:
rm -rf vendor/bundle .bundle tmp/cache log/*.log
For Xcode projects, be careful to distinguish project files from derived output. DerivedData is normally rebuildable and should not live inside a synced project backup. Your .xcodeproj, .xcworkspace, source files, assets, and project configuration are the important pieces.
Run destructive commands only after checking pwd. If you are unsure, copy the project to a safe local folder first and clean the copy instead of deleting from the only version you have.
Fix 2: move active repositories out of iCloud Drive
The durable fix is to stop developing inside iCloud Drive. Put active work in a local-only path such as ~/Developer, ~/Code, or ~/Projects. Use Git for history and collaboration. Use iCloud only for a filtered backup copy, release artifacts, documentation, or stable handoff files.
mkdir -p ~/Developer
mv ~/Library/Mobile\ Documents/com~apple~CloudDocs/my-app ~/Developer/my-app
cd ~/Developer/my-app
npm install
Do not move the folder while your editor, dev server, package manager, or test watcher is still writing to it. If the iCloud copy already has conflicts or missing files, create a fresh local checkout from Git and copy over only uncommitted work that you can verify.
Fix 3: upload a filtered project backup with rsync
If your actual goal is backup, upload a clean copy instead of the live working tree. rsync is a good manual tool because it can preview changes and exclude generated folders:
rsync -avn --delete \
--exclude 'node_modules/' \
--exclude '.git/' \
--exclude '.venv/' \
--exclude 'venv/' \
--exclude 'vendor/bundle/' \
--exclude '.next/' \
--exclude '.nuxt/' \
--exclude 'dist/' \
--exclude 'build/' \
--exclude 'coverage/' \
--exclude 'DerivedData/' \
--exclude '.cache/' \
~/Developer/my-app/ \
~/Library/Mobile\ Documents/com~apple~CloudDocs/Project-Backups/my-app/
The -n flag is the dry run. Read the output before removing it. Confirm the source and destination trailing slashes, confirm that --delete is pointed at the intended backup folder, and confirm the excluded folders are not being copied.
When the dry run looks right, run the same command without -n:
rsync -av --delete \
--exclude 'node_modules/' \
--exclude '.git/' \
--exclude '.venv/' \
--exclude 'venv/' \
--exclude 'vendor/bundle/' \
--exclude '.next/' \
--exclude '.nuxt/' \
--exclude 'dist/' \
--exclude 'build/' \
--exclude 'coverage/' \
--exclude 'DerivedData/' \
--exclude '.cache/' \
~/Developer/my-app/ \
~/Library/Mobile\ Documents/com~apple~CloudDocs/Project-Backups/my-app/
Now iCloud receives a stable backup tree: source and configuration upload, dependency junk stays local, and the upload queue has a chance to finish.
Fix 4: use .nosync selectively
macOS generally treats names ending in .nosync as excluded from iCloud Drive. That can be useful for folders you create for local scratch data:
mkdir local-db.nosync
mkdir tmp-exports.nosync
mkdir generated-reports.nosync
Do not blindly rename standard tool folders. node_modules.nosync breaks normal Node resolution unless your tooling is configured for it. Renaming .venv can confuse editors and shell scripts. .nosync is best for custom local-only scratch paths, not for making package managers fit inside iCloud Drive.
Where Lsyncer fits
Lsyncer exists for the filtered-copy workflow. Instead of keeping a long rsync command in a note, you choose a source folder, a destination, a schedule, and exclusions in a native macOS app. It skips the usual generated folders developers do not want in backups: node_modules, .git, virtual environments, build output, coverage, and caches.
It is not a replacement for Git, and it does not turn iCloud Drive into a real-time developer collaboration system. The useful pattern is narrower: keep your repo local, use Git for history, and sync a clean copy of the project to iCloud Drive, an external disk, a NAS share, or another folder. Lsyncer makes that repeatable for a one-time $19.99 purchase.
Good to upload
src,app,lib, docs, scripts, and hand-written assets.package.json, lockfiles,pyproject.toml,Gemfile, and config files.- README files, deployment manifests, small fixtures, and notes you would restore.
Usually skip
node_modules, package caches, virtual environments, and vendored dependencies..gitinternals when Git remotes already hold history.dist,build,coverage,DerivedData, logs, and temporary output.
Best practices to prevent iCloud upload problems
- Develop outside iCloud Drive. Use
~/Developeror~/Codefor active repositories. - Commit before cleanup. Git should hold important source changes before you delete rebuildable folders.
- Back up filtered copies, not live dependency trees. Source and lockfiles restore faster than a stale
node_modulesfolder. - Dry-run destructive syncs. Use
rsync -nbefore any command that includes--delete. - Keep cloud folders quiet. Avoid test watchers, dev servers, databases, and package managers writing directly inside iCloud Drive.
Related reading
- iCloud Drive stuck uploading on Mac — how to clear an existing upload queue when Finder is already stuck.
- iCloud Drive not syncing on Mac — broader sync troubleshooting for developer folders.
- rsync exclude node_modules on Mac — exact exclude patterns for clean project backups.
FAQ
Why is iCloud Drive not uploading files from my Mac?
For normal documents, the cause may be network, storage, account state, or a temporary iCloud issue. For code projects, the common cause is file churn: generated folders such as node_modules, .git, virtual environments, build output, and caches produce too many small changes for iCloud Drive to upload cleanly.
Should I put a Git repository in iCloud Drive?
Usually no. Use GitHub, GitLab, Bitbucket, or another Git remote for repository history. If you want an extra project backup in iCloud Drive, sync a filtered copy that excludes .git, dependencies, caches, and build artifacts.
Does .gitignore stop iCloud from uploading node_modules?
No. .gitignore only affects Git. iCloud Drive does not read it. To keep node_modules out of iCloud uploads, keep the active project outside iCloud Drive or create a filtered backup copy with exclusions.
Is it safe to delete node_modules to fix an upload queue?
It is normally safe if the project has a valid package manifest and lockfile, such as package.json plus package-lock.json, pnpm-lock.yaml, or yarn.lock. You can rebuild dependencies later with your package manager. Confirm you are in the right folder before deleting anything.
What is the best way to back up code to iCloud without upload problems?
Keep the live repository local, commit important work to Git, and sync a filtered copy to iCloud Drive. The copy should include source, docs, manifests, lockfiles, and configuration, while excluding dependencies, Git internals, build output, coverage, logs, and caches.