mbsync(1)

okay so bestie, you're reading the mbsync(1) manual page πŸ’– this is part 1, and we're about to make syncing IMAP4 and Maildir mailboxes make sense, no cap. Let's get into it.

✨ NAME ✨

mbsync β€” synchronize IMAP4 and Maildir mailboxes. Periodt. πŸ’…

🌈 SYNOPSIS 🌈

mbsync [options ...] {{channel[:box[{,|\n}...]]|group} ...|-a}
mbsync --list-stores [options ...] [store ...]

πŸ’… DESCRIPTION πŸ’…

So like, mbsync is a command-line app that synchronizes mailboxes. Right now it supports Maildir and IMAP4 mailboxes. New messages, message deletions, and flag changes can be propagated both ways, and you can select the operation set in a super fine-grained way. Slay.

Synchronization is based on unique message identifiers (UIDs), so no identification conflicts can occur (unlike with some other mail synchronizers). On the other hand, mbsync is susceptible to UID validity changes (but it will recover just fine if the change is unfounded). It's giving resilient.

Synchronization state is kept in one local text file per mailbox pair; these files are protected against concurrent mbsync processes. Mailboxes can be safely modified while mbsync operates (see INHERENT PROBLEMS below for a minor exception). Multiple replicas of each mailbox can be maintained. Obsessed with the flexibility, honestly. ✨

πŸ‘‘ OPTIONS πŸ‘‘

  • -c, --config file β€” read configuration from file. By default, the configuration is read from $XDG_CONFIG_HOME/isyncrc, and if that does not exist, ~/.mbsyncrc is tried in turn. $XDG_CONFIG_HOME defaults to ~/.config if not set. πŸ’–
  • -a, --all β€” select all configured Channels. Any Channel/Group specifications on the command line are ignored. Bye. πŸ’…
  • -l, --list β€” don't synchronize anything, but list all mailboxes in the selected Channels and exit. Just a little peek. πŸ‘€
  • -ls, --list-stores β€” don't synchronize anything, but list all mailboxes in the selected Stores and exit. If no Stores are specified, all configured ones are listed. These are raw Store contents, not filtered by any Channel's Patterns. This option may be used to verify each Store's configuration. Vibe check. πŸ¦‹
  • -C[f][n], --create[-far|-near] β€” override any Create options from the config file. See below. ✨
  • -R[f][n], --remove[-far|-near] β€” override any Remove options from the config file. See below. ✨
  • -X[f][n], --expunge[-far|-near] β€” override any Expunge options from the config file. See below. ✨
  • {-n|-o|-u|-g|-f|-0|-F}, {--new|--old|--upgrade|--gone|--flags|--noop|--full} {-L|-H}[n][o][u][g][f], {--pull|--push}[-new|-old|-upgrade|-gone|-flags] β€” override any Sync options from the config file. See below. πŸ”₯
  • -h, --help β€” display a summary of command line options. πŸ’–
  • -v, --version β€” display version information. ⭐
  • -y, --dry-run β€” enter simulation mode: the Channel status is queried and all required operations are determined, but no modifications are actually made to either the mailboxes or the state files. It's giving ghost mode. πŸ‘»
  • -e, --ext-exit β€” return an extended exit code: add 32 or 64 to the code if any modifications were made on the far or near side, respectively; these are not mutually exclusive, so the code may be 96 if changes were both pushed and pulled. An error may be reported at the same time, so the code may be for example 65 if some changes were successfully pulled, while others failed. πŸ’€
  • -V, --verbose β€” enable verbose mode, which displays what is currently happening. Main character energy fr fr. ✨
  • -D[C][d|D][m][M][n|N][s]], --debug[-crash|-driver|-driver-all|-maildir|-main|-net|-net-all|-sync] β€” enable debugging categories:
    • C, crash β€” use built-in crash handler
    • d, driver β€” print driver calls (metadata only)
    • D, driver-all β€” print driver calls (including messages)
    • m, maildir β€” print maildir debug info
    • M, main β€” print main debug info
    • n, net β€” print network traffic (protocol only)
    • N, net-all β€” print network traffic (including payloads)
    • s, sync β€” print synchronization debug info All categories except crash implicitly enable verbose mode. Without category specification, all categories except net-all are enabled. πŸ”
  • -q, --quiet β€” suppress progress counters (this is implicit if stdout is no TTY, or any debugging categories are enabled), notices, and the summary. If specified twice, suppress warning messages as well. 🀫

πŸŽ€ CONFIGURATION πŸŽ€

The configuration file is mandatory; mbsync will not run without it. Periodt. Lines starting with a hash mark (#) are comments and are ignored entirely. Configuration items are keywords followed by one or more arguments; arguments containing spaces must be enclosed in double quotes ("), and literal double quotes and backslashes (\) must be backslash-escaped. All keywords (including those used as arguments) are case-insensitive. Bash-like home directory expansion using the tilde (~) is supported in all options which represent local paths. The reference point for relative local paths is the configuration file's containing directory. There are a few global options, the others apply to particular sections. Sections begin with a section-starting keyword and are terminated by an empty line or end of file. Every section defines an object with an identifier unique within that object class. πŸ’…

There are two basic object classes: Stores and Channels. A Store defines a collection of mailboxes; basically a folder, either local or remote. A Channel connects two Stores, describing the way the two are synchronized. There are two auxiliary object classes: Accounts and Groups. An Account describes the connection part of network Stores, so server configurations can be shared between multiple Stores. A Group aggregates multiple Channels to save typing on the command line. We love a shortcut. πŸ¦‹

File system locations (in particular, Path and Inbox) use the Store's internal path separators, which may be slashes, periods, etc., or even combinations thereof. Mailbox names, OTOH, always use canonical path separators, which are Unix-like forward slashes. Slay. ✨

🌸 All Stores 🌸

These options can be used in all supported Store types. The term "opposite Store" refers to the other Store within a Channel. The special mailbox INBOX exists in every Store; its physical location in the file system is Store type specific. πŸ’–

  • Path path β€” the location of the Store in the (server's) file system. If this is no absolute path, the reference point is Store type specific. This string is prepended to the mailbox names addressed in this Store, but is not considered part of them; this is important for Patterns and Create in the Channels section. Note that you must append a slash if you want to specify an entire directory. (Default: none) πŸ“
  • MaxSize size[k|m][b] β€” messages larger than size will have only a small placeholder message propagated into this Store. This is useful for avoiding downloading messages with large attachments unless they are actually needed. To upgrade the placeholder to the full message, it must be flagged, and the Upgrade operation executed. Caveats: Setting a size limit on a Store you never read directly (which is typically the case for servers) is not recommended, as you may never notice that affected messages were not propagated to it. Also, as flagging is (ab-)used to request an upgrade, changes to the message's flagging state will not be propagated in either direction until after the placeholder is upgraded. K and M can be appended to the size to specify KiBytes resp. MeBytes instead of bytes. B is accepted but superfluous. If size is 0, the maximum message size is unlimited. (Default: 0) πŸ“¦
  • MapInbox mailbox β€” create a virtual mailbox (relative to Path) which aliases the INBOX. Makes sense in conjunction with Patterns in the Channels section, though with a Maildir near side, you probably want to place Inbox under Path instead. This virtual mailbox does not support subfolders. πŸ¦‹
  • Flatten delim β€” flatten the hierarchy within this Store by substituting the canonical hierarchy delimiter / with delim. This can be useful when the MUA used to access the Store provides suboptimal handling of hierarchical mailboxes, as is the case with Mutt. A common choice for the delimiter is .. Note that flattened sub-folders of the INBOX always end up under Path, including the "INBOXdelim" prefix. πŸ‘‘
  • Trash mailbox β€” specifies a mailbox (relative to Path) to copy deleted messages to prior to expunging. See RECOMMENDATIONS and INHERENT PROBLEMS below. (Default: none) πŸ—‘οΈ
  • TrashNewOnly yes|no β€” when trashing, copy only not yet propagated messages. This makes sense if the opposite Store has a Trash as well (with TrashNewOnly no). (Default: no) πŸ’…
  • TrashRemoteNew yes|no β€” when expunging the opposite Store, copy not yet propagated messages to this Store's Trash. When using this, the opposite Store does not need an own Trash at all, yet all messages are archived. (Default: no) πŸ’…

πŸ¦‹ Maildir Stores πŸ¦‹

The reference point for relative Paths is the configuration file's containing directory.

As mbsync needs UIDs, but no standardized UID storage scheme exists for Maildir, mbsync supports two schemes, each with its pros and cons. The native scheme is stolen from the latest Maildir patches to c-client and is therefore compatible with pine. The UID validity is stored in a file named .uidvalidity; the UIDs are encoded in the file names of the messages. The alternative scheme is based on the UID mapping used by isync versions 0.8 and 0.9.x. The invariant parts of the file names of the messages are used as keys into a Berkeley database named .isyncuidmap.db, which holds the UID validity as well. The native scheme is faster, more space efficient, endianness independent and "human readable", but will be disrupted if a message is copied from another mailbox without getting a new file name; this would result in duplicated UIDs sooner or later, which in turn results in a UID validity change, making synchronization fail. The alternative scheme would fail if a MUA changed a message's file name in a part mbsync considers invariant; this would be interpreted as a message deletion and a new message, resulting in unnecessary traffic. Mutt is known to work fine with both schemes. Use mdconvert to convert mailboxes from one scheme to the other. πŸ› οΈ

  • MaildirStore name β€” define the Maildir Store name, opening a section for its parameters. πŸŽ€
  • AltMap yes|no β€” bestie, this flips on the alternative UID storage scheme for the mailboxes living in this Store πŸ’…. Here's the tea though: it does NOT touch mailboxes that already have a UID storage scheme β€” you gotta use mdconvert to change those. Peep RECOMMENDATIONS below for the whole story. (Default: no)
  • Inbox path β€” where your INBOX lives 🏠. This one is not relative to Path, but you're absolutely allowed to tuck the INBOX inside the Path if that's the vibe. (Default: ~/Maildir)
  • InfoDelimiter delim β€” the character that separates the info field from a message's basename πŸŽ€. The Maildir standard says it should be the colon, but lol, that is incompatible with DOS/Windows file systems. (Default: the value of FieldDelimiter)
  • SubFolders Verbatim|Maildir++|Legacy β€” the on-disk folder naming style for hierarchical mailboxes 🌳. Heads up: this option does literally nothing when Flatten is used. So say we've got mailboxes with the canonical paths top/sub/subsub and INBOX/sub/subsub β€” here's what each style spits out on disk:
    • Verbatim β€” Path/top/sub/subsub and Inbox/sub/subsub (this is the style you probably want, no cap)
    • Maildir++ β€” Inbox/.top.sub.subsub and Inbox/..sub.subsub (this style plays nice with Courier and Dovecot β€” but note that the mailbox metadata format is not compatible). Also, attempts to set Path in this mode get rejected, periodt.
    • Legacy β€” Path/top/.sub/.subsub and Inbox/.sub/.subsub (this is mbsync's historical style, a true throwback 🫢)

(Default: unset; it will error out when sub-folders are encountered 😭)


πŸ¦‹ IMAP4 ACCOUNTS πŸ¦‹

  • IMAPAccount name β€” define the IMAP4 Account name, which opens up a whole section for its parameters ✨
  • Host host β€” the DNS name or IP address of the IMAP server 🌐. If Tunnel is used, you only need this when TLSType is not None and CertificateFile isn't used β€” in that case the host name gets used for certificate subject verification.
  • Port port β€” the TCP port number of the IMAP server πŸ”Œ. (Default: 143 for IMAP, 993 for IMAPS) If Tunnel is used, this setting is ignored.
  • Timeout timeout β€” the connect and data timeout for the IMAP server, in seconds ⏱️. Zero means unlimited. (Default: 20)
  • User username β€” the login name on the IMAP server πŸ‘€.
  • UserCmd [+]command β€” give a shell command to fetch a user instead of hardcoding one, so you can script the whole username-retrieval situation 🎬. The command must produce exactly one line on stdout; the trailing newline is optional. Slap a + in front of the command to signal that it produces TTY output (like a prompt); forgetting that will merely make your output messier πŸ™ˆ. And remember to backslash-escape double quotes and backslashes you embed into the command.
  • Pass password β€” the password for username on the IMAP server πŸ”‘. Note that this option is not required. If neither a password nor a password command is specified in the config file, mbsync will just prompt you for one.
  • PassCmd [+]command β€” give a shell command to fetch a password instead of hardcoding one, so you can use password files and agents πŸ•΅οΈ. See UserCmd above for the deets.
  • UseKeychain yes|no β€” whether to pull the password from the macOS Keychain 🍎. (Default: no)

You can create the keychain item you need like this:

security add-internet-password -r imap -s Host -a User -w password [ -T /path/to/mbsync ]
  • Tunnel command β€” a command to run to establish the connection instead of opening a TCP socket πŸš‡. This is how you run an IMAP session over an SSH tunnel, for example.
  • AuthMechs type ... β€” the list of acceptable authentication mechanisms πŸ”. On top of the mechanisms listed in the SASL registry (link below), the legacy IMAP LOGIN mechanism is also known. The wildcard * represents all mechanisms deemed secure enough for the current TLSType setting. The mechanism actually used is the most secure choice from the intersection of this list, the list the server supplies, and the installed SASL modules 🧠. (Default: *)
  • TLSType {None|STARTTLS|IMAPS} β€” pick your connection security/encryption method πŸ›‘οΈ:
    • None β€” no security. This is the default when Tunnel is set, since tunnels are usually secure.
    • STARTTLS β€” security gets established via the STARTTLS extension after connecting the regular IMAP port 143. Most servers support this, so it's the default (unless a tunnel is used).
    • IMAPS β€” security gets established by starting TLS negotiation right after connecting the secure IMAP port 993.
  • TLSVersions {+|-}{1.0|1.1|1.2|1.3} ... β€” add/remove the specified TLS versions to/from the set of acceptable choices 🧚. Use old versions only when the server has problems with newer ones. Note that new versions are automatically enabled as soon as OpenSSL supports them, even if mbsync doesn't recognize them yet. (Default: All starting with 1.2).
  • SystemCertificates yes|no β€” whether the system's default CA (certificate authority) certificate store should be used to verify certificate trust chains πŸ”. Disable this if you want to trust only hand-picked certificates. (Default: yes)
  • CertificateFile path β€” a file containing additional X.509 certificates used to verify server identities πŸ“œ. It may contain two types of certificates:
    • Host β€” these certificates are matched only against the received server certificate itself. They are always trusted, regardless of validity. A typical use case would be forcing acceptance of an expired certificate. You can grab these with the mbsync-getcert tool; make sure to verify their fingerprints before trusting them, or transfer them securely from the server's network (if it can be trusted beyond the server itself) ⚠️.
    • CA β€” these certificates are used as trust anchors when building the certificate chain for the received server certificate. They supplant or supersede the system's trust store, depending on the SystemCertificates setting; it is not necessary and not recommended to specify the system's trust store itself here. The trust chains are fully validated βœ….
  • ClientCertificate path β€” a file containing a client certificate to send to the server πŸͺͺ. ClientKey should also be specified. Note that client certificate verification is usually not required, so it's unlikely you need this option.
  • ClientKey path β€” a file containing the private key corresponding to ClientCertificate πŸ—οΈ.
  • CipherString string β€” the OpenSSL cipher string for connections secured with TLS up to version 1.2 (but not 1.3 and above) πŸ”’. The format is described in ciphers(1). (Default: empty, which implies system-wide policy)
  • PipelineDepth depth β€” the maximum number of IMAP commands that can be simultaneously in flight πŸš€. Setting this to 1 disables pipelining. This is mostly a debugging option, but it can also limit average bandwidth consumption (GMail may require this if you have a very fast connection), or spare flaky servers like M$ Exchange πŸ’€. (Default: unlimited)
  • DisableExtension[s] extension ... β€” disable the use of specific IMAP extensions 🚫. This can be used to work around bugs in servers (and possibly mbsync itself πŸ™ˆ). (Default: empty)

🌈 IMAP STORES 🌈

The reference point for relative Paths is whatever the server feels like it should be; probably the user's $HOME or $HOME/Mail on that server 🏑. The location of INBOX is up to the server too, and it's usually irrelevant.

  • IMAPStore name β€” define the IMAP4 Store name, opening a section for its parameters ✨
  • Account account β€” which IMAP4 Account to use πŸ”—. Instead of defining an Account and referencing it here, you can also just specify all the Account options directly in the Store's section β€” which makes sense if an Account is only used for one Store anyway.
  • UseNamespace yes|no β€” selects whether the server's first "personal" NAMESPACE should be prefixed to mailbox names 🏷️. Disabling this makes sense for some broken IMAP servers. This option is meaningless if a Path was specified. (Default: yes)
  • PathDelimiter delim β€” the server's hierarchy delimiter πŸ”ͺ. (Default: taken from the server's first "personal" NAMESPACE) Do not abuse this to re-interpret the hierarchy. Use Flatten instead.
  • SubscribedOnly yes|no β€” selects whether to synchronize only mailboxes that are subscribed to on the IMAP server πŸ“¬. In technical terms, if this option is set, mbsync will use the IMAP command LSUB instead of LIST to look for mailboxes in this Store. This option makes sense only in conjunction with Patterns. (Default: no)

πŸ’… CHANNELS πŸ’…

  • Channel name β€” define the Channel name, opening a section for its parameters ✨
  • {Far|Near} :store:[mailbox] β€” specify the far resp. near side Store to be connected by this Channel πŸ›€οΈ. If Patterns are specified, mailbox is interpreted as a prefix which is not matched against the patterns, and which is not affected by mailbox list overrides. Otherwise, if mailbox is omitted, INBOX is assumed.
  • Pattern[s] [!]pattern ... β€” instead of syncing just one mailbox pair, sync all mailboxes that match the pattern(s) 🌸. The mailbox names are the same on the far and near side. Patterns are IMAP4 patterns, i.e., * matches anything and % matches anything up to the next hierarchy delimiter. Prepending ! to a pattern makes it an exclusion. Multiple patterns can be specified (either by supplying multiple arguments or by using Pattern multiple times); later matches take precedence πŸ‘‘.

Note that INBOX is not matched by wildcards, unless it lives under Path.

The mailbox list selected by Patterns can be overridden by a mailbox list in a Channel reference (a Group specification or the command line).

Example: "Patterns % !Trash"

  • MaxSize size[k|m][b] β€” literally the same energy as the option with the same name over in the Stores section, except this one hits Far and Near at the same time. ⚠️ Heads up bestie: this actually modifies the Stores, so if you're reusing those Stores across multiple Channels, do not come crying to me when your settings start beefing with each other. Keep them consistent.
  • MaxMessages count β€” caps how many messages get to stay in each near side mailbox. Perfect for those mailboxes where you keep the full archive chillin' on the server but you only wanna mirror the last few messages (mailing lists, I'm looking at you 🫢). The messages that arrived first get deleted first β€” and no, that has nothing to do with the actual date on the message, it's arrival order, periodt. Messages that are flagged (a.k.a. marked as important) plus β€” by default β€” unread messages will not get auto-deleted. If count is 0, then the max number of messages is unlimited. (Global default: 0).
  • ExpireUnread yes|no β€” decides whether unread messages get caught up in MaxMessages. Normally unread messages are treated as important, so they never expire β€” which is the whole point, you never miss new messages even after ghosting your inbox for like a month. But if your archive is by design stuffed with a huge pile of unread messages, then treating them all as important would basically defeat MaxMessages entirely πŸ’€. That's when you flip this on. (Global default: no).
  • ExpireSide Far|Near β€” picks which side gets expired when MaxMessages is configured. (Global default: Near).
  • Sync {None|[Pull] [Push] [New] [Old] [Upgrade] [Gone] [Flags] [Full]} β€” choose which synchronization operation(s) to run:
    • Pull β€” propagate changes from far to near side.
    • Push β€” propagate changes from near to far side.
    • New β€” propagate newly appeared messages.
    • Old β€” propagate previously skipped, failed, and expired messages. This one is (relatively) expensive and can repeatedly spit out error messages, so it always has to be specified explicitly. No sneaky defaults here.
    • Upgrade β€” upgrade placeholders to full messages. Only useful if you've got a MaxSize configured.
    • Gone β€” propagate message disappearances. Only applies to messages that are actually gone, like, expunged gone. The affected messages in the opposite Store just get marked as deleted β€” meaning they won't really be deleted until that Store gets expunged. πŸ‘»
    • Flags β€” propagate flag changes. And yes, Deleted/Trashed counts as a flag too, which is extra interesting if you're running mutt with the maildir_trash option.
    • Full β€” an alias for "New Upgrade Gone Flags". This is the global default, bestie.
    • None (--noop on the command line) β€” don't propagate anything. Useful if you just wanna expunge and nothing else.

So Pull and Push are direction flags, while New, Old, Upgrade, Gone, and Flags are type flags. These two flag classes make up a whole two-dimensional matrix (a table, yes, we're doing math πŸ’…). Its cells are the individual actions to perform. And there are two styles of asserting those cells:

  1. In the first style, the flags select entire rows/columns of the matrix. Only the cells selected both horizontally and vertically get asserted. Specifying no direction is like specifying both directions, and specifying no type is like specifying Full. For example, "Sync Pull New Flags" will propagate new messages and flag changes from the far side to the near side, "Sync New Gone" will propagate message arrivals and deletions both ways, and "Sync Push" will propagate all changes from the near side to the far side.
  2. In the second style, direction flags get concatenated with type flags; every compound flag immediately asserts a cell in the matrix. On top of at least one compound flag, the individual flags can be used too β€” but unlike the first style, they immediately assert all cells in their respective row/column (the one exception being Old). For example, "Sync PullNew PullGone Push" will propagate message arrivals and deletions from the far side to the near side and any changes (except old messages) from the near side to the far side.
⚠️ Note that it is not allowed to assert a cell in two different ways, e.g. "Sync PullNew Pull" and "Sync PullNew Gone Push" will induce error messages. Pick a lane, babe.

None may not be combined with any other operation. At all. Ever.

  • Create {None|Far|Near|Both} β€” automatically create missing mailboxes [on the far/near side]. Otherwise mbsync just prints an error message and skips that mailbox pair if a mailbox and the corresponding sync state don't exist. (Global default: None)
  • Remove {None|Far|Near|Both} β€” propagate mailbox deletions [to the far/near side]. Otherwise it prints an error message and skips that mailbox pair if a mailbox doesn't exist but the corresponding sync state does. For MailDir mailboxes, deleting the cur/ subdirectory is enough to mark them as deleted. This keeps things compatible with SyncState *. ✨
Note that for safety, non-empty mailboxes are never deleted. Safety first, always.

(Global default: None)

  • Expunge {None|Far|Near|Both} β€” permanently yeet all messages [on the far/near side] that are marked for deletion. Mutually exclusive with ExpungeSolo for the same side. See RECOMMENDATIONS below. (Global default: None)
  • ExpungeSolo {None|Far|Near|Both} β€” permanently removes all messages [on the far/near side] that are both marked for deletion and have no corresponding message in the opposite Store. Together with Sync Gone, this lets you actually mirror expunges. But note, it only makes sense if nothing else is expunging the other messages that are marked for deletion. Also note that this doesn't work for IMAP Stores that don't support the UIDPLUS extension 😭. Mutually exclusive with Expunge for the same side. (Global default: None)
  • CopyArrivalDate {yes|no} β€” selects whether the messages' arrival time gets propagated along with them. Turning this on makes sense if you wanna keep that time-stamp-based message sorting intact. Note that IMAP does not guarantee the time stamp (which it calls the internal date) is actually the arrival time β€” but honestly it's usually close enough. (Global default: no)

Sync, Create, Remove, Expunge, ExpungeSolo, MaxMessages, ExpireUnread, ExpireSide, and CopyArrivalDate can all be used before any section for a global effect. Global settings get overridden by Channel-specific options, which in turn get overridden by command line switches. Hierarchy, bestie. πŸ‘‘

  • SyncState {*|path} β€” sets the location of this Channel's synchronization state files. * means the state should be saved in a file named .mbsyncstate in the near side mailbox itself. The glow-up here: you don't need to handle the state file separately if you delete the mailbox. Downside? It only works with Maildir mailboxes, obviously. πŸ™ˆ Otherwise, this is interpreted as a string to prepend to the near side mailbox name to build a complete path. Note that you must append a slash if you want to specify a directory. This option can be used outside any section for a global effect. In that case, the appended string is made up according to the pattern :far-store:far-box_:near-store:near-box (see also FieldDelimiter below). (Global default: $XDG_STATE_HOME/isync/, with a fallback to ~/.mbsync/ if only that exists. $XDG_STATE_HOME defaults to ~/.local/state if it's not set.)

πŸ‘― Groups

  • Group name [channel[:box[,...]]] ... β€” defines the Group name, opening a section for its parameters. Note that even though Groups have their own namespace, they will "hide" Channels with the same name on the command line. One or more Channels can be specified on the same line. If you supply one or more boxes to a channel, those get used instead of whatever's specified in the Channel's Patterns. Same deal on the command line, except there newlines can be used as mailbox name separators too. 🌈
  • Channel[s] channel[:box[,...]] ... β€” adds the specified Channels to the Group. This option can be specified multiple times within a Group.

🌍 Global Options

  • FSync yes|no β€” selects whether mbsync performs forced flushing, which decides your level of data safety after system crashes and power outages ⚑. Disabling it is reasonably safe for file systems mounted with data=ordered mode. Enabling it is a wise choice for file systems mounted with data=writeback, especially modern ones like ext4, btrfs and xfs. The performance impact on older file systems may be disproportionate. (Default: yes)
  • FieldDelimiter delim β€” the character used to delimit fields in the string appended to a global SyncState. mbsync prefers to use the colon, but that's incompatible with DOS/Windows file systems. This option is meaningless for SyncState if the latter is *, obviously. However, it also determines the default of InfoDelimiter. (Global default: ; on Windows, : everywhere else)
  • BufferLimit size[k|m][b] β€” the per-Channel, per-direction instantaneous memory usage above which mbsync will refrain from using more memory. Note that this is not an absolute limit, since even a single message can consume more memory than this. (Default: 10M)

πŸ–₯️ CONSOLE OUTPUT

If mbsync's output is connected to a console, it'll print progress counters by default. The output looks like this:

C: 1/2  B: 3/4  F: +13/13 *23/42 #0/0 -0/0  N: +0/7 *0/0 #0/0 -0/0

This represents the cumulative progress over Channels, boxes, and messages affected on the far and near side, respectively. The message counts represent added messages, messages with updated flags, trashed messages, and expunged messages, respectively. No attempt is made to calculate the totals in advance, so they grow over time as more information gets gathered. It's giving ✨live updates✨.

Irrespective of output redirection, mbsync will print a summary of the above upon completion β€” except in quiet mode. 🀫

πŸ’– RECOMMENDATIONS πŸ’–

okay bestie, listen up, these are the little life hacks that make your setup not a mess:

Make sure your IMAP server does not auto-expunge deleted messages β€” it's slow, and honestly semantically kinda questionable. Specifically, Gmail needs to be configured not to do it. no cap.

By default, mbsync will not delete any messages β€” expunges are propagated by marking the messages as deleted in the opposite Store. Once you've verified that your setup actually works, you'll typically want to set Expunge to Both, so that deletions become effective. that's the glow-up moment ✨

mbsync's built-in trash functionality relies on mbsync doing the expunging of deleted messages. This is the case when it propagates deletions of previously propagated messages, and the trash is on the target Store (typically your IMAP server).

However, when you intend mbsync to trash messages which were not propagated yet, the MUA must mark the messages as deleted without expunging them (e.g., Mutt's maildir_trash option). Note that most messages are propagated a long time before they are deleted, so this is a corner case you probably do not want to optimize for. This also implies that the TrashNewOnly and TrashRemoteNew options are typically not very useful. like, they're giving "I tried" 😭

If your server supports auto-trashing (as Gmail does), it is probably a good idea to rely on that instead of mbsync's trash functionality. If you do that, and intend to synchronize the trash like other mailboxes, you should not use mbsync's Trash option at all. periodt.

Use of the Trash option with M$ Exchange 2013 requires the use of DisableExtension MOVE due to a server bug. πŸ™ˆ

When using the more efficient default UID mapping scheme, it is important that the MUA renames files when moving them between Maildir folders. Mutt always does that, while mu4e needs to be configured to do it:

(setq mu4e-change-filenames-when-moving t)

The general expectation is that a completely new filename is generated as if the message was new, but stripping the ,U=xxx infix is sufficient as well. either way, slay πŸ’…


🌸 INHERENT PROBLEMS 🌸

ngl, some things are just how they are:

Changes done after mbsync has retrieved the message list will not be synchronised until the next time mbsync is invoked. so yeah, it's not psychic, bestie.

Using Trash on IMAP Stores without the UIDPLUS extension (notably, M$ Exchange up to at least 2010) bears a race condition: messages will be lost if they are marked as deleted after the message list was retrieved but before the mailbox is expunged. There is no risk as long as the IMAP mailbox is accessed by only one client (including mbsync) at a time.

⚠️ messages will be LOST. this is not a drill. one client at a time, or you're risking your mail, fr fr. πŸ’€

πŸŽ€ FILES πŸŽ€

  • $XDG_CONFIG_HOME/isyncrc (usually ~/.config/isyncrc) β€” Default configuration file. See also the example file in the documentation directory.
  • $XDG_STATE_HOME/isync/ (usually ~/.local/state/isync/) β€” Directory containing synchronization state files.
  • ~/.mbsyncrc β€” Legacy configuration file. the old money version 🧚
  • ~/.mbsync/ β€” Legacy directory containing synchronization state files.

✨ SEE ALSO ✨

mdconvert(1), mutt(1), maildir(5)

Up to date information on mbsync can be found at http://isync.sf.net/

SASL mechanisms are listed at http://www.iana.org/assignments/sasl-mechanisms/sasl-mechanisms.xhtml


πŸ‘‘ AUTHORS πŸ‘‘

Originally written by Michael R. Elkins, rewritten and currently maintained by Oswald Buddenhagen, contributions by many others; see the AUTHORS file for details. iconic behavior, truly.


and that's the whole page, bestie! this was mbsync from isync 1.5.1, dated 2025-03-11 β€” go sync those mailboxes, you absolute main character πŸ¦‹πŸ’–

πŸ“¦ where this page comes from