This question about protocol design came into my mind regarding battery consumption on phones.
From my PC, I know there is just little Syncthing traffic when devices&folders show idle. It’s just one open TCP connection because I disabled local/global discovery and relay.
How is the Syncthing protocol designed here?
E.g. does a discovery server connection stay TCP connected, send keep alives every X seconds?
If I am connected to a relay server, does the server exchange bytes with me on top of an idle tcp connection to say keep alive / hello / poll stats in intervals?
Or can I assume “0 bytes transfer” in idle on those connections?
If there is a keepalive which Syncthing (not the OS) does, which interval is it?
Is my interpretation correct that it will cause a mobile phone’s modem to wake up every 90 seconds an the latest? Given the situation, the user is on mobile data or WiFi connection and the Android OS installed allows our app’s running native process to do so.
I have no clue what the phone and modem will do, but indeed syncthing will write something to the connection every 90s. However that’s just one connection, if you have multiple devices nothing says they will send at the same time, so “any sends” will happen more frequently most likely.
Ok, good info . I just doubt, we can improve this for phone users.
Thinking aloud…
Even if I did a test build disabling the ping, other paired devices would still wake my phone’s connection - which consumes “significant” battery according to my google research. So I couldn’t improve nor test that easily if it helped.
I’ve also read an intersting article which referred to things like GCM/FCM (“Google push”) that keep the connection open all time but avoid unnecessary data transfer to save battery. My email app also does this for IMAP, it connects, waits until the connection drops in idle, then reconnects later when it notices that.
Personally, I’ve found out that just keeping the connection to the discovery server running also drains a lot of battery. For example, if I leave Syncthing running overnight even with all remote devices paused, the battery charge drops from 80% to 60%. This is on a stable Wi-Fi connection at home, as outside, on mobile data, the situation is worse.
On the other hand, without Syncthing in the background, the same phone drains maybe about 5%, from 80% to 75%.
Exactly . That’s why im thinking about it. Years ago, I created a todo on the gh repo where I wanted to ask the user “turn on discovery/relay” etc and explain it might depend on how much battery usage is okay plus the user’s skills to IP:port wire everything manually.
I didn’t code it, whilst hoping for a better idea. Other ideas I had, e.g. to make the app syncing non-continously (by turning on an option) and then check “with double code” when folders/files change → to initiate a sync cycle. Wait until done, exit. Plus a regular interval where the device runs SyncthingNative just to check if new files are available on remotes.
Checking for changes in the “android java way” would be possible, but back in 2018 when SyncthingNative’s fileWatcher replaced that was originally troublesome. E.g. ignores weren’t respected, resulting in scan loops for /Android/ internal folders and files the user had on the ignore list - also consuming battery until the phones went off. (I would have to write an ignore pattern matcher in java to do it right.)
If you want to improve this, imo you need to take a different approach. Something like the new iOS app does, that takes more control of when and how things are running by reaching into our code. I think you are allowing to do something similar-ish but less controlled already by scheduling when syncthing is running. Downsides are likely things like the startup scans, which slows things down and costs energy too.
With the current slow I/O access on Android, I think this is a no-go, unless you sync only a small number of files… In my case, it can take 10+ minutes just to do the first scan on start, which eats more battery than just keeping the app running (unless we’re talking about waking it up very rarely, e.g. every few hours or so).
However, I run Syncthing through Termux and simply suspend the process when needed (using SIGSTOP). This way, there is no need to rescan the folders when it’s resumed later.
To be honest, it also drains a lot of battery on laptops, but I just deal with it, as I prefer to have my files kept in sync at all times .
Yes, that’s also correct. I don’t sync many files between my phone and other devices but lately users got my attention because they had thousands of files and performance got bad on the android app. This was fixed “some week ago”.
Yeah, what I do specifically is killall -STOP syncthing to pause, and then killall -CONT syncthing to resume just the Syncthing process . I’ve found this way more efficient than exiting and restarting the whole thing.
Ah for performance when pulling as in actually transferring files I do have an improvement pending. I very much hope to send a PR this week. That seems unrelated to battery usage though, really just “speed”/duration of filesystem operations while pulling. It’s around us limiting the number of concurrent writes during pull, quite heavily, and that slows things down a lot if writes have a high overhead that’s (largely) independent of other writes - e.g. on Android where the android-java-layer overhead is the main cause of slowness, not actual storage interaction.
Edit: I missed that you wrote it was fixed recently - I’d bet it was “fixed” by something that changed in the users side
I think the existance of this hack really just indicates the option not to rescan unconditionally on startup, but only after the rescan interval, would really be good to have. Afaik that’s the only thing that makes properly stopping and starting inefficient. And properly stopping and starting has benefits, like remotes actually knowing the device is gone right away and on startup you immediately get new connections/dials.
Hm. I don’t think that’s great when it’s paired with the fs watcher, though. Like, it’s cool to run with a one day rescan interval plus the watcher, but that doesn’t mean it’s cool to wait half a day to do a scan after being shut down for a few hours. (Though it’s not clear that being SIGSTOPped for that time is any better.)
Yeah it’s definitely not a silver bullet and I wouldn’t suggest to enable it by default with the watcher. However you could do it safely in the context of a wrapper, if you watched the folder in the wrapper while syncthing isn’t running. Plus that bit in the parantheses. On the other hand you can be sure that people will enable the option willi-nilly, when really their problem is something else entirely, and then they have two problems - however I’d rather fix problems of users using syncthing in a reasonable way than try to prevent users from making their own sync-life worse through misuse of non-standard behaviour