Technical
Session rhythm: the pattern most operators never look at
August 1, 2026 · 7 min read
Ask an operator how they make automation look human and you will hear about swipes. Ask what time their flows run and you will hear "nine in the morning". Those two answers are in tension, and the second one is doing more damage.
Two scales of timing
Every automated session has timing at two levels, and they are measured differently.
Within a session — the gaps between individual actions. Tap, wait, scroll, wait, type. This is where sleep(2) lives.
Between sessions — when a run starts, how long it lasts, how many actions it performs, how often it happens. This is where the scheduler lives.
Almost all attention goes to the first. Almost all the signal is in the second, because the second is visible in aggregate without needing to instrument anything.
Why fixed sleeps are visible
Plot the gaps between a person's actions in an app and you get a long-tailed distribution: mostly short, with a fat tail where they read something, got distracted, or switched apps. A log-normal shape is a decent approximation.
Plot the gaps in a flow built with fixed sleeps and you get spikes. Two seconds, two seconds, two seconds. Not a distribution — a comb.
The fix is trivial and almost nobody does it: draw the delay from a distribution rather than using a constant. Even crude randomisation — a base delay with a multiplier sampled from a sensible range — turns a comb into something with shape. Better still, use waits that key on state rather than time, and let the natural variance of the app produce the timing for you.
Free improvement: replacing "sleep 3 seconds" with "wait until the feed appears" makes the flow both more reliable and more natural, because the resulting gaps vary with real conditions instead of a number you picked.
The session-level pattern
Here is the part that survives every improvement to gesture realism.
A scheduled task that fires at 09:00:00 every day, runs for eleven minutes and forty seconds, and performs exactly forty-three actions, produces a signature that is obvious the moment anyone looks at the account's activity over a month. Every individual swipe can be a perfect Bézier curve. It does not matter. The regularity is at a level the swipes cannot reach.
Multiply that by fifty accounts all doing it at the same instant and it stops being a pattern and becomes a cluster.
Real usage does not look like that. People open an app at odd times. They skip days. Some sessions are two minutes and some are forty. They use it more on Sunday evening than Tuesday morning. None of this needs to be simulated with any sophistication — it needs to not be actively suppressed by a scheduler that fires on the dot.
What to vary, in order of value
- Start time. A window rather than a moment. If the task is "sometime in the morning", let it be sometime in the morning — a random offset across an hour or two costs nothing and removes the strongest signal.
- Whether it runs at all. People miss days. A task that has never once been skipped in four months is describing a machine.
- Duration and volume. Data lists help here naturally: if each run draws different rows, the work differs and so does the time it takes.
- Order. Where the flow allows it, doing things in a different sequence is cheap variance.
- Stagger across devices. Fifty devices starting together is worse than any one of them starting on the dot. Spread the fleet across a window.
Why this is under-optimised
Two reasons, both understandable.
Gesture realism is visible. You can watch a straight-line swipe and feel that it looks wrong. Timing distributions are invisible — you would have to log a month of runs and plot them to see the problem, and nobody does that because everything appears to be working.
And schedulers are built for reliability. "Runs at exactly 09:00, every day, without fail" is the specification every scheduling tool is proud of. That is the correct goal for a backup job and the wrong goal here.
Measuring your own
You do not need instrumentation to check this. Look at your calendar of scheduled tasks and ask:
- How many tasks fire at a time ending in
:00? - How many devices start within the same minute?
- Has any task been skipped in the last month?
- If you plotted run durations, would they be a spike or a spread?
If the answers are "most", "all", "no" and "a spike", the gesture work is not the thing to improve next.
Where it sits among the other signals
Input mechanics, session rhythm and network identity are three layers, and they are not equally weighted. As the companion post on detection argues, network identity usually carries the most — an account that changes egress, or fifty accounts sharing one, tells a clearer story than anything on screen.
Session rhythm sits second. Input mechanics, the layer everyone optimises first, sits third — not because it does not matter, but because it is the one most tools already handle and the one hardest to observe from inside an app.
The useful reordering: fix egress pairing, then fix timing, then worry about curves. Most operators do it backwards.
A scheduler that does not run like a metronome
Icemoon runs saved flows across a fleet on a calendar, with data lists feeding each pass so no two runs are identical. Real devices, human-like input, no jailbreak.
Start free trial