Using AI

Backing Up Obsidian to Google Drive Twice a Day: Mac rsync and the Long Japanese Filename Trap

Backing Up Obsidian to Google Drive Twice a Day: Mac rsync and the Long Japanese Filename Trap

Good morning, まさきん here.

I have set things up so that my whole set of Obsidian notes is backed up to Google Drive every day. I only meant to copy it over with the Mac’s built-in rsync, but it failed once on long Japanese filenames. Others are likely to get stuck at the same spot, so here are the steps and the workaround.

Note: this information is current as of publication. Please check the official sites for the latest conditions.

POINT
  • An Obsidian backup can be built simply by copying the vault to Google Drive with rsync
  • The rsync that ships with macOS (openrsync) failed on long Japanese filenames because it could not create its temporary file
  • Adding --inplace stops it from creating temporary files, and that got it through in my environment
  • It runs twice a day via launchd. The first run was about 20,000 files and several GB, and the exit code was 0
  • Secrets and caches are excluded, and I check the cloud side once a week

Why I added one more backup destination

The whole set of Obsidian notes is called a “vault.” Until now, I had been backing up my vault to GitHub. But having only one backup destination felt a little shaky.

So I chose Google Drive as a second place to keep it. I prepared one folder under My Drive in Google Drive for desktop. rsync copies the incremental changes there.

The other day, I wrote about cancelling Obsidian Sync. I have moved the master copy of my notes to Notion, but the vault files themselves are still on my machine. Having given up sync, I wanted to keep the backup in my own hands.

A vault is just a folder

Obsidian’s official help says notes are stored as plain text files in Markdown format. A vault is a folder on your local file system. Subfolders are included.

Settings go into the .obsidian folder directly under the vault. The help explains that things like hotkeys and themes are kept there.

In other words, backing up needs no special tools. Copy the folder somewhere else and that is your backup. It is thanks to this design that rsync can be used.

Sync and backup are different things

Obsidian’s official help explains sync and backup separately. Sync keeps your notes up to date. But, it notes, it does not protect you from data loss.

ItemSyncBackup
PurposeKeep every device in the same stateKeep a copy in a separate place
DirectionTwo-way as a ruleOne-way, from the source to the backup
When you deleteThe deletion propagates elsewhere tooDepending on settings, it stays in the backup
When something breaksThe broken state can propagate tooThe version from before it propagated may remain
Role this timeNot usedCopied with rsync twice a day

What I am doing this time is the right-hand column, backup. I do not open the Google Drive folder in Obsidian. It sits there purely as the place things get copied to.

The official help also cautions against syncing the same vault with multiple services. This is to avoid data conflicts and corruption. I think not editing the backup destination directly fits with that caution as well.

The overall setup

The mechanism has just three parts.

  1. The vault folder (e.g. ~/Notes)
  2. A backup folder under My Drive in Google Drive
  3. A shell script that calls rsync, and launchd to run it on a schedule

rsync copies to a local folder. Uploading from there onward is the job of Google Drive for desktop. The script does not call any cloud API.

The difference between mirroring and streaming

Google Drive for desktop has two ways of handling My Drive. I summarized the official help’s explanation in a table.

ItemStreamingMirroring
Where files are storedMainly in the cloudBoth in the cloud and locally
Offline useOnly what you mark for offlineAlways available
Space on your computerUses almost noneUses as much as a full copy
Location on macOSUnder ~/Library/CloudStorage (cannot be changed)The folder you choose in settings

Streaming on macOS appears under “Locations” in the Finder sidebar. The default location is ~/Library/CloudStorage, and it is said that this cannot be changed.

Thinking of it as an rsync destination, it seems to break down like this. With mirroring, the copied result also stays on your machine in full. That means you use space twice over, for the vault and for the backup. Streaming saves space, but the actual files live mainly on the cloud side.

Which is right depends, I think, on how much free disk space you have. At a scale of several GB, the burden of mirroring may be small. Incidentally, Obsidian’s official help has guidance on vaults kept in Google Drive: set them to be available offline. That is about using it for sync, but the thinking seems useful as a reference.

The basic rsync command

The skeleton is about this much. The paths are generalized examples.

#!/bin/bash
SRC="$HOME/Notes/"
DEST="$HOME/GoogleDrive/vault-backup/"

rsync -a --inplace \
  --exclude '.venv/' \
  --exclude 'node_modules/' \
  --exclude '.cache/' \
  --exclude 'tmp/' \
  --exclude '.env' \
  --exclude '*.token' \
  "$SRC" "$DEST"
rc=$?
echo "$(date '+%F %T') rc=$rc" >> "$HOME/Library/Logs/vaultbackup.log"
exit $rc

Replace DEST with the actual path under your own My Drive. With streaming, it will be under ~/Library/CloudStorage.

I use only a few options.

OptionMeaning (per the man page)How I use it here
-aSets recursion, preserving timestamps and so on, all at onceIncluded
--inplaceWrites directly to the destination without creating a temporary fileIncluded (the workaround described below)
--excludeExcludes files matching a patternExcludes secrets and caches
-nA dry run that does not actually change the destinationUsed as a check before the first run
--deleteDeletes files from the destination that are not in the sourceWhether to include it depends on your policy

If you add --delete, files you deleted at the source also disappear from the backup. The behavior moves closer to sync. If you want to keep notes you deleted by mistake, I think not adding it is also a valid choice.

The trailing slash on the source needs attention too. With it, rsync copies “the contents of the folder.” Without it, the folder itself goes in one level deeper.

Where to draw the line on what to exclude

A vault tends to pick up things other than notes. I excluded the following four kinds.

KindExampleWhy exclude it
Virtual environments.venv/ and node_modules/Can be rebuilt. Huge number of files
Caches.cache/ and the likeCan be rebuilt. Contents change frequently
Temporary storagetmp/ and the likeNo need to keep
Secrets.env and token filesI don’t want to widen what sits in the cloud

I think there are two axes for the decision. Exclude what can be rebuilt. Also exclude what would hurt if it leaked. Those two.

The more backup destinations you have, the more places your secrets sit. So I set it up to leave them out from the start. I also wrote about how to hunt for secrets in the two leaks that got through even though gitleaks said “no leaks”.

You can verify your exclusions with a dry run using -n. Add -v as well and you get a list of the files that would be copied. It is reassuring to check that no secret filenames show up.

Try the fee simulator and get 100 points, no sign-up required With backups sorted, review your phone bill with Rakuten Mobile too

Clicking this opens the Rakuten login page. Once you log in, you’ll see the campaign details.

The stumble: it failed on long Japanese filenames

The first run stopped partway through. The cause was files with long Japanese filenames.

What appeared in the error was a function name, mkstempat. It said that creating a temporary file had failed. The cause was that the temporary file’s name exceeded 255 bytes.

Here is how it works. rsync normally creates a temporary file at the destination. When the transfer finishes, it moves it to the real name. The rsync man page at samba.org also describes this default behavior.

The temporary file’s name is longer than the original name. So even when the original name only just fits, the temporary file’s name can go over the limit.

Warning

The file itself can exist, yet it fails only when being copied. That is because, even though the original filename is within the limit, the temporary file’s name exceeds it. If you give your notes longish Japanese titles, you may be prone to hitting this.

How many Japanese characters is 255 bytes?

In the macOS headers, NAME_MAX is defined as 255. The comment reads “max bytes in a file name.”

From here it is arithmetic. Most Japanese characters take 3 bytes each in UTF-8. Divide 255 by 3 and you get 85. So for a name made up only of Japanese, roughly 85 characters is the guide. If an extension or single-byte characters are mixed in, the number shifts a little.

That said, the story is a bit more complicated. On the Apple Developer Forums, an Apple support engineer gives a different explanation as well: the limit of APFS itself is 255 characters, which doesn’t line up with NAME_MAX. It also said that the limit varies with the volume format.

So I treat “roughly 85 characters” as a guide on the safe side. The limit that actually applies may change depending on what mechanism the destination folder sits on top of.

The workaround is —inplace

The fix was simply adding one option. --inplace.

The openrsync man page explains that it operates directly on the destination file without creating a temporary file. Since no temporary file is created, the problem of the name getting longer doesn’t occur either. In my environment, this got it through to the end.

There are trade-offs, though. The cautions that the samba.org man page lists are along these lines.

The destination this time is a backup folder that nobody opens. Even if it stops, the next run copies it again. So I judged this an acceptable trade-off for this use.

Shortening the filenames is another option. But renaming about 20,000 files was not realistic.

rsync on macOS is openrsync

To begin with, rsync on the Mac is not what it used to be inside. On recent macOS, the standard rsync is an implementation called openrsync.

Apple publishes the source of its rsync. That repository contains an openrsync directory. The man page is also titled “openrsync.” It is described as compatible with protocols 27 to 29 of the samba.org version.

The switch is said to have happened around macOS Sequoia 15.4. However, I could not confirm it in Apple’s official release notes. So I will leave it at “is said to.”

There is one practical caution. rsync examples you find online won’t necessarily work as is. It seems best to check the options you use by running man rsync on your own machine.

Running it twice a day with launchd

I left the scheduled execution to launchd. In Apple’s developer documentation, cron still works but is not recommended. It directs you to use launchd.

The time is specified with a key called StartCalendarInterval. The skeleton of the plist looks like this. The job name and times are examples.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.example.vaultbackup</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/bash</string>
    <string>/Users/yourname/bin/vaultbackup.sh</string>
  </array>
  <key>StartCalendarInterval</key>
  <array>
    <dict>
      <key>Hour</key><integer>3</integer>
      <key>Minute</key><integer>30</integer>
    </dict>
    <dict>
      <key>Hour</key><integer>13</integer>
      <key>Minute</key><integer>30</integer>
    </dict>
  </array>
  <key>StandardOutPath</key>
  <string>/tmp/vaultbackup.out.log</string>
  <key>StandardErrorPath</key>
  <string>/tmp/vaultbackup.err.log</string>
</dict>
</plist>

According to the launchd.plist man page, you can list multiple time dictionaries. For twice a day, you write two dictionaries. Any field you leave out is treated as “all.”

I set it for two runs, in the small hours and just after midday. The early-morning run picks up the previous day’s work. The early-afternoon run picks up the morning’s work.

How sleep is handled differs from cron. Apple’s documentation says that if the machine was asleep at the scheduled time, the job runs when it wakes.

If you are used to writing cron, you may also like my post on the day-of-month and day-of-week trap in cron. With scheduled jobs, I believe double-checking after you write them matters.

Results of the first run and the scheduled runs

The first run was about 20,000 files and several GB. The first run after adding --inplace finished normally. The exit code was 0.

The scheduled run from launchd also finished with 0. Running it by hand, and running it on schedule. I checked both because the environments they run in differ slightly.

However, this means “it was copied to the local backup folder.” Uploading to the cloud is a separate matter. The initial upload is taking time. As of this post, I have not yet been able to confirm that it completed. So I am not writing that result.

Checking the cloud side once a week

Even if rsync’s exit code is 0, that doesn’t mean the files reached the cloud. So I set up a separate check on whether they arrived. The frequency is just once a week.

I look at two things.

  1. Freshness: whether the files on the cloud side carry recent dates
  2. Contents: whether I can actually open and read a file

By date alone, even a corrupted file looks new. Isn’t it only once you have opened and read it that you can call it “a backup you can restore from”?

I don’t do it every day because I wouldn’t keep it up. I decided weekly is enough here.

Don’t put failure notifications in the script

The script does not send notifications when it fails. I designed it to leave that to the monitoring I already have.

The script has only two jobs. Copy. Record the exit code in a log. Those two.

If you put notifications in too, notification settings and secrets creep into the script. If monitoring is gathered in one place, then even as jobs increase there is only one place to fix.

Why I passed on Time Machine

On a Mac, Time Machine is also a candidate. Obsidian’s official help lists it too, as an OS tool.

But on my Mac, no backup disk was set up. It can’t be used as is. According to Apple’s support page, an external storage device is required. The suggested capacity is at least twice that of your Mac.

I didn’t go as far as preparing that this time, and passed. Time Machine is a tool that protects the whole Mac. Its role may be a little different from my aim here of getting just the vault out to another place.

Common mistakes and pitfalls

Having built this, here are the points where I felt it was easy to stumble.

The one I actually hit was the first. I intend to guard against the fifth with the weekly check.

Things to confirm before you start

CHECK
  • The location of the vault folder, and its approximate file count and size
  • Free space in Google Drive and free disk space on your computer
  • Whether My Drive is set to streaming or mirroring
  • Whether there are any .env or token files in the vault
  • Whether there are any long filenames, such as over 80 Japanese characters
  • Whether a dry run with -n shows the files you intend to copy

Frequently asked questions

Q. Is Google Drive alone enough for backing up Obsidian?

With only one place, you are stuck when that place is unavailable. Obsidian’s official help also explains that the cloud is both an alternative to and a complement to physical storage. I went with two places, counting GitHub.

Q. Can I open the vault in Google Drive directly?

Obsidian’s official help says syncing via Google Drive is not officially supported. In this setup too, the premise is that the backup is never opened. I think it is safest to edit only in the original vault.

Q. Is it fine to always use --inplace?

It depends on the use. The man page cautions that the destination is in a half-finished state during transfer. For a backup destination nobody opens, the impact can probably be called small.

Q. What about installing rsync from Homebrew?

Installing the samba.org version of rsync separately is another approach. But I haven’t tried it. This time I dealt with it by adding --inplace.

Q. Isn’t twice a day too often?

rsync copies only the differences. If nothing has changed, it finishes having done almost nothing. The burden of adding runs is small, so it may be best to decide based on how much time you can afford to lose.

Q. What happens if the Mac is asleep?

According to Apple’s documentation, a job whose time passed during sleep runs when the machine wakes. How it is handled when the power was off needs checking separately.

Q. If I delete a note at the source, does it disappear from the backup too?

Unless you have added --delete, it stays in the backup. If you add it, files not in the source also disappear from the backup. Which you choose depends on what you expect from the backup.

Q. Where do I see whether the upload has finished?

You can check sync status in the Google Drive for desktop app. I have not yet been able to confirm completion of my initial upload. In the weekly check, I plan to go as far as opening and reading a file.

Official sources I referred to

Summary

An Obsidian vault is just a folder. So I was able to build a daily backup with nothing but rsync and launchd.

Where I stumbled was long Japanese filenames. Adding a single --inplace gets it through, but it is worth knowing there is a trade-off.

Confirming that it reached the cloud is still to come. Why not start with a dry run using -n on your own vault?

Once you have sorted out a “monthly system” like backups, you may be able to look over your monthly phone bill with the same eye.

Try the fee simulator and get 100 points, no sign-up required Check your monthly phone bill with Rakuten Mobile

Clicking this opens the Rakuten login page. Once you log in, you’ll see the campaign details.

This article contains affiliate advertising. If you sign up for a product or service through a link on this site, we may receive compensation from the partner company. The site operator is also an employee of Rakuten Group and may receive compensation through an employee referral program. The content and opinions here are based on the operator’s own experience and research regardless of any advertising relationship, but please read with the above in mind. See the Disclaimer & Affiliate Disclosure for details. Disclaimer & Affiliate Disclosure

This article includes machine-translated content. Please check the official Rakuten Mobile multilingual page for exact terms.

If you have concerns about Rakuten Mobile coverage or signal quality, you can consult through the official signal improvement request form .

ABOUT THE AUTHOR
まさきん

Rakuten Group employee · Digital Marketer (holds a Financial Planner qualification)

In his early 40s, part of a dual-income household with four kids. Works as a digital marketer at Rakuten Group, while also using his Financial Planner (FP) qualification to focus on household finances and building assets.

View Profile

Related Articles

RELATED
Gemini (Google AI Pro) Family Sharing Covers Up to 5 Family Members: Setup Steps and Scope Using AI

Gemini (Google AI Pro) Family Sharing Covers Up to 5 Family Members: Setup Steps and Scope

Google AI Pro can be shared with up to 5 family members besides the manager. The Gemini app and storage are shared, while YouTube Premium Lite is for the manager only. Flow limits are shared across the family. I went through the official help to sort out the setup steps and how child accounts are handled.

2026.10.13 · 11 min read
3 Reasons Your AI Subscription Billing Date Does Not Match Your Budget: Claude Upgrades Change It Using AI

3 Reasons Your AI Subscription Billing Date Does Not Match Your Budget: Claude Upgrades Change It

If you upgrade Claude to Max mid-month, your billing cycle resets and that day becomes your new billing date. The yen conversion of dollar charges is set when the data reaches your card company, and statements and budgeting apps lag by a few days. Here are 5 steps to decide the month using the receipt email as your source of truth.

2026.10.13 · 12 min read
Turning Unprocessed freee Accounting Transactions into a Monthly Reconciliation Run: 7:30 on the 5th, 3 Categories, and a Cap of 15 Items Handed to a Human Using AI

Turning Unprocessed freee Accounting Transactions into a Monthly Reconciliation Run: 7:30 on the 5th, 3 Categories, and a Cap of 15 Items Handed to a Human

About 18 unprocessed transactions sat untouched in freee Accounting across 6 weekly checks. Here is my design for a reconciliation run on my home Mac at 7:30 a.m. on the 5th of each month, and where I drew the line: one monthly task for the items that can be confirmed, and one task each, capped at 15, for the ones that need a human decision.

2026.10.12 · 13 min read
Switch to Rakuten Mobile, get up to 14,000 points Try the fee simulator and get 100 points, no sign-up required →
Apply Now →